如何理解 JavaFX 三角形网格?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19960368/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make sense of JavaFX triangle mesh?
提问by ajeh
Just trying to make sense of JavaFX documentation re triangle mesh. This code works and draws a rectangle.
只是想了解有关三角形网格的 JavaFX 文档。此代码工作并绘制一个矩形。
public class Shape3DRectangle extends TriangleMesh {
public Shape3DRectangle(float Width, float Height) {
float[] points = {
-Width/2, Height/2, 0, // idx p0
-Width/2, -Height/2, 0, // idx p1
Width/2, Height/2, 0, // idx p2
Width/2, -Height/2, 0 // idx p3
};
float[] texCoords = {
1, 1, // idx t0
1, 0, // idx t1
0, 1, // idx t2
0, 0 // idx t3
};
/**
* points:
* 1 3
* ------- texture:
* |\ | 1,1 1,0
* | \ | -------
* | \ | | |
* | \ | | |
* | \| -------
* ------- 0,1 0,0
* 0 2
*
* texture[3] 0,0 maps to vertex 2
* texture[2] 0,1 maps to vertex 0
* texture[0] 1,1 maps to vertex 1
* texture[1] 1,0 maps to vertex 3
*
* Two triangles define rectangular faces:
* p0, t0, p1, t1, p2, t2 // First triangle of a textured rectangle
* p0, t0, p2, t2, p3, t3 // Second triangle of a textured rectangle
*/
int[] faces = {
2, 2, 1, 1, 0, 0,
2, 2, 3, 3, 1, 1
};
this.getPoints().setAll(points);
this.getTexCoords().setAll(texCoords);
this.getFaces().setAll(faces);
}
}
The last 3 lines of the comment come from Class TriangleMesh. My problem is that I do not see a match between their definition of the faces array and the faces array in the code. Thus don't understand how to use faces array in general for other cases. Should it not be this instead:
评论的最后 3 行来自Class TriangleMesh。我的问题是我没有看到他们对 faces 数组的定义与代码中的 faces 数组相匹配。因此不明白如何在其他情况下使用面数组。不应该是这样的:
int[] faces = {
2, 3, 0, 2, 1, 0,
2, 3, 1, 0, 3, 1
};
But then nothing renders of the rectangle. What am I missing and what should go into the faces array in general?
但随后没有渲染矩形。我错过了什么,一般来说什么应该进入faces数组?
采纳答案by jewelsea
Explanation of how the face direction works
面方向如何工作的说明
The direction in which the face is defined is important. In the working sample, the point of the first face is 2, 1, 0 (i.e. the triangle is defined in a counter-clockwise order). In the faces array you suggest, the first face is 2, 0, 1 (clockwise). A face which is defined in a clockwise manner faces away from the viewer. A face which is defined in a counter-clockwise manner faces toward the viewer.
定义人脸的方向很重要。在工作样本中,第一个面的点为 2, 1, 0(即三角形按逆时针顺序定义)。在您建议的面数组中,第一个面是 2, 0, 1(顺时针)。以顺时针方式定义的面背向观察者。以逆时针方式定义的面面向观察者。
How to make your mesh visible
如何使您的网格可见
If you take your suggested face definition and rotate the mesh 180 degrees round the Y axis, you will see the face. Without rotation of the mesh, you will by default be looking at the back of the face, and the back of the mesh will be culled (i.e. not visible).
如果您采用建议的面定义并将网格围绕 Y 轴旋转 180 度,您将看到该面。如果不旋转网格,默认情况下您将看到脸部的背面,并且网格的背面将被剔除(即不可见)。
Another way to see your mesh without rotation is to set the cull face of the Meshto CullFace.NONE, then the back of the mesh will show (though as it will just show as black rather than a shaded region).
另一种无需旋转即可查看网格的方法是将网格的剔除面设置为CullFace.NONE,然后网格的背面将显示(尽管它只会显示为黑色而不是阴影区域)。
A note on the comments in your supplied code
关于您提供的代码中的注释的注释
The comment in your code sample is slightly misleading, it should reflect the the actual face definition rather than a face definition which doesn't really work as expected.
您的代码示例中的注释有点误导,它应该反映实际的人脸定义,而不是真正不能按预期工作的人脸定义。
Documentation request change suggestion
文档请求更改建议
IMO, the TriangleMeshdocumentation should be enhanced, I logged a change request in the JavaFX issue trackeragainst the runtime project to request this enhancement.
IMO,应增强TriangleMesh文档,我在JavaFX 问题跟踪器中针对运行时项目记录了更改请求以请求此增强。
Change request for documentation to highlight ordering of points in mesh faces is:
更改文档以突出显示网格面中点的顺序是:
RT-34292 Document importance of TriangleMesh order of elements
RT-34292 文档 TriangleMesh 元素顺序的重要性
Umbrella change request for documentation of the Java 8 3D API is:
Java 8 3D API 文档的总括更改请求是:
RT-26385 Finish javadoc for FX 8 3D API
RT-26385 完成 FX 8 3D API 的 javadoc
Demo
演示
Here is a sample test harness you can use for playing around with this concepts in order to understand them better.
这是一个示例测试工具,您可以使用它来玩弄这些概念,以便更好地理解它们。
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
// drag the mouse over the rectangle to rotate it.
public class RectangleViewer extends Application {
double anchorX, anchorY, anchorAngle;
private PerspectiveCamera addCamera(Scene scene) {
PerspectiveCamera perspectiveCamera = new PerspectiveCamera(false);
scene.setCamera(perspectiveCamera);
return perspectiveCamera;
}
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
final MeshView rect = new MeshView(
new Shape3DRectangle(200, 200)
);
rect.setMaterial(new PhongMaterial(Color.DARKGREEN));
rect.setRotationAxis(Rotate.Y_AXIS);
rect.setTranslateX(250);
rect.setTranslateY(250);
// try commenting this line out to see what it's effect is . . .
rect.setCullFace(CullFace.NONE);
final Group root = new Group(rect);
final Scene scene = new Scene(root, 500, 500, true);
scene.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent event) {
anchorX = event.getSceneX();
anchorY = event.getSceneY();
anchorAngle = rect.getRotate();
}
});
scene.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent event) {
rect.setRotate(anchorAngle + anchorX - event.getSceneX());
}
});
addCamera(scene);
primaryStage.setScene(scene);
primaryStage.show();
}
public class Shape3DRectangle extends TriangleMesh {
public Shape3DRectangle(float Width, float Height) {
float[] points = {
-Width/2, Height/2, 0, // idx p0
-Width/2, -Height/2, 0, // idx p1
Width/2, Height/2, 0, // idx p2
Width/2, -Height/2, 0 // idx p3
};
float[] texCoords = {
1, 1, // idx t0
1, 0, // idx t1
0, 1, // idx t2
0, 0 // idx t3
};
/**
* points:
* 1 3
* ------- texture:
* |\ | 1,1 1,0
* | \ | -------
* | \ | | |
* | \ | | |
* | \| -------
* ------- 0,1 0,0
* 0 2
*
* texture[3] 0,0 maps to vertex 2
* texture[2] 0,1 maps to vertex 0
* texture[0] 1,1 maps to vertex 1
* texture[1] 1,0 maps to vertex 3
*
* Two triangles define rectangular faces:
* p0, t0, p1, t1, p2, t2 // First triangle of a textured rectangle
* p0, t0, p2, t2, p3, t3 // Second triangle of a textured rectangle
*/
// if you use the co-ordinates as defined in the above comment, it will be all messed up
// int[] faces = {
// 0, 0, 1, 1, 2, 2,
// 0, 0, 2, 2, 3, 3
// };
// try defining faces in a counter-clockwise order to see what the difference is.
// int[] faces = {
// 2, 2, 1, 1, 0, 0,
// 2, 2, 3, 3, 1, 1
// };
// try defining faces in a clockwise order to see what the difference is.
int[] faces = {
2, 3, 0, 2, 1, 0,
2, 3, 1, 0, 3, 1
};
this.getPoints().setAll(points);
this.getTexCoords().setAll(texCoords);
this.getFaces().setAll(faces);
}
}
}
Demo Output
演示输出
Front and back faces of the rectangle mesh when the rectangle is drawn to be by default facing away the viewer (by defining a face in a clockwise direction) and with a CullFace.NONE setting (win7 jdkb115).
默认情况下,矩形网格的正面和背面在绘制矩形时背对观察者(通过定义顺时针方向的面)并使用 CullFace.NONE 设置 (win7 jdkb115)。