简体   繁体   English

ARCore - 从 Modelrenderable 列表中选择不同的 3D 对象

[英]ARCore - Select different 3D Object from Modelrenderable list

I'm making an app which is quite similar to IKEA Place app.我正在制作一个与 IKEA Place 应用程序非常相似的应用程序。 First all the products will be listed from a ListView in the first Activity.首先,所有产品将从第一个活动的 ListView 中列出。 When you click to a product, all the information of that product will be displayed in a new Activity in CardView form.当您点击某个产品时,该产品的所有信息都会以 CardView 形式显示在一个新的 Activity 中。 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.下面会有“预览”和“加入购物车”按钮,这将引导您进行下一步,要么在 AR 中将产品预览为真实的 3D 对象,要么您可以直接将产品添加到购物车并转到付款步骤。 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.现在我面临的问题是,每个产品都有自己的 3D 对象预览,但它们总是在 AR 中显示相同的 3D 对象。 What should I do to let the app know when to select the corresponding object when you want to preview different peoducts in AR?当您想在 AR 中预览不同的产品时,我该怎么做才能让应用知道何时选择相应的对象? Here is my code.这是我的代码。

ProductFragment.java产品片段.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.这是与每个产品对应的我的 3d 对象列表。

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产品视图活动.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 ArFragment预览

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.我只能在 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 中打开项目并检查调试器/编译日志的输出或警告,如果检查所有访问修饰符失败,并确保在新模型进入焦点之前没有留在私有类中公共的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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