如何使用 Sceneform、ARCore 绘制多边形? [英] How to draw a polygon with Sceneform, ARCore?

查看:34
本文介绍了如何使用 Sceneform、ARCore 绘制多边形?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Let's say I have three anchors from hit result from ArFragment.

Anchor anchor = hitResult.createAnchor();

Anchor anchor = hitResult.createAnchor();

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

How can I draw a triangle and apply custom texture using Sceneform?

推荐答案

第一步是创建一个AnchorNode的列表,以便能够获取Anchor s.我们会将它们全部添加到列表中:

First step is to create a list of AnchorNodes to be able to get the coordinates of the Anchors. We will add all of them in a list:

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

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

then in OnTapArPlaneListener, we can create our triangle if we reach three anchors (or three coordinates). We will generate our triangle as a 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;
    }
}

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

And this is the result I got with the code shown before (I added some Bugdroids to show where the anchors are):

这篇关于如何使用 Sceneform、ARCore 绘制多边形?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆