【问题标题】:Google ARCore Sceneform How to detect ray hit to ar object谷歌 ARCore Sceneform 如何检测光线击中 ar 对象
【发布时间】:2021-01-07 23:04:48
【问题描述】:

我是 Google AR 核心和 Sceneform 的新手。我想在 Android Studio 上开发一个基本的 fps 游戏,当用户触摸屏幕上的任何位置时,将创建 AR 对象,如果按下按钮,将从屏幕中心射出一条射线,如果射线击中任何创建的 AR对象,分数​​会增加。 代码如下,但我无法继续。我该怎么办?

public class MainActivity extends AppCompatActivity{
    private static final String TAG = MainActivity.class.getSimpleName();
    private static final double MIN_OPENGL_VERSION = 3.0;

    private ArFragment arFragment;
    private ModelRenderable mRenderable;
    private ImageButton imageButton;
    private TextView scoreText;
    private int score=0;
    private Set<Vector3> position = new HashSet<Vector3>();


   // Set<Vector3> obj_set = new HashSet<Vector3>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (!checkIsSupportedDeviceOrFinish(this)) {
            return;
        }
        setContentView(R.layout.activity_main);

        arFragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
        imageButton = (ImageButton) findViewById(R.id.imageButton);
        scoreText = (TextView) findViewById(R.id.scoreText);


        setUpModel();
        setUpPlane();

        imageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    Camera camera = arFragment.getArSceneView().getScene().getCamera();
                    Ray ray = new Ray(camera.getWorldPosition(),camera.getForward());

                    HitTestResult result = arFragment.getArSceneView().getScene().hitTest(ray);
                    if (result.getNode() != null && result.getDistance() < 0) {
                        // Hit something
                        //doSomething(result.getNode());
                        Log.e(TAG,"RAYCASTING ERROR");
                    }else{
                        Iterator value = position.iterator();
                        while(value.hasNext()){
                            if(position.equals(result.getPoint())){
                                Toast.makeText(getApplicationContext(),"HIT WAS DETECTED",Toast.LENGTH_SHORT).show();
                                score = score + 5;
                                scoreText.setText("SCORE: " + score + "");
                                Log.e(TAG,"HEY THERE");
                            }
                            else{
                                Log.e(TAG,"NOOOOOOO");
                            }
                        }
                    }

                } catch (Exception e) {
                    Log.e(TAG, "ERROR ON BUTTON");
                }
            }
        });

    }

    private void setUpModel() { //Load the model
        WeakReference<MainActivity> weakActivity = new WeakReference<>(this);

        ModelRenderable.builder()
                .setSource(this, R.raw.model)
                .setIsFilamentGltf(true)
                .build()
                .thenAccept(modelRenderable -> {
                    MainActivity activity = weakActivity.get();
                    if (activity != null) {
                        mRenderable = modelRenderable;
                    }
                })
                .exceptionally(throwable -> {
                    Toast.makeText(MainActivity.this, "Model can not be loaded!", Toast.LENGTH_SHORT).show();
                    return null;
                });
    }

    private void setUpPlane() {//Attach the scene to the node
        arFragment.setOnTapArPlaneListener(new BaseArFragment.OnTapArPlaneListener() {
            @Override
            public void onTapPlane(HitResult hitResult, Plane plane, MotionEvent motionEvent) {

                // Creates the anchor
                Anchor anchor = hitResult.createAnchor();
                AnchorNode anchorNode = new AnchorNode(anchor);
                anchorNode.setParent(arFragment.getArSceneView().getScene());
                createModel(anchorNode);
            }
        });
    }
    private void createModel(AnchorNode anchorNode) {// Create the transformable model and add it to the anchor
        TransformableNode node = new TransformableNode(arFragment.getTransformationSystem());
        node.setParent(anchorNode);
        node.setRenderable(mRenderable);
        node.select();

        position.add(anchorNode.getWorldPosition());

    }

    public static boolean checkIsSupportedDeviceOrFinish(final Activity activity) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            Log.e(TAG, "Sceneform requires Android N or later");
            Toast.makeText(activity, "Sceneform requires Android N or later", Toast.LENGTH_LONG).show();
            activity.finish();
            return false;
        }
        String openGlVersionString =
                ((ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE))
                        .getDeviceConfigurationInfo()
                        .getGlEsVersion();
        if (Double.parseDouble(openGlVersionString) < MIN_OPENGL_VERSION) {
            Log.e(TAG, "Sceneform requires OpenGL ES 3.0 later");
            Toast.makeText(activity, "Sceneform requires OpenGL ES 3.0 or later", Toast.LENGTH_LONG)
                    .show();
            activity.finish();
            return false;
        }
        return true;
    }
}

【问题讨论】:

    标签: java android android-studio arcore sceneform


    【解决方案1】:

    我不确定我是否完全理解您想要实现的目标,但如果您想在用户指向对象并按下按钮时增加分数,那么您可以检查结果!= null 然后执行您的操作,为什么你在 else 部分有命中检测逻辑?所以你可以:

    ...
        HitTestResult result = arFragment.getArSceneView().getScene().hitTest(ray);
        if (result.getNode() != null) {
            // Hit something
             Toast.makeText(getApplicationContext(),"HIT WAS DETECTED",Toast.LENGTH_SHORT).show();
             score = score + 5;
             scoreText.setText("SCORE: " + score + "");                  
        }
    ...
    

    只要用户指向对象,这当然会使分数不断增加。

    【讨论】:

      猜你喜欢
      • 2018-02-11
      • 2019-11-03
      • 2019-03-15
      • 2020-10-14
      • 2019-05-14
      • 1970-01-01
      • 1970-01-01
      • 2019-09-27
      • 1970-01-01
      相关资源
      最近更新 更多