将shape3f移动到由大Point3f数组组成的shape3D中

时间:2015-09-11 15:10:16

标签: java java-3d

我有以下代码在canvas3D窗口中绘制4个点

public final class energon extends JPanel {    

    int s = 0, count = 0;

    public energon() {
        setLayout(new BorderLayout());
        GraphicsConfiguration gc=SimpleUniverse.getPreferredConfiguration();
        Canvas3D canvas3D = new Canvas3D(gc);//See the added gc? this is a preferred config
        add("Center", canvas3D);

        BranchGroup scene = createSceneGraph();
        scene.compile();

        // SimpleUniverse is a Convenience Utility class
        SimpleUniverse simpleU = new SimpleUniverse(canvas3D);


        // This moves the ViewPlatform back a bit so the
        // objects in the scene can be viewed.
        simpleU.getViewingPlatform().setNominalViewingTransform();

        simpleU.addBranchGraph(scene);
    }
    public BranchGroup createSceneGraph() {
        BranchGroup lineGroup = new BranchGroup();
        Appearance app = new Appearance();
        ColoringAttributes ca = new ColoringAttributes(new Color3f(204.0f, 204.0f,          204.0f), ColoringAttributes.SHADE_FLAT);
        app.setColoringAttributes(ca);

        Point3f[] plaPts = new Point3f[4];

        for (int i = 0; i < 2; i++) {
            for (int j = 0; j <2; j++) {
                plaPts[count] = new Point3f(i/10.0f,j/10.0f,0);
                //Look up line, i and j are divided by 10.0f to be able to
                //see the points inside the view screen
                count++;
            }
        }
        PointArray pla = new PointArray(4, GeometryArray.COORDINATES);
        pla.setCoordinates(0, plaPts);
        Shape3D plShape = new Shape3D(pla, app);
        TransformGroup objRotate = new TransformGroup();
        objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRotate.addChild(plShape);
        lineGroup.addChild(objRotate);
        return lineGroup;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(new energon()));
        frame.setSize(300, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

现在我想添加一个timertask,定期更新plaPts Point3f数组中某个点的位置。但是,当我调用plaPts [1] .setX(2)时,屏幕上没有任何反应,它们保持在相同的位置。

为了实现这一点,您是否必须将每个点放在一个单独的TransformGroup(由一个shape3D和一个大小为1的Point3f数组组成)中?我以后会使用100000点,如果它们都在不同的TransformGroups中,它对性能有害吗?有更简单的方法吗?像shape3D.repaint()这样的东西,它会根据plaPTS中的新值自动更新点的位置。

1 个答案:

答案 0 :(得分:0)

使用10000 TransformGroup个实例,会导致可怕的性能(与单PointArray相比)。

您应该查看GeometryArray JavaDocs,尤其是使用数据复制按引用之间的干扰。

较新版本的Java3D仅支持复制方法。 (您的方法可以使用引用方法,但您仍然必须触发更新。)

通过复制使用这一事实意味着当您将Point3f数组传递给PointArray数组的构造函数时,会创建副本 {1}}方法。因此,对这些点的修改不会影响PointArray

相反,您可以使用setCoordinate方法修改点数。以下是一个示例,您只需添加此方法并将PointArray传递给它:

private static void moveOnePointOf(final PointArray pa)
{
    pa.setCapability(PointArray.ALLOW_COORDINATE_WRITE);
    Thread t = new Thread(new Runnable()
    {
        Point3f p = new Point3f();
        @Override
        public void run()
        {
            while (true)
            {
                pa.getCoordinate(0, p);
                p.x = (float)Math.sin(System.currentTimeMillis()/1000.0);;
                pa.setCoordinate(0, p);

                try
                {
                    Thread.sleep(100);
                }
                catch (InterruptedException e)
                {
                    Thread.currentThread().interrupt();
                }
            }
        }
    });
    t.setDaemon(true);
    t.start();
}

进一步说明和提示:

  • Don not 为每个点使用一个线程。这只是一个例子; - )
  • 不要忘记设置写入坐标的功能:

    pointArray.setCapability(PointArray.ALLOW_COORDINATE_WRITE);
    
  • 您甚至可以考虑不使用Point3f数组,并直接在PointArray设置坐标

  • 在某些系统上,本机渲染组件有点奇怪。对于Java3D或其他基于OpenGL的窗口,这意味着窗口最初是灰色的,除非您调整大小或重新绘制它。你可以通过添加

    来避免这种情况
    System.setProperty("sun.awt.noerasebackground", "true");
    

    作为main方法的第一行。