Java3D中的动态对象可见性



我正在使用Java和Java3D构建一个相对简单的银河系模型,该模型可以"飞行"通过。

到目前为止,我有一个简单的版本,可以读取40000颗已知恒星,并将它们(通过键盘+鼠标导航)显示为Sphere对象。然而,有几个问题阻碍了进一步的进展。

我正在努力解决的一个问题是,我需要根据恒星的视星等来渲染它们,视星等是恒星亮度的绝对星等(对数尺度)及其与观测者的当前距离的函数。视星等非常低的恒星(如从地球轨道上看到的半人马座比邻星)应该是不可见的,而极亮的恒星(例如天津四)即使在离地球相对较大的距离也应该是可见的。

因此,我不能仅仅根据恒星的固定"实际"大小和距离当前观测位置的距离来显示它们。这导致即使是非常昏暗的近距离恒星也会出现巨大的斑点,而像天津四这样的疯狂发光的恒星由于距离遥远而根本不会出现。

问题是,在不动态分配和删除Java3d对象的情况下,我如何根据恒星的视星等来表示恒星的图像,视星等根据其与当前视点位置的距离而变化?或者,如果我必须在渲染开始后更改Java3D中的对象,我如何在不降低帧速率的情况下做到这一点?

我尝试过使用透明度;这只会让巨大的圆圈更难看到。我试过用雾,但它完全遮住了遥远的恒星(和星座线)。我曾尝试将"球体"转换为Shape3D对象,但这会占用两倍的堆空间。

一个令人高兴的特殊情况是,我不需要显示任何视星等大于7.00的恒星,因为人眼看不到它们。理论上,我只需要根据我在太空中的当前位置为我能看到的任何东西生成一个3D对象。与为数据库中的每个星创建Sphere对象相比,这不仅可以提高性能,还可以帮助我避免耗尽Java堆空间。(我有超过100000颗真正的星星,我想包括在内,但在40000颗之后,我的堆空间就用完了,而且我尝试过的Java设置都没有给我更多的堆空间。)

我知道这种动态显示恒星亮度是可能的。非凡的太空引擎模拟程序的创建者做到了这一点(AND成功地获得了每秒60帧)。我一辈子都搞不清楚他是怎么做的。

我完全相信我已经达到了我天真实现的极限,获得可接受性能和功能的唯一方法是重新设计整个显示概念。我很想看到一些关于如何使用Java3D进行动态对象可见性的具体答案,但在这一点上,我将接受专家的猜测。(我不想放弃Java3D,但我也愿意接受那里的具体建议。)

对象的可见性可以在不添加或从场景图中删除对象的情况下进行管理,如下所示:

  • 渲染属性

将RenderingAttributes实例添加到Shape3D的外观中,并调用"RenderingAttributes.setVisible(boolean visible)"。通过将单个实例添加到多个外观中,可以共享单个实例,以便同步其Shape3D的可见性。

  • SharedGroup和Link

将对象添加到SharedGroups,并通过"链接"节点将其链接到场景图中的其父对象。当调用"Link.setSharedGroup(mySharedGroup)"时,对象将是可见的,而当调用"Link。setSharedGroup(null)"时它们将是不可见的。

  • 交换机

使用子索引模式child_MASK收集一个或多个Switch分组节点中的对象。位集用于指定渲染Switch的哪个子级。

堆大小

在Win XP 32位4 GB RAM上,我的堆大小设置为:-Xmx1536m。

球体

球体对象是如何构建的?你使用com.sun.j3d.utils.geometry.Sphere吗?

另请参阅:http://www.java.net/forum/topic/javadesktop/java-desktop-technologies/java-3d/why-large-number-hidden-shapes-slows-rende

八月,InteractiveMesh

最新更新