简体   繁体   中英

ARCore - Select different 3D Object from Modelrenderable list

I'm making an app which is quite similar to IKEA Place app. First all the products will be listed from a ListView in the first Activity. When you click to a product, all the information of that product will be displayed in a new Activity in CardView form. There will be "Preview" and "Add to Cart" button down below, which will lead you to the next step, either to preview the product in AR as a real 3D Object, or you can directly add the product to Cart and go to the payment step. Now I'm facing the problem that, each product will have its own 3D Object preview, but they always display the same 3D Object in AR. What should I do to let the app know when to select the corresponding object when you want to preview different peoducts in AR? Here is my code.

ProductFragment.java

package com.example.myar;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import androidx.fragment.app.Fragment;

import com.nex3z.notificationbadge.NotificationBadge;


public class ProductFragment extends Fragment {

private NotificationBadge badge;

here is the list of my 3d Objects corresponding to each product.

private String[] names = {"name1", "name2", "name3", "name4", "name5", "name6", "name7" };
private int[] images = {R.drawable.background, R.drawable.ic_launcher_background, R.drawable.background,
        R.drawable.background, R.drawable.ic_launcher_background, R.drawable.ic_launcher_background, R.drawable.background};
private String[] description ={"123", "456", "789", "1011", "abc", "3311", "31313"};
private String[] price ={"19,00 €", "20,50 €", "35,00 €", "44,19 €", "5,79 €", "89,99 €", "1,99 €"};
private String[] object3D = {"ArcticFox_Posed.sfb", "AJ-Vase.sfb", "10432_Aloe_Plant_v1_max2008_it2.sfb","AJ-Vase.sfb",
        "AJ-Vase.sfb", "ArcticFox_Posed.sfb", "10432_Aloe_Plant_v1_max2008_it2.sfb"};

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    setHasOptionsMenu(true);

    View view = inflater.inflate(R.layout.product_fragment, container, false);
    ListView listView = view.findViewById(R.id.ItemListView);
    ProductFragment.customadapter ca = new ProductFragment.customadapter();
    listView.setOnItemClickListener((parent, view1, position, id) -> {

        String nameItemListview = names[position];
        int imageItemListview = images[position];
        String descItemListview = description[position];
        String priceItemListview = price[position];
    //    String object3DListview = object3D[position];

        Intent intent = new Intent(view1.getContext(), ProductViewActivity.class);
        intent.putExtra("item Names", nameItemListview);
        intent.putExtra("item Images", imageItemListview);
        intent.putExtra("item Desc", descItemListview);
        intent.putExtra("item Price", priceItemListview);
     //   intent.putExtra("3D Object", object3DListview);
        ProductFragment.this.startActivity(intent);
    });

    listView.setAdapter(ca);
    return view;

}

@Override
    public void onCreateOptionsMenu( Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.menu_cart, menu);
    View view = menu.findItem(R.id.action_cart).getActionView();;
    badge = view.findViewById(R.id.badge);
    ImageView cart_icon = view.findViewById(R.id.cart_icon);
    cart_icon.setOnClickListener(v -> startActivity(new Intent (getContext(), CartActivity.class)));
    updateCartCount();
}

private void updateCartCount() {
    if(badge == null) return;
    getActivity().runOnUiThread(() -> {
        if (MainActivity.cartRepository.countItem() == 0)
            badge.setVisibility(View.VISIBLE);
        else {
            badge.setVisibility((View.VISIBLE));
            badge.setText(String.valueOf(MainActivity.cartRepository.countItem()));
        }
    });
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == R.id.action_cart) {
    }
    return true;
}
class customadapter extends BaseAdapter {

       @Override
    public int getCount() {
        return images.length;
    }

    @Override
    public Object getItem(int arg0) {
        return null;
    }

    @Override
    public long getItemId(int arg0) {
        return 0;
    }

    @SuppressLint({"ViewHolder", "InflateParams"})
    @Override
    public View getView(final int position, View view, ViewGroup parent) {
        view = getLayoutInflater().inflate(R.layout.layout_list_item, null);

        TextView tv = view.findViewById(R.id.item_name);
        ImageView image = view.findViewById(R.id.item_image);
        TextView pv = view.findViewById(R.id.item_price);

        tv.setText(names[position]);
        image.setImageResource(images[position]);
        pv.setText(price[position]);

        return view;
    }
}

@Override
public void onResume() {
    super.onResume();
    updateCartCount();
}
}

ProductViewActivity.java

package com.example.myar;

import android.content.Intent;
import android.os.Bundle;

import android.util.Log;
import android.view.MenuItem;

import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.Toolbar;


import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;

import com.example.myar.RoomDatabase.ModelDB.Cart;
import com.google.gson.*;


public class ProductViewActivity extends FragmentActivity {
    Toolbar productToolbar;
    ImageView productImage;
    TextView productName;
    TextView productDesc;
    TextView productPrice;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_productview);

    productToolbar = findViewById(R.id.toolbarTop);
    productImage = findViewById(R.id.product_image);
    productName = findViewById(R.id.product_name);
    productDesc = findViewById(R.id.product_description);
    productPrice = findViewById(R.id.product_price);

    String nameHolder = getIntent().getStringExtra("item Names");
    productName.setText(nameHolder);

    int imageHolder = getIntent().getIntExtra("item Images", -1);
    productImage.setImageResource(imageHolder);

    String descHolder = getIntent().getStringExtra("item Desc");
    productDesc.setText(descHolder);

    String priceHolder = getIntent().getStringExtra("item Price");
    productPrice.setText(priceHolder);

    productToolbar.setTitle("Detail");
    setActionBar(productToolbar);
    getWindow().setStatusBarColor(ContextCompat.getColor(ProductViewActivity.this, R.color.colorProductBackground));

    //backButton as arrow
    if (getActionBar() != null) {
        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setDisplayShowHomeEnabled(true);
    }

    Button previewButton = findViewById(R.id.previewButton);
    previewButton.setOnClickListener(view -> openPreview());

    Button addToCartButton = findViewById(R.id.addToCartButton);
    addToCartButton.setOnClickListener(view -> addToCartActivity());
}
//click on Arrow to go back to last Activity
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // handle arrow click here
    if (item.getItemId() == android.R.id.home) {
        finish(); // close this activity and return to preview activity (if there is any)
    }
    return super.onOptionsItemSelected(item);
}
public void openPreview (){

    Intent intent = new Intent(this, ArFragmentPreview.class);
    startActivity(intent);
}

public void addToCartActivity (){

    try {
        Cart cartItem = new Cart();
        cartItem.name = productName.getText().toString();
        cartItem.description = productDesc.getText().toString();
        cartItem.price = productPrice.getText().toString();

        MainActivity.cartRepository.insertToCart(cartItem);
        Log.d("MyAR", new Gson().toJson(cartItem));
        Toast.makeText(this, "Save Item to Cart successful", Toast.LENGTH_SHORT).show();
    }
    catch (Exception ex)
    {
        Toast.makeText(this, ex.getMessage(), Toast.LENGTH_SHORT).show();
    }

}

}

ArFragmentPreview

package com.example.myar;

import android.net.Uri;
import android.os.Bundle;
import android.view.Gravity;
import android.view.MotionEvent;
import android.widget.Button;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.google.ar.sceneform.collision.Box;
import com.google.ar.sceneform.ux.ArFragment;
import com.google.ar.core.Anchor;
import com.google.ar.core.HitResult;
import com.google.ar.core.Plane;
import com.google.ar.sceneform.AnchorNode;
import com.google.ar.sceneform.Camera;
import com.google.ar.sceneform.Node;
import com.google.ar.sceneform.Sun;
import com.google.ar.sceneform.math.Quaternion;
import com.google.ar.sceneform.math.Vector3;
import com.google.ar.sceneform.rendering.ModelRenderable;
import com.google.ar.sceneform.ux.TransformableNode;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class ArFragmentPreview extends AppCompatActivity {

private ArFragment arFragment;
public Plane.Type planeType;
ModelRenderable Fox, Vase, Plant;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_arpreview_layout);
    arFragment = (ArFragment)getSupportFragmentManager().findFragmentById(R.id.arFragment);
    arFragment.setOnTapArPlaneListener((HitResult hitResult, Plane plane, MotionEvent motionEvent) -> {

I can only render this file in AR.

        //Renderable mode in AR app
        ModelRenderable.builder()
                .setSource(this, Uri.parse("ArcticFox_Posed.sfb"))
                .build()
                .thenAccept(modelRenderable -> addModelToScene(modelRenderable, hitResult, planeType))
                .exceptionally(throwable -> {
                    Toast toast = Toast.makeText(this, "Unable to load andy renderable", Toast.LENGTH_LONG);
                    toast.setGravity(Gravity.CENTER, 0, 0);
                    toast.show();
                    return null;
                });

    Button backButton = findViewById(R.id.backButton);
    backButton.setOnClickListener(v -> this.finish());

    Button clearButton = findViewById(R.id.clearButton);
    clearButton.setOnClickListener(view -> onClear());

}

private void addModelToScene(ModelRenderable modelRenderable, HitResult hitResult, Plane.Type planeType) {
    Anchor anchor = hitResult.createAnchor();
    AnchorNode anchorNode = new AnchorNode(anchor);
    anchorNode.setParent(arFragment.getArSceneView().getScene());

    Vector3 size = ((Box) modelRenderable.getCollisionShape()).getSize();

    TransformableNode transformableNode = new TransformableNode(arFragment.getTransformationSystem());
    transformableNode.setParent(anchorNode);
    arFragment.getArSceneView().getScene().addChild(anchorNode);

    if (planeType == Plane.Type.HORIZONTAL_DOWNWARD_FACING) {
        transformableNode.setParent(transformableNode);
        transformableNode.setLocalPosition(new Vector3(0, size.y, 0));
        transformableNode.setLocalRotation(new Quaternion(0, 0, 1, 0));
        transformableNode.setRenderable(modelRenderable);
        transformableNode.select();
    } else if (planeType == Plane.Type.VERTICAL) {
        transformableNode.setParent(transformableNode);
        //transformableNode.setLookDirection(new Vector3(0,0,0));
        transformableNode.setRenderable(modelRenderable);
        transformableNode.select();
    } else {
        transformableNode.setRenderable(modelRenderable);
        transformableNode.select();
    }
}

private void onClear() {
    List<Node> children = new ArrayList<>(arFragment.getArSceneView().getScene().getChildren());
    for (Node node : children) {
        if (node instanceof AnchorNode) {
            if (((AnchorNode) node).getAnchor() != null) {
                Objects.requireNonNull(((AnchorNode) node).getAnchor()).detach();
            }
        }
        if (!(node instanceof Camera) && !(node instanceof Sun)) {
            node.setParent(null);
        }
    }
}

}

您可以尝试在 JMonkey 中打开项目并检查调试器/编译日志的输出或警告,如果检查所有访问修饰符失败,并确保在新模型进入焦点之前没有留在私有类中公共的。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM