如何在 Anchor 上一次只显示一个 AR 对象?
How to show only one AR object at a time on Achor?
我想在一个锚点上一次只显示一个对象。目前我正在运行时从服务器获取我的 AR 模型并显示我的模型。当我每次获得新的 AR 模型时都点击锚点,所以我必须在一些点击(等于点击次数)后有很多模型。我想立即限制模型。每次当用户点击屏幕时,ar 模型总是一次只显示一个对象。
public class ARObjectActivity extends AppCompatActivity {
private ArFragment arFragment;
private String Asset_3D = "";
String imageUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_a_r_object);
arFragment=(ArFragment) getSupportFragmentManager().findFragmentById(R.id.arFragment);
Intent intent = getIntent();
imageUri = intent.getStringExtra("arImageUri");
arFragment.setOnTapArPlaneListener((hitResult, plane, motionEvent) ->
placeModel(hitResult.createAnchor()));
}
private void placeModel(Anchor anchor) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
ModelRenderable.builder()
.setSource(ARObjectActivity.this, RenderableSource.builder()
.setSource(ARObjectActivity.this, Uri.parse(imageUri),
RenderableSource.SourceType.GLTF2)
.setScale(0.5f)
.setRecenterMode(RenderableSource.RecenterMode.ROOT)
.build()
)
.setRegistryId(Asset_3D)
.build()
.thenAccept(modelRenderable -> addNoteToScene(modelRenderable,anchor))
.exceptionally(throwable -> {
AlertDialog.Builder builder = new AlertDialog.Builder(ARObjectActivity.this);
builder.setMessage(throwable.getMessage()).show();
return null;
});
}
}
private void addNoteToScene(ModelRenderable modelRenderable, Anchor anchor) {
AnchorNode anchorNode = new AnchorNode(anchor);
//anchorNode.setRenderable(modelRenderable);
anchorNode.setParent(arFragment.getArSceneView().getScene());
// arFragment.getArSceneView().getScene().addChild(anchorNode);
// Create the transformable andy and add it to the anchor.
TransformableNode node = new TransformableNode(arFragment.getTransformationSystem());
//set rotation in direction (x,y,z) in degrees 90
node.setLocalRotation(Quaternion.axisAngle(new Vector3(1f, 1f, 1f), 90f));
node.setParent(anchorNode);
node.setRenderable(modelRenderable);
node.select();
}
}
添加这个新方法
private void clearAllModel() {
List<Node> children = new ArrayList<Node>(arFragment.getArSceneView().getScene().getChildren());
for (Node node : children) {
if (node instanceof AnchorNode) {
AnchorNode tmp = (AnchorNode) node;
if (tmp.getAnchor() != null) {
tmp.getAnchor().detach();
}
}
}
}
然后在
调用它
arFragment.setOnTapArPlaneListener((hitResult, plane, motionEvent) -> {
clearAllModel();
placeModel(hitResult.createAnchor()));
}
说明:
如您所见,每次点击 placeModel
进入 addNoteToScene
时,都会有这行代码
anchorNode.setParent(arFragment.getArSceneView().getScene());
你现有的所有模型(在 anchorNode 上)都在这个 arFragment.getArSceneView().getScene()
作为 child
按照我的方法建议,第一次有0 child (null)。所以它会继续前进,只做 placeModel
然后它有 1 child。
第二次删除 1 child,然后再次调用 placeModel
,并再次将其设为 1 child。依此类推...所以,将只有 1 child (model)
我想在一个锚点上一次只显示一个对象。目前我正在运行时从服务器获取我的 AR 模型并显示我的模型。当我每次获得新的 AR 模型时都点击锚点,所以我必须在一些点击(等于点击次数)后有很多模型。我想立即限制模型。每次当用户点击屏幕时,ar 模型总是一次只显示一个对象。
public class ARObjectActivity extends AppCompatActivity {
private ArFragment arFragment;
private String Asset_3D = "";
String imageUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_a_r_object);
arFragment=(ArFragment) getSupportFragmentManager().findFragmentById(R.id.arFragment);
Intent intent = getIntent();
imageUri = intent.getStringExtra("arImageUri");
arFragment.setOnTapArPlaneListener((hitResult, plane, motionEvent) ->
placeModel(hitResult.createAnchor()));
}
private void placeModel(Anchor anchor) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
ModelRenderable.builder()
.setSource(ARObjectActivity.this, RenderableSource.builder()
.setSource(ARObjectActivity.this, Uri.parse(imageUri),
RenderableSource.SourceType.GLTF2)
.setScale(0.5f)
.setRecenterMode(RenderableSource.RecenterMode.ROOT)
.build()
)
.setRegistryId(Asset_3D)
.build()
.thenAccept(modelRenderable -> addNoteToScene(modelRenderable,anchor))
.exceptionally(throwable -> {
AlertDialog.Builder builder = new AlertDialog.Builder(ARObjectActivity.this);
builder.setMessage(throwable.getMessage()).show();
return null;
});
}
}
private void addNoteToScene(ModelRenderable modelRenderable, Anchor anchor) {
AnchorNode anchorNode = new AnchorNode(anchor);
//anchorNode.setRenderable(modelRenderable);
anchorNode.setParent(arFragment.getArSceneView().getScene());
// arFragment.getArSceneView().getScene().addChild(anchorNode);
// Create the transformable andy and add it to the anchor.
TransformableNode node = new TransformableNode(arFragment.getTransformationSystem());
//set rotation in direction (x,y,z) in degrees 90
node.setLocalRotation(Quaternion.axisAngle(new Vector3(1f, 1f, 1f), 90f));
node.setParent(anchorNode);
node.setRenderable(modelRenderable);
node.select();
}
}
添加这个新方法
private void clearAllModel() {
List<Node> children = new ArrayList<Node>(arFragment.getArSceneView().getScene().getChildren());
for (Node node : children) {
if (node instanceof AnchorNode) {
AnchorNode tmp = (AnchorNode) node;
if (tmp.getAnchor() != null) {
tmp.getAnchor().detach();
}
}
}
}
然后在
调用它arFragment.setOnTapArPlaneListener((hitResult, plane, motionEvent) -> {
clearAllModel();
placeModel(hitResult.createAnchor()));
}
说明:
如您所见,每次点击 placeModel
进入 addNoteToScene
时,都会有这行代码
anchorNode.setParent(arFragment.getArSceneView().getScene());
你现有的所有模型(在 anchorNode 上)都在这个 arFragment.getArSceneView().getScene()
作为 child
按照我的方法建议,第一次有0 child (null)。所以它会继续前进,只做 placeModel
然后它有 1 child。
第二次删除 1 child,然后再次调用 placeModel
,并再次将其设为 1 child。依此类推...所以,将只有 1 child (model)