我用Java和Java3D建立了一个相对简单的银河系模型,这个模型可以“飞”过去。
到目前为止,我有一个简单的版本,可以读取40,000颗已知的恒星,并将它们(带有keyboard+mouse导航)显示为Sphere对象。然而,有几个问题阻碍了进一步的进展。
我正在努力解决的问题之一是,我需要根据恒星的表观星等来渲染它们,这是一颗恒星的绝对亮度(对数尺度)和它与观察者之间的距离的函数。表观星等非常低的恒星(如从地球轨道上看到的半人马座比邻星)应该是不可见的,而极亮的恒星(如Deneb)即使在离地球相对较远的地方也应该是可见的。
因此,我不能仅仅根据恒星的固定“实际”大小和它们与当前观测地点的距离来显示它们。这会导致即使是非常暗淡的近星也会产生巨大的气泡,而像Deneb这样的疯狂发光的恒星由于它们的距离而完全不显示。
问题是,在不动态分配和删除Java3d对象的情况下,我如何能够根据恒星的表观星等来表示它的图像,该星等是根据它与当前视点位置的距离变化的?或者,如果在渲染开始后,我必须在Java3D中更改对象,我如何才能做到这一点而不杀死我的帧速率呢?
我试过用透明的方法,这只会让巨大的圆圈更难看。我试过用雾,但雾气完全消除了遥远的星星(和星座线)。我尝试过将Sphere转换为Shape3D对象,但这占用了堆空间的两倍。
一个令人高兴的特例是,我不需要显示任何星等大于7点的恒星,因为人眼看不到它们。理论上,我只需要根据我目前在太空中的位置,为我能看到的任何东西生成一个3D物体。这不仅可以提高为数据库中的每个恒星创建Sphere对象的性能,还可以帮助我避免耗尽Java堆空间。(我想包括100,000多个真正的恒星,但我在40,000之后耗尽了堆空间,而且我尝试过的Java设置没有给我更多的堆空间。)
我知道这种动态显示恒星亮度是可能的。非凡的空间引擎仿真程序的创建者做到了这一点(并设法获得60帧每秒)。我不知道他是怎么做到的。
我完全希望我已经达到了我天真的实现的极限,获得可接受的性能和功能的唯一方法是重新设计整个显示概念。我希望看到一些关于如何使用Java3D实现动态对象可见性的具体答案,但在这一点上,我将满足于专家猜测。(我不想放弃Java3D,但我也愿意接受一些具体的建议。)
发布于 2011-06-22 12:56:52
可以管理对象的可见性,而无需添加和从场景图中删除它们,如下所示:
在Shape3D的外观中添加一个RenderingAttributes实例,并调用‘RenderingAttributes.setVisible(布尔可见)’。通过将单个实例添加到多个外观中,可以共享单个实例,这样就可以同步它们的Shape3D可见性。
将对象添加到SharedGroups,并通过链接节点链接到场景图中的父对象。当调用'Link.setSharedGroup(mySharedGroup)‘时,对象将是可见的,当调用'Link.setSharedGroup(null)’时,它们将是不可见的。
使用子索引模式CHILD_MASK在一个或多个交换机分组节点中收集对象。BitSet用于指定呈现开关的哪个子节点。
堆大小
在Win XP 32位和4 GB RAM上,我的堆大小设置为:-Xmx1536m。
球
您的Sphere对象是如何构造的?你用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
https://stackoverflow.com/questions/6433091
复制相似问题