如何提高Javafx 3d性能? [英] How to improve Javafx 3d performance?

查看:107
本文介绍了如何提高Javafx 3d性能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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

公共类TetrahedronMesh扩展TriangleMesh {
private ArrayList< Point3i>顶点;
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)));
面对[facesCounter] = pointCounter + 0;
面对[facesCounter + 1] = pointCounter + 0;
面对[facesCounter + 2] = pointCounter + 1;
面对[facesCounter + 3] = pointCounter + 1;
面对[facesCounter + 4] = pointCounter + 2;
面对[facesCounter + 5] = pointCounter + 2;
面对[facesCounter + 6] = pointCounter + 1;
面对[facesCounter + 7] = pointCounter + 1;
面对[facesCounter + 8] = pointCounter + 0;
面对[facesCounter + 9] = pointCounter + 0;
面对[facesCounter + 10] = pointCounter + 3;
面对[facesCounter + 11] = pointCounter + 3;
面对[facesCounter + 12] = pointCounter + 2;
面对[facesCounter + 13] = pointCounter + 2;
面对[facesCounter + 14] = pointCounter + 1;
面对[facesCounter + 15] = pointCounter + 1;
面对[facesCounter + 16] = pointCounter + 3;
面对[facesCounter + 17] = pointCounter + 4;
面对[facesCounter + 18] = pointCounter + 0;
面对[facesCounter + 19] = pointCounter + 0;
面对[facesCounter + 20] = pointCounter + 2;
面对[facesCounter + 21] = pointCounter + 2;
面对[facesCounter + 22] = pointCounter + 3;
面对[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 );
}
}
});


I am doing a javafx visualisation application for 3d points. As I am new to javafx, I started from the tutorial provided in the oracle website:

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

The example above runs perfect on my Mac, But after adding more points, the mouse drag, which causes the camera to rotate and thus people can view the objects from different angle, became very slow and simply not applicable any more.

I currently have a data for a rabbit with about 40000 points:

The code I used to rotate camera:

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

which is the same as in the oracle example.

What I have tried:

  1. set JVM flag -Djavafx.animation.fullspeed=true, this helped a bit, but not significant.
  2. set JVM flag -Djavafx.autoproxy.disable=true, this did not help.
  3. set Cache to true and CacheHint to Cache.SPEED, this did not make much difference.
  4. create another thread to do the rotation, and sync back after calculation, this did not help neither.

Any help is appreciated.Thanks in advance!

解决方案

Here is how I made a point cloud using tetrahedrons in a triangle mesh. seems to run faster than using spheres or squares. this code helped me 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 code as follows

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

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

Picking the point using the scene

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);
            }
        }
    });

这篇关于如何提高Javafx 3d性能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆