【问题标题】:How to draw a polygon with Sceneform, ARCore?如何使用 Sceneform、ARCore 绘制多边形?
【发布时间】:2019-06-23 07:51:54
【问题描述】:

假设我有来自 ArFragment 的命中结果的三个锚点。

锚定锚 = hitResult.createAnchor();

如何使用 Sceneform 绘制三角形并应用自定义纹理?

【问题讨论】:

    标签: java android polygon arcore sceneform


    【解决方案1】:

    第一步是创建AnchorNodes 的列表,以便能够获取Anchors 的坐标。我们会将它们全部添加到一个列表中:

    private final List<AnchorNode> anchorsList = new ArrayList<>();
    

    然后在OnTapArPlaneListener 中,如果我们到达三个锚点(或三个坐标),我们就可以创建我们的三角形。我们将生成我们的三角形为ModelRenderable:

    final Anchor anchor = hitResult.createAnchor();
    final AnchorNode anchorNode = new AnchorNode(anchor);
    
    anchorNode.setParent(arFragment.getArSceneView().getScene());
    anchorsList.add(anchorNode);
    
    if (anchorsList.size() == 3) {
        final Texture.Sampler sampler = Texture.Sampler.builder()
                .setMinFilter(Texture.Sampler.MinFilter.LINEAR_MIPMAP_LINEAR)
                .setMagFilter(Texture.Sampler.MagFilter.LINEAR)
                .setWrapModeR(Texture.Sampler.WrapMode.REPEAT)
                .setWrapModeS(Texture.Sampler.WrapMode.REPEAT)
                .setWrapModeT(Texture.Sampler.WrapMode.REPEAT)
                .build();
    
        Texture.builder()
                .setSource(() -> getAssets().open("wall.jpg"))
                .setSampler(sampler)
                .build()
                .thenAccept(texture -> MaterialFactory.makeOpaqueWithTexture(this, texture)
                        .thenAccept(material -> {
                            final Node node = new Node();
                            final ModelRenderable triangle = makeTriangleWithAnchors(anchorsList, material);
    
                            node.setParent(arFragment.getArSceneView().getScene());
                            node.setRenderable(triangle);
                        })
                );
    }
    

    这里是makeTriangleWithAnchors()方法的详细信息:

    private ModelRenderable makeTriangleWithAnchors(@NonNull final List<AnchorNode> anchorNodes, @NonNull final Material material) {
        if (anchorNodes.size() != 3) throw new IllegalStateException("Different count of anchorsList than 3");
    
        final Vector3 p0 = anchorNodes.get(0).getLocalPosition();
        final Vector3 p1 = anchorNodes.get(1).getLocalPosition();
        final Vector3 p2 = anchorNodes.get(2).getLocalPosition();
        final Vector3 up = Vector3.up();
        final UvCoordinate uvTop = new UvCoordinate(0.5f, 1.0f);
        final UvCoordinate uvBotLeft = new UvCoordinate(0.0f, 0.0f);
        final UvCoordinate uvBotRight = new UvCoordinate(1.0f, 0.0f);
        final List<Vertex> vertices = new ArrayList<>(Arrays.asList(
                Vertex.builder().setPosition(p0).setNormal(up).setUvCoordinate(uvTop).build(),
                Vertex.builder().setPosition(p1).setNormal(up).setUvCoordinate(uvBotRight).build(),
                Vertex.builder().setPosition(p2).setNormal(up).setUvCoordinate(uvBotLeft).build()
        ));
    
        final List<Integer> triangleIndices = new ArrayList<>(3);
        triangleIndices.add(0);
        triangleIndices.add(2);
        triangleIndices.add(1);
        triangleIndices.add(0);
        triangleIndices.add(1);
        triangleIndices.add(2);
    
        final RenderableDefinition.Submesh submesh = RenderableDefinition.Submesh.builder()
                .setTriangleIndices(triangleIndices)
                .setMaterial(material)
                .build();
        final RenderableDefinition renderableDefinition = RenderableDefinition.builder()
                .setVertices(vertices)
                .setSubmeshes(Arrays.asList(submesh))
                .build();
        final CompletableFuture future = ModelRenderable.builder()
                .setSource(renderableDefinition)
                .build();
    
        final ModelRenderable result;
        try {
            result = (ModelRenderable) future.get();
        } catch (InterruptedException | ExecutionException e) {
            throw new AssertionError("Error creating renderable.", e);
        }
    
        if (result == null) {
            throw new AssertionError("Error creating renderable.");
        } else {
            return result;
        }
    }
    

    这是我使用之前显示的代码得到的结果(我添加了一些 Bugdroid 来显示锚点的位置):

    【讨论】:

    • 谢谢!我希望他们在他们的文档参考中发布更多这样的东西/示例,并添加对球体、立方体、圆柱体之外的更多几何图元的支持。
    • 不客气。实际上我看了一下立方体是如何在ShapeFactory 中实现的,以使其适应扁平三角形。最后,如果您将我的回答标记为您问题的解决方案,那就太好了。
    • 能否请您帮忙修改代码以将其中一个节点设置为创建的三角形的父节点?当 arFragment.getArSceneView().getScene() 设置时 - 节点三角形连接不太稳定。但是当我只是改变父级时 - 三角形看起来更小并且移动了。感谢您的帮助!
    猜你喜欢
    • 2019-11-03
    • 2014-03-03
    • 2015-08-02
    • 1970-01-01
    • 2011-01-16
    • 2017-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多