面部方向如何工作的解释
定义面部的方向很重要。在工作示例中,第一个面的点是 2、1、0(即,三角形是按逆时针顺序定义的)。在您建议的 faces 数组中,第一个面是 2, 0, 1(顺时针)。以顺时针方式定义的面背向观察者。以逆时针方式定义的面朝向观察者。
如何让你的网格可见
如果您采用建议的面定义并将网格绕 Y 轴旋转 180 度,您将看到面。如果不旋转网格,默认情况下您将看到脸部的背面,并且网格的背面将被剔除(即不可见)。
另一种在不旋转的情况下查看网格的方法是 set the cull face of the Mesh 到 CullFace.NONE,然后网格的背面将显示(尽管它只会显示为黑色而不是阴影区域)。
关于您提供的代码中的 cmets 的注释
您的代码示例中的注释有点误导,它应该反映实际的人脸定义,而不是不能真正按预期工作的人脸定义。
文档请求更改建议
IMO,TriangleMesh 文档应该得到增强,我在 JavaFX 问题跟踪器中记录了针对运行时项目的更改请求以请求此增强。
更改文档以突出显示网格面中点的顺序的请求是:
JDK-8122785 Document importance of TriangleMesh order of elements
Java 8 3D API 文档的总括变更请求是:
JDK-8101810 Finish javadoc for FX 8 3D API
演示
这是一个示例测试工具,您可以使用这些测试工具来玩弄这些概念,以便更好地理解它们。
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);
}
}
}
演示输出
矩形网格的正面和背面在绘制矩形时默认背向观察者(通过定义顺时针方向的面)并具有 CullFace.NONE 设置 (win7 jdkb115)。
常见问题解答
为什么是高度/2
我以这种方式定义模型坐标,因为在这种情况下,我希望我正在旋转的 3D 形状的中心是该形状的centroid。这样我就可以围绕其质心旋转形状,而无需执行额外的平移。请参阅 pivot point rotation 以查看围绕任意枢轴点旋转所需的额外平移。
坐标原点是右下角吗?
涉及多个坐标。具有局部坐标系的模型有坐标(参见@987654328@ 文档):
Node 类定义了一个传统的计算机图形“局部”坐标系,其中 x 轴向右增加,y 轴向下增加。形状的具体节点类提供了用于定义该局部坐标空间内形状的几何形状和位置的变量。
相机操作的场景有坐标。在 3D 透视应用程序中,相机是PerspectiveCamera。关于它如何影响坐标的信息是:
默认情况下,此摄像机位于场景中心,并沿 Z 轴正方向观察。此相机定义的坐标系的原点位于面板的左上角,Y 轴指向下方,Z 轴指向远离观察者(进入屏幕)的方向。如果将 PerspectiveCamera 节点添加到场景图中,则转换后的相机位置和方向将定义相机的位置和相机正在看的方向。
mesh 中也有纹理坐标。这些是completely different 并将纹理贴图上的点映射到模型上的顶点:
术语 texCoord 用于表示单个顶点的一对 2D 纹理坐标 (u, v),而术语 texCoords(复数)用于表示多个顶点的纹理坐标集。