ARCore 使用 SceneForm 框架 —— 控制 ModelRenderable 显示尺寸/边界

通过之前的博客,可以完成 3D 模型的显示,但是当我们换了一个其他模型的时候,会发现存在模型尺寸过大或者过小;想想也是可以理解的,别人制作的模型文件,又不是针对你的世界坐标系取实现的,那尺寸和你的世界坐标系的不匹配自然也就是正常
我们可以发现 SceneForm 提供了一个 setWorldScale 来设置 3D 模型的显示比例;但是实际情况是,我们现实生活中的物体都是以长宽高多少米的形式显示的,怎么将具体的尺寸换算成比例,也就是处理显示尺寸关键点

:在通过代码设置 3D 模型的尺寸/大小时,需要调用 TransformableNodegetScaleController().setEnabled(false) 方法,禁止框架自动控制缩放

    /**
     * 绘制 3D 模型,本函数是对之前《ARCore 使用 SceneForm 框架 —— 三维空间中不基于 Plane 加载 3D 模型》中的
     * showObj 函数的改进,如有疑问请参照《ARCore 使用 SceneForm 框架 —— 三维空间中不基于 Plane 加载 3D 模型》
     * @param arFragment 获取方式参照《ARCore 使用 SceneForm 框架 —— 三维空间中不基于 Plane 加载 3D 模型》
     * @param showSet
     * @param andyRenderable 获取方式参照《ARCore 使用 SceneForm 框架 —— 三维空间中不基于 Plane 加载 3D 模型》
     */
    public void draw3DObj(CleanArFragment arFragment, Vector3 showSet, ModelRenderable andyRenderable) 
    {

        AnchorNode anchorNode = new AnchorNode();
        anchorNode.setWorldPosition(showSet);  //设置显示在世界坐标系的位置
        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.getScaleController().setEnabled(false);
        andy.select();

        // 设置 3D 模型 x,y,z 最大的长度为 1 米
        Box box = (Box) andy.getRenderable().getCollisionShape();
        Vector3 size = box.getSize();
        if (size != null) {
        	// 获取最长边
            float maxExtent = size.x < size.y ? size.y : size.x;
            maxExtent = size.z < maxExtent ? maxExtent : size.z;
            if (maxExtent > 0) {        //没有边界,不进行边界重绘
                float scale = 1 / maxExtent;
                andy.setWorldScale(new Vector3(scale, scale, scale));
            }
        }

    }
发布了23 篇原创文章 · 获赞 22 · 访问量 3892

猜你喜欢

转载自blog.csdn.net/qq_19154605/article/details/103176632