如何改善Javafx 3d性能?

时间:2014-05-20 01:21:29

标签: java javafx

我正在为3d点做一个javafx可视化应用程序。由于我是javafx的新手,我从oracle网站提供的教程开始:

http://docs.oracle.com/javase/8/javafx/graphics-tutorial/javafx-3d-graphics.htm#JFXGR256

上面的示例在我的Mac上运行完美,但是在添加更多点之后,鼠标拖动会导致相机旋转,因此人们可以从不同的角度查看对象,变得非常慢并且根本不再适用。 / p>

我目前有一个兔子的数据,大约有40000点: visualisation of a rabbit with about 40000 points

我用来旋转相机的代码:

cameraXform.ry.setAngle(cameraXform.ry.getAngle() - mouseDeltaX * MOUSE_SPEED * modifier * ROTATION_SPEED);            
cameraXform.rx.setAngle(cameraXform.rx.getAngle() + mouseDeltaY * MOUSE_SPEED * modifier * ROTATION_SPEED);

与oracle示例中的相同。

我尝试过:

  1. 设置JVM标志-Djavafx.animation.fullspeed = true,这有点帮助,但不重要。
  2. 设置JVM标志-Djavafx.autoproxy.disable = true,这没有帮助。
  3. 将Cache设置为true,将CacheHint设置为Cache.SPEED,这没有太大区别。
  4. 创建另一个线程来进行旋转,并在计算后同步回来,这对两者都没有帮助。
  5. 感谢任何帮助。谢谢!

2 个答案:

答案 0 :(得分:1)

以下是我如何使用三角形网格中的四面体制作点云。似乎比使用球体或方块运行得更快。这段代码帮助了我scalafx google code

import java.util.ArrayList;
import javafx.scene.shape.TriangleMesh;

public class TetrahedronMesh extends TriangleMesh {
    private ArrayList<Point3i> vertices;
    private int[] facesLink;

    public TetrahedronMesh(double length, ArrayList<Point3i> v) {
        this.vertices = v;
        if (length > 0.0) {
            float[] points = new float[vertices.size() * 12];
            int[] faces = new int[vertices.size() * 24];
            facesLink = new int[vertices.size() * 4];
            float[] texCoords = new float[vertices.size() * 12];
            int vertexCounter = 0;
            int primitiveCounter = 0;
            int pointCounter = 0;
            int facesCounter = 0;
            int texCounter = 0;
            for (Point3i vertex : vertices) {
                vertex.scale(100);
                points[primitiveCounter] = vertex.x;
                points[primitiveCounter + 1] = (float) (vertex.y - (length
                        * Math.sqrt(3.0) / 3.0));
                points[primitiveCounter + 2] = -vertex.z;
                points[primitiveCounter + 3] = (float) (vertex.x + (length / 2.0));
                points[primitiveCounter + 4] = (float) (vertex.y + (length
                        * Math.sqrt(3.0) / 6.0));
                points[primitiveCounter + 5] = -vertex.z;
                points[primitiveCounter + 6] = (float) (vertex.x - (length / 2.0));
                points[primitiveCounter + 7] = (float) (vertex.y + (length
                        * Math.sqrt(3.0) / 6.0));
                points[primitiveCounter + 8] = -vertex.z;
                points[primitiveCounter + 9] = vertex.x;
                points[primitiveCounter + 10] = vertex.y;
                points[primitiveCounter + 11] = (float) -(vertex.z - (length * Math
                        .sqrt(2.0 / 3.0)));
                faces[facesCounter] = pointCounter + 0;
                faces[facesCounter + 1] = pointCounter + 0;
                faces[facesCounter + 2] = pointCounter + 1;
                faces[facesCounter + 3] = pointCounter + 1;
                faces[facesCounter + 4] = pointCounter + 2;
                faces[facesCounter + 5] = pointCounter + 2;
                faces[facesCounter + 6] = pointCounter + 1;
                faces[facesCounter + 7] = pointCounter + 1;
                faces[facesCounter + 8] = pointCounter + 0;
                faces[facesCounter + 9] = pointCounter + 0;
                faces[facesCounter + 10] = pointCounter + 3;
                faces[facesCounter + 11] = pointCounter + 3;
                faces[facesCounter + 12] = pointCounter + 2;
                faces[facesCounter + 13] = pointCounter + 2;
                faces[facesCounter + 14] = pointCounter + 1;
                faces[facesCounter + 15] = pointCounter + 1;
                faces[facesCounter + 16] = pointCounter + 3;
                faces[facesCounter + 17] = pointCounter + 4;
                faces[facesCounter + 18] = pointCounter + 0;
                faces[facesCounter + 19] = pointCounter + 0;
                faces[facesCounter + 20] = pointCounter + 2;
                faces[facesCounter + 21] = pointCounter + 2;
                faces[facesCounter + 22] = pointCounter + 3;
                faces[facesCounter + 23] = pointCounter + 5;
                facesLink[pointCounter] = vertexCounter;
                facesLink[pointCounter + 1] = vertexCounter;
                facesLink[pointCounter + 2] = vertexCounter;
                facesLink[pointCounter + 3] = vertexCounter;
                texCoords[texCounter] = 0.5f;
                texCoords[texCounter + 1] = 1.0f;
                texCoords[texCounter + 2] = 0.75f;
                texCoords[texCounter + 3] = (float) (1.0 - Math.sqrt(3.0) / 4.0);
                texCoords[texCounter + 4] = 0.25f;
                texCoords[texCounter + 5] = (float) (1.0 - Math.sqrt(3.0) / 4.0);
                texCoords[texCounter + 6] = 1.0f;
                texCoords[texCounter + 7] = 1.0f;
                texCoords[texCounter + 8] = 0.5f;
                texCoords[texCounter + 9] = (float) (1.0 - Math.sqrt(3.0) / 2.0);
                texCoords[texCounter + 10] = 0.0f;
                texCoords[texCounter + 11] = 1.0f;
                vertexCounter++;
                primitiveCounter += 12;
                pointCounter += 4;
                facesCounter += 24;
                texCounter += 12;
            }
            getPoints().setAll(points);
            getFaces().setAll(faces);
            getTexCoords().setAll(texCoords);
            // getFaceSmoothingGroups().setAll(0, 1, 2, 3);
        }
    }

    public Point3i getPointFromFace(int faceId) {
        return vertices.get(facesLink[faceId]);
    }
}

Point3i代码如下

public class Point3i {
    public int x;
    public int y;
    public int z;

    public Point3i() {
        x = 0;
        y = 0;
        z = 0;
    }
}

使用场景挑选点

scene.setOnMousePressed(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent me) {
            PickResult pr = me.getPickResult();
            int faceId = pr.getIntersectedFace();
            if (faceId != -1) {
                Point3i p = tetrahedronMesh.getPointFromFace(faceId);
            }
        }
    });

答案 1 :(得分:0)

我知道这是旧的,但对其他人来说..

不是一起创建一个新的形状,而是每个预定义的形状 Sphere,Box,Cylinder,允许您设置构造函数中的分割数。

例如,球体默认为64格,32为经度,32为纬度。 你可以很容易地做... =新球(半径,分区); (4是我相信球体的最小值。)