我需要创建此形状。我了解如何创建简单的形状(例如立方体),但我完全不了解如何创建这种形状。如何获得这些阵列的正确点?请帮助
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;
`
您可以使用多种方法来构建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));
您现在可以检查生成的网格,您将看到所有生成的三角形:
因此您可以使用此信息来“填充”您的点,纹理和面阵列,并了解其工作原理。
TriangleMesh
最后,从头开始,但基于上述三角剖分,这些是必需的数组:
顶点
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曲面生成,因此可以使用以下表达式轻松绘制顶点坐标:。
{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
在这种情况下,坐标纹理的索引与顶点的索引相同(但是可以不同)。注意顶点缠绕或逆时针旋转。
编辑
如果不使用法线,则添加面部平滑组很方便:每个组都包含属于同一平面的面部索引。例如,前四个索引属于顶表面。
这是创建自定义int[] smooth = {0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};
节点的全部代码:
MeshView