Java – How to combine multiple 3D objects into one using AR core

How to combine multiple 3D objects into one using AR core… here is a solution to the problem.

How to combine multiple 3D objects into one using AR core

Here I display multiple 3D objects in the scene (check the image below)
enter image description here

Here I have 3D model objects

and can now group 3D model objects. If I move one 3D object, then the other 2 3D objects need to move as well. Is it possible to achieve this without using unified and cloud anchors

Below is my code

package com.google.ar.sceneform.samples.hellosceneform;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.os.Build;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.widget.Toast;
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.rendering.ModelRenderable;
import com.google.ar.sceneform.ux.ArFragment;
import com.google.ar.sceneform.ux.TransformableNode;

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

private ArFragment arFragment;
  private ModelRenderable andyRenderable;

@Override
  @SuppressWarnings({"AndroidApiChecker", "FutureReturnValueIgnored"})

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

if (!checkIsSupportedDeviceOrFinish(this)) {
      return;
    }

setContentView(R.layout.activity_ux);
    arFragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.ux_fragment);

 When you build a Renderable, Sceneform loads its resources in the background while returning
     a CompletableFuture. Call thenAccept(), handle(), or check isDone() before calling get().
    ModelRenderable.builder()
        .setSource(this, R.raw.andy)
        .build()
        .thenAccept(renderable -> andyRenderable = renderable)
        .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;
            });

arFragment.setOnTapArPlaneListener(
        (HitResult hitResult, Plane plane, MotionEvent motionEvent) -> {
          if (andyRenderable == null) {
            return;
          }

 Create the Anchor.
          Anchor anchor = hitResult.createAnchor();
          AnchorNode anchorNode = new AnchorNode(anchor);
          anchorNode.setParent(arFragment.getArSceneView().getScene());

 Create the transformable andy and add it to the anchor.
          TransformableNode andy = new TransformableNode(arFragment.getTransformationSystem());
          andy.setParent(anchorNode);
          andy.setRenderable(andyRenderable);
          andy.select();
        });
  }

public static boolean checkIsSupportedDeviceOrFinish(final Activity activity) {
    if (Build.VERSION.SDK_INT < 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;
  }
}

Solution

You can use the .setParent() method to group 3D objects together. When an object is transformed (moved, rotated, or scaled), the child objects are also transformed.

An example of the solar system is shown in >createSolarSystem(). The planets are the child nodes of the Sun and the Moon are the child nodes of the Earth nodes.

You can then use setLocalPosition() to position the object relative to the parent object. For examplepositioning the planet in solarActivity :

Planet planet =
    new Planet(
        this, name, planetScale, orbitDegreesPerSecond, axisTilt, renderable, solarSettings);
planet.setParent(orbit);
planet.setLocalPosition(new Vector3(auFromParent * AU_TO_METERS, 0.0f, 0.0f));

Related Problems and Solutions