Javafx Quadrilateral Mesh

前端 未结 1 1190
执念已碎
执念已碎 2021-01-20 17:55

I need to display a quadrilateral mesh in javafx each mesh face having 4 points i have tried some triangle mesh examples from fxyz library, but not sure how does it work for

相关标签:
1条回答
  • 2021-01-20 18:25

    The 3DViewer project that is available at the OpenJFX repository, contains already a PolygonalMesh implementation, that allows any number of points per face, so any polygon can be a face.

    You can use them that mesh implementation in a PolygonMeshView, instead of the regular MeshView.

    Since a triangle is a valid polygon, any TriangleMesh can be easily used as a PolygonMesh.

    For instance, the CuboidMesh from FXyz library has the following implementation assuming a PolygonMesh:

    private PolygonMesh getTriangleMesh(float width, float height, float depth) {
        float L = 2f * width + 2f * depth;
        float H = height + 2f * depth;
        float hw = width/2f, hh = height/2f, hd = depth/2f;        
    
        float[] points = new float[] {
                hw, hh, hd,             hw, hh, -hd,
                hw, -hh, hd,            hw, -hh, -hd,
                -hw, hh, hd,            -hw, hh, -hd,
                -hw, -hh, hd,           -hw, -hh, -hd
            };
    
        float[] texCoords = new float[] {
                depth / L, 0f,                              (depth + width) / L, 0f,
                0f, depth / H,                              depth / L, depth / H, 
                (depth + width) / L, depth / H,             (2f * depth + width) / L, depth/H,  
                1f, depth / H,                              0f, (depth + height) / H,    
                depth / L, (depth + height)/H,              (depth + width) / L, (depth + height) / H,  
                (2f * depth + width) / L, (depth + height) / H,  1f, (depth + height) / H,
                depth / L, 1f,                              (depth + width) / L, 1f        
            };
    
        int[][] faces = new int[][] {
            {0, 8, 2, 3, 1, 7},            {2, 3, 3, 2, 1, 7},            
            {4, 9, 5, 10, 6, 4},           {6, 4, 5, 10, 7, 5},            
            {0, 8, 1, 12, 4, 9},           {4, 9, 1, 12, 5, 13},            
            {2, 3, 6, 4, 3, 0},            {3, 0, 6, 4, 7, 1},            
            {0, 8, 4, 9, 2, 3},            {2, 3, 4, 9, 6, 4},            
            {1, 11, 3, 6, 5, 10},          {5, 10, 3, 6, 7, 5}
            };
    
        int[] smooth = new int[] {
            1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6
        };
    
        PolygonMesh mesh = new PolygonMesh(points, texCoords, faces);
        mesh.getFaceSmoothingGroups().addAll(smooth);
        return mesh;
    }
    

    This gives the following result:

    private double mouseOldX, mouseOldY = 0;
    private final Rotate rotateX = new Rotate(0, Rotate.X_AXIS);
    private final Rotate rotateY = new Rotate(0, Rotate.Y_AXIS);
    
    @Override
    public void start(Stage primaryStage) {
        PolygonMeshView meshView = new PolygonMeshView(getTriangleMesh(100, 150, 200));
        meshView.setDrawMode(DrawMode.LINE);
        meshView.setCullFace(CullFace.NONE);
        meshView.setMaterial(new PhongMaterial(Color.LIGHTYELLOW));
    
        Scene scene = new Scene(new Group(meshView), 500, 300, true, SceneAntialiasing.BALANCED);
        scene.setOnMousePressed(event -> {
            mouseOldX = event.getSceneX();
            mouseOldY = event.getSceneY();
        });
    
        scene.setOnMouseDragged(event -> {
            rotateX.setAngle(rotateX.getAngle() - (event.getSceneY() - mouseOldY));
            rotateY.setAngle(rotateY.getAngle() + (event.getSceneX() - mouseOldX));
            mouseOldX = event.getSceneX();
            mouseOldY = event.getSceneY();
        });
    
        PerspectiveCamera camera = new PerspectiveCamera(false);
        camera.setNearClip(0.1);
        camera.setFarClip(10000.0);
        camera.getTransforms().addAll(rotateX, rotateY, new Translate(-250, -150, 0));
        scene.setCamera(camera);
    
        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    

    But if we combine the triangles of faces in same sides of the prism, we can easily generate the quadrilateral faces. Note that points and texCoords remain the same:

    private PolygonMesh getQuadrilateralMesh(float width, float height, float depth) {
        float L = 2f * width + 2f * depth;
        float H = height + 2f * depth;
        float hw = width/2f, hh = height/2f, hd = depth/2f;        
    
        float[] points = new float[] {
                hw, hh, hd,             hw, hh, -hd,
                hw, -hh, hd,            hw, -hh, -hd,
                -hw, hh, hd,            -hw, hh, -hd,
                -hw, -hh, hd,           -hw, -hh, -hd
            };
    
        float[] texCoords = new float[] {
                depth / L, 0f,                              (depth + width) / L, 0f,
                0f, depth / H,                              depth / L, depth / H, 
                (depth + width) / L, depth / H,             (2f * depth + width) / L, depth/H,  
                1f, depth / H,                              0f, (depth + height) / H,    
                depth / L, (depth + height)/H,              (depth + width) / L, (depth + height) / H,  
                (2f * depth + width) / L, (depth + height) / H,  1f, (depth + height) / H,
                depth / L, 1f,                              (depth + width) / L, 1f        
            };
    
        int[][] faces = new int[][] {
            {0, 8, 2, 3, 3, 2, 1, 7},         
            {4, 9, 5, 10, 7, 5, 6, 4},           
            {0, 8, 1, 12, 5, 13, 4, 9},            
            {2, 3, 6, 4, 7, 1, 3, 0},            
            {0, 8, 4, 9, 6, 4, 2, 3},         
            {1, 11, 3, 6, 7, 5, 5, 10}
        };
    
        int[] smooth = new int[] {
            1, 2, 3, 4, 5, 6
        };
    
        PolygonMesh mesh = new PolygonMesh(points, texCoords, faces);
        mesh.getFaceSmoothingGroups().addAll(smooth);
        return mesh;
    }
    

    That will be used as:

    @Override
    public void start(Stage primaryStage) {
        PolygonMeshView meshView = new PolygonMeshView(getQuadrilateralMesh(100, 150, 200));
        ...
    }
    

    giving the expected result:

    Note that for this sample each face is using points and texture indices, but you normal indices could be added as well.

    0 讨论(0)
提交回复
热议问题