Java3D 中的动态对象可见性

发布于 2024-11-16 09:02:16 字数 1064 浏览 6 评论 0原文

我正在使用 Java 和 Java3D 构建一个相对简单的可以“飞过”的银河系模型。

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

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

因此,我不能仅根据星星的固定“实际”大小以及距当前观察位置的距离来显示星星。即使是非常暗淡的近距离恒星,这也会产生巨大的斑点,而像天津四这样的极其明亮的恒星由于距离太远而根本不会显示出来。

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

我尝试过使用透明度;这只会让巨大的圆圈变得更难看到。我尝试过使用雾,但这完全模糊了遥远的星星(和星座线)。我尝试将 Spheres 转换为 Shape3D 对象,但这会占用两倍的堆空间。

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

我知道这种动态显示星星的亮度是可能的。非凡的 Space Engine 模拟程序的创建者做到了这一点(并且设法达到每秒 60 帧)。我就是无法弄清楚他是如何做到的。

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

I'm using Java and Java3D to build a relatively simple model of the Milky Way galaxy that can be "flown" through.

So far I have a naive version working that reads in 40,000 known stars and displays them (with keyboard+mouse navigation) as Sphere objects. However, there are several problems blocking further progress.

One of the problems I'm struggling with is that I need to render stars according to their apparent magnitude, which is a function of a star's absolute magnitude of brightness (logarithmic scale) and its current distance from the observer. Stars with a very low apparent magnitude (such as Proxima Centauri as seen from Earth orbit) should be invisible, while extremely bright stars (such as Deneb) should be visible even at a relatively large distance from Earth.

So I can't just display stars based on their fixed "actual" size and their distance from the current observation location. This results in giant blobs for even very dim close stars, while insanely luminous stars like Deneb don't display at all because of their distance.

The question is, how can I represent the image of a star based on its apparent magnitude, which changes according to its distance from the current viewpoint position, without dynamically allocating and deleting Java3d objects? Or, if I have to change objects in Java3D after rendering has begun, how can I do that without killing my frame rate?

I've tried using transparency; that just makes giant circles a little harder to see. I've tried using fog, but that fogs out distant stars (and constellation lines) completely. I've tried converting Spheres to Shape3D objects, but that eats up twice the heap space.

One happy special case is that I don't need to display any star whose apparent magnitude is larger than 7.00, since the human eye can't see them. In theory, I should only need to generate a 3D object for any thing that I can see based on my current position in space. Not only would this improve performance over creating a Sphere object for every star in the database, it would help me avoid running out of Java heap space. (I have over 100,000 real stars I'd like to include, but I'm running out of heap space after 40,000 and no Java setting I've tried is giving me more heap space.)

I know that this sort of dynamic display of star brightness is possible. The creator of the remarkable Space Engine simulation program does it (AND manages to get 60 frames per second). I just can't for the life of me figure out how he does it.

I fully expect that I've hit the limits of my naive implementation and that the only way to get acceptable performance and functionality is to redesign the entire display concept. I'd love to see some specific answers for how to do dynamic object visibility using Java3D, but at this point I'll settle for expert speculation. (I'd prefer not to abandon Java3D, but I'm open to specific recommendations there as well.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小镇女孩 2024-11-23 09:02:16

可以管理对象的可见性,而无需从场景图中添加和删除它们,如下所示:

  • RenderingAttributes

将 RenderingAttributes 实例添加到 Shape3D 的外观并调用“RenderingAttributes.setVisible(booleanvisible)”。可以通过将单个实例添加到多个外观来共享该实例,以便同步其 Shape3D 的可见性。

  • SharedGroup 和 Link

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

  • Switch

收集一个或多个子索引模式为 CHILD_MASK 的 Switch 分组节点中的对象。 BitSet 用于指定呈现 Switch 的哪个子级。

堆大小

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

Sphere

你的 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

八月, 交互式网格

Visibility of objects can be managed without adding and removing them from the scene graph as follows:

  • RenderingAttributes

Add a RenderingAttributes instance to the Shape3D's Appearance and call 'RenderingAttributes.setVisible(boolean visible)'. A single instance can be shared by adding it to several Appearances so that their Shape3D's visibility will be synchronized.

  • SharedGroup and Link

Add the objects to SharedGroups and link them via a Link node to their parent in the scene graph. When calling 'Link.setSharedGroup(mySharedGroup)' the object(s) will be visible and when calling 'Link.setSharedGroup(null)' they will be invisible.

  • Switch

Collect the objects in one or more Switch grouping nodes with child index mode CHILD_MASK. A BitSet is used to specify which child of a Switch is rendered.

Heap size

On Win XP 32 bit with 4 GB RAM my heap size setting is: -Xmx1536m.

Sphere

How are your Sphere objects constructed? Do you use com.sun.j3d.utils.geometry.Sphere?

See also : http://www.java.net/forum/topic/javadesktop/java-desktop-technologies/java-3d/why-large-number-hidden-shapes-slows-rende

August, InteractiveMesh

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文