如何使用javaFx TriangleMesh创建这种形状?

问题描述 投票:3回答:1

我需要创建此形状。我了解如何创建简单的形状(例如立方体),但我完全不了解如何创建这种形状。如何获得这些阵列的正确点?请帮助

    TriangleMesh mesh = new TriangleMesh();

    mesh.getPoints().addAll(
            0, 0, 0,//P1
            0,0,100,//P2
            0,20,100,//P3
            60,20,100,//P4
            60,0,100,//P5
            60,20,60,//P6
            60,0,60,//P7
            40,0,60,//P8
            40,20,60,//P9
            40,20,0,//P10
            40,0,0,//P11
            0,20,0//P12
    );

    mesh.getTexCoords().addAll(
     //which points should be here?
    );

    mesh.getFaces().addAll(
   // which points should be here?
               );
    return mesh;

`

I need to create this shape

java javafx geometry shapes javafx-3d
1个回答
2
投票

您可以使用多种方法来构建3D形状,就像您发布的形状一样。

3D建模

[最简单的方法可能是使用3D编辑器,例如Blender(开源),然后将模型导出到.OBJ文件。在此OBJ文件中,您将获得顶点,纹理和面的列表。但是,该格式不能直接读取,因此您不能仅将其输入JavaFX MeshView。但是,有些进口商使用这种格式,将创建一个TriangleMesh,例如one

JCSG

[不处理点,顶点和面,但是使用Java方法,另一种选择是使用JCSG:您可以只创建两个立方体,然后进行布尔运算以获取所需的形状(从一个20x20x60立方体中减去一个60x20x100立方体)。还有一种将CSG对象转换为TriangleMesh的方法。

FXyz3D

从纯JavaFX的角度来看,您还可以使用FXyz3D库及其TriangulatedMesh。 Is是基于具有3D点({x,y,0})列表的平面,这些点定义了其周长,并对其进行了三角剖分并拉伸到给定的高度。在内部,它使用TriangulatedMesh,恰好是Poly2Tri

由于在XY上需要平坦的表面,因此我将点列表重写为:

a 2D constrained Delaunay triangulation library

然后可以通过以下方式生成形状:

private final List<Point3D> points = new ArrayList<>(Arrays.asList(
            new Point3D(0,   0, 0),
            new Point3D(0, 100, 0), new Point3D(60, 100, 0),
            new Point3D(60, 60, 0), new Point3D(40, 60,  0),
            new Point3D(40,  0, 0), new Point3D( 0,  0,  0)));

((请注意,旋转会将平面XY中的平面放置到平面XZ中,如图所示)

TriangulatedMesh customShape = new TriangulatedMesh(points, 20); customShape.setLevel(0); customShape.setCullFace(CullFace.NONE); customShape.getTransforms().addAll(new Rotate(-90, Rotate.X_AXIS));

您现在可以检查生成的网格,您将看到所有生成的三角形:

TriangulatedMesh

因此您可以使用此信息来“填充”您的点,纹理和面阵列,并了解其工作原理。

TriangleMesh

最后,从头开始,但基于上述三角剖分,这些是必需的数组:

顶点

Line and Fill Meshes

float[] vertices = { 0.0, 0.0, 0.0, // 0 0.0, 0.0, 100.0, // 1 60.0, 0.0, 100.0, 60.0, 0.0, 60.0, 40.0, 0.0, 60.0, 40.0, 0.0, 0.0, 0.0, 20.0, 0.0, 0.0, 20.0, 100.0, 60.0, 20.0, 100.0, 60.0, 20.0, 60.0, 40.0, 20.0, 60.0, 40.0, 20.0, 0.0}; // 11

纹理坐标

例如,这些可以基于尺寸为1x1的2D曲面生成,因此可以使用以下表达式轻松绘制顶点坐标:vertices

{x / (MaxX-MinX), y /(MaxY-MinY)}

面孔

我们将为每个三角形面添加3个顶点的索引和3个纹理坐标。

float[] texture = {
        0.00, 0.00,        // 0
        0.00, 1.00,        // 1
        1.00, 1.00,
        1.00, 0.60,
        0.67, 0.60,
        0.67, 0.00,
        0.00, 0.00,
        0.00, 1.00,
        1.00, 1.00,
        1.00, 0.60,
        0.67, 0.60,
        0.67, 0.00};        // 11

例如,对于顶表面,定义了四个三角形,第一个(0)具有顶点(1、2、4),第二个(1)具有顶点(4、2、3),并且依此类推:

int[] faces = { 1, 1, 2, 2, 4, 4, // 0 4, 4, 2, 2, 3, 3, // 1 1, 1, 4, 4, 0, 0, // 2 0, 0, 4, 4, 5, 5, 7, 7, 10, 10, 8, 8, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 10, 10, 6, 6, 11, 11, 10, 10, 0, 0, 1, 1, 7, 7, 0, 0, 7, 7, 6, 6, 1, 1, 2, 2, 8, 8, 1, 1, 8, 8, 7, 7, 2, 2, 3, 3, 9, 9, 2, 2, 9, 9, 8, 8, 3, 3, 4, 4, 10, 10, 3, 3, 10, 10, 9, 9, 4, 4, 5, 5, 11, 11, 4, 4, 11, 11, 10, 10, 5, 5, 0, 0, 6, 6, 5, 5, 6, 6, 11, 11}; // 19

在这种情况下,坐标纹理的索引与顶点的索引相同(但是可以不同)。注意顶点缠绕或逆时针旋转。

编辑

如果不使用法线,则添加面部平滑组很方便:每个组都包含属于同一平面的面部索引。例如,前四个索引属于顶表面。

Faces

这是创建自定义int[] smooth = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7}; 节点的全部代码:

MeshView
© www.soinside.com 2019 - 2024. All rights reserved.