SceneForm SDK技术问题:对象可在地面移动但无法在墙面移动如何解决
看起来你遇到的问题是在SceneForm里,把模型放在地面(水平平面)上可以正常拖动,但放在墙面上(垂直平面)就没法移动了。我来帮你分析下原因和解决办法:
问题原因
你现在的代码里,使用了默认的TransformableNode,它默认的**平移控制器(TranslationController)**是PlaneTranslationController——这个控制器会把模型的移动限制在创建Anchor时所在的平面内。但对于垂直平面来说,默认的手势交互逻辑可能没有正确响应垂直方向的拖动,或者说需要明确启用对垂直平面的支持。
另外,虽然你注释掉了平面类型的判断,允许在任意平面放置,但PlaneTranslationController对于垂直平面的移动约束需要正确配置。
解决方案
下面提供两种常见的解决思路,你可以根据需求选择:
方案1:让模型在任意3D空间自由移动(不受平面限制)
如果你希望放置后的模型可以在整个AR空间里自由拖动,而不是绑定在原来的平面上,可以把默认的PlaneTranslationController替换成FreeTranslationController:
修改你的代码,在创建TransformableNode后添加这段代码:
// 替换默认的平移控制器为自由平移,允许在3D空间任意移动 andy.getTranslationController().setEnabled(false); FreeTranslationController freeTranslationController = new FreeTranslationController(andy); andy.setTranslationController(freeTranslationController); freeTranslationController.setEnabled(true);
这样修改后,不管是地面还是墙面放置的模型,都可以通过手势在整个AR空间里拖动、旋转和缩放。
方案2:让模型在所在的平面内移动(支持垂直墙面)
如果你希望模型仍然保持在放置的平面内移动(比如墙面的模型只能沿着墙面拖动),可以保留PlaneTranslationController,但需要确保它能正确识别垂直平面的交互。
首先确保你的AR Session已经启用了垂直平面检测(在ArFragment的配置里):
ArSceneView sceneView = arFragment.getArSceneView(); Config config = sceneView.getSession().getConfig(); config.setPlaneDetectionMode(Config.PlaneDetectionMode.HORIZONTAL_AND_VERTICAL); sceneView.getSession().configure(config);
然后,在创建TransformableNode时,明确启用平移控制器:
// 确保平移控制器启用,默认是启用的,但可以明确设置 andy.getTranslationController().setEnabled(true);
这样修改后,墙面放置的模型应该可以沿着墙面的垂直方向拖动了。
完整修改后的代码示例(方案1)
这里给你整合方案1的完整代码,供参考:
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(); andy.setEnabled(true); // 替换为自由平移控制器,允许3D空间自由移动 andy.getTranslationController().setEnabled(false); FreeTranslationController freeTranslationController = new FreeTranslationController(andy); andy.setTranslationController(freeTranslationController); freeTranslationController.setEnabled(true); });
额外提示
- 测试的时候,确保墙面有足够清晰的纹理,AR系统能正确检测到垂直平面;
- 如果使用方案2,拖动墙面模型时,尽量沿着墙面的方向滑动手势,这样控制器能更好地识别你的操作意图。
内容的提问来源于stack exchange,提问作者user1560818

