【发布时间】:2019-06-23 07:51:54
【问题描述】:
假设我有来自 ArFragment 的命中结果的三个锚点。
锚定锚 = hitResult.createAnchor();
如何使用 Sceneform 绘制三角形并应用自定义纹理?
【问题讨论】:
标签: java android polygon arcore sceneform
假设我有来自 ArFragment 的命中结果的三个锚点。
锚定锚 = hitResult.createAnchor();
如何使用 Sceneform 绘制三角形并应用自定义纹理?
【问题讨论】:
标签: java android polygon arcore sceneform
第一步是创建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;
}
}
【讨论】:
ShapeFactory 中实现的,以使其适应扁平三角形。最后,如果您将我的回答标记为您问题的解决方案,那就太好了。
arFragment.getArSceneView().getScene() 设置时 - 节点三角形连接不太稳定。但是当我只是改变父级时 - 三角形看起来更小并且移动了。感谢您的帮助!