如何理解JavaFX三角网格?

时间:2013-11-13 17:25:23

标签: java javafx

试图理解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);
    }
}

评论的最后3行来自Class TriangleMesh。我的问题是我没有看到他们对faces数组的定义和代码中的faces数组之间的匹配。因此,不了解如何在其他情况下使用faces数组。如果不是这样的话:

        int[] faces = {
            2, 3, 0, 2, 1, 0,
            2, 3, 1, 0, 3, 1
        };

然后没有渲染矩形。 我缺少什么,一般应该进入faces数组?

1 个答案:

答案 0 :(得分:11)

面部方向如何运作的说明

定义面部的方向很重要。在工作样本中,第一面的点是2,1,0(即,三角形以逆时针顺序定义)。在你建议的faces数组中,第一个面是2,0,1(顺时针)。以顺时针方式限定的面背向观察者。以逆时针方式限定的面朝向观察者。

如何使网格可见

如果采用建议的面部定义并将网格围绕Y轴旋转180度,您将看到面部。如果没有网格的旋转,您将默认查看面部的背面,并且网格的背面将被剔除(即不可见)。

另一种看待你的网格没有旋转的方法是set the cull face of the MeshCullFace.NONE,然后网格的背面会显示(虽然它只显示为黑色而不是阴影区域)。 / p>

关于您提供的代码中的评论的说明

您的代码示例中的注释略有误导,它应该反映实际的面部定义,而不是面部定义,这种定义实际上并不像预期的那样。

文档请求更改建议

IMO,应该增强TriangleMesh文档,我在JavaFX issue tracker中针对运行时项目记录了一个更改请求以请求此增强。

更改文档请求以突出显示网格面中点的顺序:

RT-34292 Document importance of TriangleMesh order of elements

Java 8 3D API文档的伞更改请求是:

RT-26385 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)。

back front