我有以下代码在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中的新值自动更新点的位置。
答案 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();
}
进一步说明和提示:
不要忘记设置写入坐标的功能:
pointArray.setCapability(PointArray.ALLOW_COORDINATE_WRITE);
您甚至可以考虑不使用Point3f
数组,并直接在PointArray
设置坐标
在某些系统上,本机渲染组件有点奇怪。对于Java3D或其他基于OpenGL的窗口,这意味着窗口最初是灰色的,除非您调整大小或重新绘制它。你可以通过添加
来避免这种情况System.setProperty("sun.awt.noerasebackground", "true");
作为main
方法的第一行。