问题描述
比方说,我从ArFragment的命中结果中获得了三个锚点.
Let's say I have three anchors from hit result from ArFragment.
如何使用Sceneform绘制三角形并应用自定义纹理?
How can I draw a triangle and apply custom texture using Sceneform?
推荐答案
第一步是创建 AnchorNode
的列表,以获取 Anchor
s.我们将所有这些添加到列表中:
First step is to create a list of AnchorNode
s to be able to get the coordinates of the Anchor
s. 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绘制多边形?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!