Another note: if I switch off bounds calculations globally (i.e. use Node.setGlobalIgnoreBounds(true)) because of I 100% know all my shapes always fit the screen (I simply do not need bounds - they are only practically needed for culling), picking fails with NPE.

You commented out glSelect-based picking, which I believe works faster for complicated geometry-based picking because of it works on the triangle level and at least accelerated by driver native code(OK, imagine I want to pick a particle in a particle system only if I really hit particle; particle system is a single shape and has 10,000 particles).

I believe we should leave both picking methods - pure software and glSelect, because of there are cases when one is usable while other is not.

Implementation of PickResults returned by Canvas3D.pickAll(..) drops important information neccessary to make decision which shape is closer to the viewer: it returns middle point of the min/max intersection points, and this is definitely not enough to make decision of which shape to pick in case of mutually intersecting shapes: small cube can be much closer to the viewer than the center of the bigger cube and INSIDE the bigger cube, thus completely invisible but mis-picked basing on the middle point information.

PickResults have to be extended to hold original picking result values.

Another note: if I switch off bounds calculations globally (i.e. use Node.setGlobalIgnoreBounds(true)) because of I 100% know all my shapes always fit the screen (I simply do not need bounds - they are only practically needed for culling), picking fails with NPE.

You commented out glSelect-based picking, which I believe works faster for complicated geometry-based picking because of it works on the triangle level and at least accelerated by driver native code(OK, imagine I want to pick a particle in a particle system only if I really hit particle; particle system is a single shape and has 10,000 particles).

I believe we should leave both picking methods - pure software and glSelect, because of there are cases when one is usable while other is not.

Implementation of PickResults returned by Canvas3D.pickAll(..) drops important information neccessary to make decision which shape is closer to the viewer: it returns middle point of the min/max intersection points, and this is definitely not enough to make decision of which shape to pick in case of mutually intersecting shapes: small cube can be much closer to the viewer than the center of the bigger cube and INSIDE the bigger cube, thus completely invisible but mis-picked basing on the middle point information.

PickResults have to be extended to hold original picking result values.

The reason, why I didn't post the reactivation of an extremely improved glSelect picking is, that I'm not completely ready and I first want to wait until we're on sourceforge and I changed the core package names to org.xith3d, too. gl-picking was considered to be too slow, because of a tumb glSelect-name-to-shape mapping. I changed it to be a lot faster. And - as you already found out - moved it to Canvas3D.pick*().

Can somebody explain the reasons of disabling glSelect picking for Parallel Projection?

1

// never pick on PARALLEL projected atoms

I previous version problems always arose with picking in parallel projection. I guess it is due to a missing gluPickMatrix() function for parallel projection. In fact, picking can be done faster in parallel projection. And in most cases you'll use HUD or something like that for the parallel part. And the HUD system uses it's own picking system.

In one of my projects I use Parallel Projection with quite complicated geometry, no bounds, no culling, no background clear etc., so I can confirm that Xith3D picking was working quite good in previous versions (actually, I added glSelect based picking to Xith3D) - it can be tested in simple picking example available as JWS app on xith.org.

Now I am trying to fix glSelect picking to reach at least the same functionality level as it was before, so I believe I am coming soon with fixes.

There are some strange effects with pickable non-renderable nodes - this is what I am trying to fix at the moment, preferrably leaving the rest unchanged.

There are some inconsistences in rendering of the nodes switched off with setRenderable(false), but it is supposed to be a next step.

In one of my projects I use Parallel Projection with quite complicated geometry, no bounds, no culling, no background clear etc., so I can confirm that Xith3D picking was working quite good in previous versions (actually, I added glSelect based picking to Xith3D) - it can be tested in simple picking example available as JWS app on xith.org.

Now I am trying to fix glSelect picking to reach at least the same functionality level as it was before, so I believe I am coming soon with fixes.

There are some strange effects with pickable non-renderable nodes - this is what I am trying to fix at the moment, preferrably leaving the rest unchanged.

There are some inconsistences in rendering of the nodes switched off with setRenderable(false), but it is supposed to be a next step.

Yuri

It's so good to see someone else actually having a closer look and working on the rendering code .

Looks like I already have a fix for glSelect picking in Parallel Projection, but I can't submit it until I fix also pickable non-renderable issue - I still have no proper visual results (I get picked shapes that marked as pickable=false (though, they should not even be rendered duting picking pass))...

I just added support for minimum-, maximum- and medial distance to PickResult.

Yuri, maybe you could help me with the DisplayList improvement. Please have a look at the most recent changes. I tried to call executeShaders() from within the ShapeAtomPeer, which resulted in strange effects in HUD3DTest. I don't get it, why it doesn't work. And I think it is really important, since it promises a really huge performance boost. So if you can spare a little time, please have a look.

I was thinking to put my hand a bit to improve performance in Quake benchmark, but practically have bunch of problems with my existing codebase at the moment... so first I plan to fix topics top-urgent for me (i.e. finalize migration to the new codebase and add ability to copy-to-texture at the end of the pass, so we can use a kind of CTT with possible extension to RTT).

If some problems with display lists will show up in my code, I will check them immediately. And before submitting pick fixes I will check if I did not break anything in HUD3DTest with my changes.

I was thinking to put my hand a bit to improve performance in Quake benchmark, but practically have bunch of problems with my existing codebase at the moment... so first I plan to fix topics top-urgent for me (i.e. finalize migration to the new codebase and add ability to copy-to-texture at the end of the pass, so we can use a kind of CTT with possible extension to RTT).

If some problems with display lists will show up in my code, I will check them immediately. And before submitting pick fixes I will check if I did not break anything in HUD3DTest with my changes.

I think, I have an idea, why you're not getting any pick result when picking on parallel...

Please check, if you correctly adapted the select-name-offset-generation. The actual select-name pushed to the select-buffer is the current array-index of the shape in the renderbin shifted by an offset. The offset is calculated by adding the previously rendered bin size to the current offset. And I left the parallel groups out of this offset. So this point needs to be changed in CanvasPeer.getAtomByGlobalIndex() and some methods on CanvasPeerImpl, if not already done by you.

I believe my problem is caused by the fact that scenegraph is not re-traversed upon picking mode activation. I get proper shapes (at least shapes on the right positions) picked, but they aremy visual shapes, not those pickable sensors (sensors are not renderable but pickable).

I believe my problem is caused by the fact that scenegraph is not re-traversed upon picking mode activation. I get proper shapes (at least shapes on the right positions) picked, but they aremy visual shapes, not those pickable sensors (sensors are not renderable but pickable).

Now I am looking for a correct way of triggering the re-traversal.

You'll have to call the cullAtoms() method from within the pickAll() method. You'll have to add some getters to make is accessable from there. And don't forget to increment the current frame-id in Renderer before invoking this method.

BTW, I have the question: doesn't it make sense to make all cullAtoms(...) except cullAtoms(Universe, ...) private? I just think where to place few extra checks and want to ensure architectural consistency, so we know we fixed this picking problem once and forever.

BTW, I have the question: doesn't it make sense to make all cullAtoms(...) except cullAtoms(Universe, ...) private? I just think where to place few extra checks and want to ensure architectural consistency, so we know we fixed this picking problem once and forever.

I left only those public, that can possibly and undagerously be called from outside. At the moment only cullAtoms(Universe, ...) is called from outside, but maybe the other two will be in the future. But good to rethink it one more time.

Normally I follow the practice of leaving public only neccessary fields and methods - we are free to change it anyway, and it also pushes developers to think what do they call and what risks it has when they want to promote some private methods to public.

Normally I follow the practice of leaving public only neccessary fields and methods - we are free to change it anyway, and it also pushes developers to think what do they call and what risks it has when they want to promote some private methods to public.

I'm very for good encapsulation and think of it every time I write some piece of code. And I marked these two additional methods public, since it is totally unrisky to use them from outside and nobody wanting to use it is in charge to first check it. But I'm also happy with making them private. So go ahead .

I plan to commit changes as soon as I have my codebase completelly working with new version of Xith3D (not supposed to be too long).

In the meantime, the I discovered following misbehavior:

1) Create new everything, except the scene2) Render once empty scene3) Create scene and attach it (there are A LOT of switches, some are ON, some are OFF)4) Render scene once5) Sleep for 10 seconds to see the results6) Render scene once7) Sleep for 10 seconds to see the results

Result seen at 5) shows that scene rendered incorrect with ALL switches turned ON.Result seen at 7) shows that scene rendered correct (I think) with switches turned as they should be.

This caused by the fact that collectSwitchAtoms(...) in AtomsCollector does not favor the switch states, and cullSwitchAtoms(...) of FrustumCuller is not called at 4) (i.e. on the first frame just after locale modification) due to condition in renderOnce(...) of Renderer (marked with "// if the universe is dirty (e.g. before the first frame) --> collect atoms, cull and sort" comment).

I just checked in details the current implementation of Switch and associated interaction of modification manager with the switch. It really looks like here is a kind of design flaw: if I change state of the switch on the fly, modification manager does not get notified of such a change (OK, this part is supposed to be here but calls are commented out (or just not completely implemented)). Even more, if I pass BitSet (that is mutable) to setChildMask and after change its bits, there is no way to notify modification manager about such change, so scene will not get re-culled and will be rendered in previous state (this is a case for my app, indeed).

Former version of Xith3D was regenerating a list of atoms for every frame, which has been treated as performance bottleneck (and practically it is), so it even potentially (by-design) had no such problems as handling changes in mutable non-Xith3D objects passed to the rendering core (added to scenegraph) by-reference, so theoretically I could have single BitSet to control mutliple switches over the scene (example: I have multiple items on different levels that show up after I complete some task, availability of all items controlled by same BitSet, besides items themselves reside in different subgraphs).

Practically, introduction of Modification Manager will lead us to the same (by concept) architecture as Java3D, where atom list modifications are driven by events generated on scenegraph changes and delivered to the renderer via kind of delaying queue (i.e. the steps are "collect changes", "apply changes to the atom list", "render atom list"), which is beneficial only for relatively static scenes, while highly dynamic scenes (with hundreds or thousands nodes altered per frame) will only loose performance with this. So applications like Quake Benchmark and other walk-through games will sure benefit from the Modification Manager, while some others will degrade in performance.

At the moment, ALL the rendering in new Xith3D core implementation became Modification Manager-centric. I have no problems with all these things, except that it should be a support for no-queue scenegraps also (which is a great benefit for beginner developers also, because of they do not have to worry about of all these mutable/immutable stuff, setting changed flag if the change something, etc.)

Option for apps like mine can be to add a global option that will force scenegraph recull on every frame rendered without even touching modification manager.

1) Create new everything, except the scene2) Render once empty scene3) Create scene and attach it (there are A LOT of switches, some are ON, some are OFF)4) Render scene once5) Sleep for 10 seconds to see the results6) Render scene once7) Sleep for 10 seconds to see the results

Result seen at 5) shows that scene rendered incorrect with ALL switches turned ON.Result seen at 7) shows that scene rendered correct (I think) with switches turned as they should be.

This caused by the fact that collectSwitchAtoms(...) in AtomsCollector does not favor the switch states, and cullSwitchAtoms(...) of FrustumCuller is not called at 4) (i.e. on the first frame just after locale modification) due to condition in renderOnce(...) of Renderer (marked with "// if the universe is dirty (e.g. before the first frame) --> collect atoms, cull and sort" comment).

Hmm... I didn't come to the idea, that one is not rendering the scene constantly. I'll change AtomsCollector to not cull at all and let the FrustumCuller work at the first frame, too. Then this problem should be solved.

I just checked in details the current implementation of Switch and associated interaction of modification manager with the switch. It really looks like here is a kind of design flaw: if I change state of the switch on the fly, modification manager does not get notified of such a change (OK, this part is supposed to be here but calls are commented out (or just not completely implemented)). Even more, if I pass BitSet (that is mutable) to setChildMask and after change its bits, there is no way to notify modification manager about such change, so scene will not get re-culled and will be rendered in previous state (this is a case for my app, indeed).

Former version of Xith3D was regenerating a list of atoms for every frame, which has been treated as performance bottleneck (and practically it is), so it even potentially (by-design) had no such problems as handling changes in mutable non-Xith3D objects passed to the rendering core (added to scenegraph) by-reference, so theoretically I could have single BitSet to control mutliple switches over the scene (example: I have multiple items on different levels that show up after I complete some task, availability of all items controlled by same BitSet, besides items themselves reside in different subgraphs).

Practically, introduction of Modification Manager will lead us to the same (by concept) architecture as Java3D, where atom list modifications are driven by events generated on scenegraph changes and delivered to the renderer via kind of delaying queue (i.e. the steps are "collect changes", "apply changes to the atom list", "render atom list"), which is beneficial only for relatively static scenes, while highly dynamic scenes (with hundreds or thousands nodes altered per frame) will only loose performance with this. So applications like Quake Benchmark and other walk-through games will sure benefit from the Modification Manager, while some others will degrade in performance.

At the moment, ALL the rendering in new Xith3D core implementation became Modification Manager-centric. I have no problems with all these things, except that it should be a support for no-queue scenegraps also (which is a great benefit for beginner developers also, because of they do not have to worry about of all these mutable/immutable stuff, setting changed flag if the change something, etc.)

Option for apps like mine can be to add a global option that will force scenegraph recull on every frame rendered without even touching modification manager.

I don't know, if you checked out the most recent version. The AtomsCollector now doesn't do more than generating the RenderAtoms (and culls, but won't do in a few hours). Culling is done each frame for sure. And it should absolutely honor any change in the scenegraph (even switches). So if you could post an example, where this problem occurrs, it would be very helpful.

The switch-change-events are not needed anymore in the modification manager, since I changed my first plan to update the global atoms list when a change in the scenegraph has been made. I recently removed the global atoms list and went back to the list built by FrustumCuller, since the other way hasn't proven to be faster.

But when a Node is added or removed to / from the scenegraph the modification manager creates the atoms and handles lights and fogs. This can only be faster than collecting lights and fogs each frame. There's no need for the end-developer to set any changed-flags, since this is done automatically. It it doesn't work in any situation, we'll have to fix it. There're no queres to collect changes. Any change in the scenegraph is directly applied to the atoms list (and only to the affected part). So there's no need for any Rendering Hints. Even dynamic sceneres won't loose performance because of this architecture but will certainly gain performance.

Consider a scene, where a Node is added every 100th frame and one is removed every 100th frame. Then 99 frames are rendered with the pregenerated atoms and only before 1 single frame, the atoms are modified (not completely rebuilt). This is in any case faster, isn't it? If a TransformGroup changes it's value, then this change is directly passed through to the atoms without any additional time.

Maybe I've overseen something, but I guess this is the fastest possible way.

Let us go though few cases (some of them are implementation questions, so for me it is most important to understand which changes made with purpose and which are just implementation flaws/questions):

1. Suppose we change color in Coloring Attributes. This indirectly causes a call of ScenegraphModificationsManager.onNodeComponentChanged(), which is empty and thus scenegraph does not consider to be modified. In renderer confition of modManager.hasAnythingChanged() [in latest version as of morning 25 oct CET] prevents scene to be reculled and, most important in this case, atoms to get resorted.

2. Suppose you have many shapes having DIFFERENT instances of ColoringAttributes containing EXACTLY the same information. In this case, all the shaders based on these ColoringAttributes will be created by the "master shader" based on ONLY ONE (the first occured) instance of ColoringAttributes using stateId-based replacement mechanism (Optimization Level 1). Now imagine I am changing color in ONE instance of ColoringAttributes. It is supposed to alter the stateId of changed shader, so generating at least two different shading states for those not changed and one changed ColoringAttributes. Yes, I can see the ShapeAtom.updateShaders(...) method, but it never get called, so after ColoringAttributes change we have problem that the State Change Elimination subsystem (located now in RenderAtomPeer.executeShader(...), Optimization Level 2) treat the updated shader as one equal by its stateId with old ones, so gratefully bypasses its execution. Even more interesting, if we by incident change the "master shader" ColoringAttributes, ALL the shapes will change their colors. [there is also a question of checking the TransparencyAttributes in updateShaders(...), but this I believe implementation point.

Marvin, I would appreciate if you will attend these topics so I can clarify for myself what are the major architectural changes in the core except the core re-organization. The questions I am asking arise because of I already have code 100% correctly working on the older version of Xith3D, and because of it is very big and highly interactive code it acts as a very good test for the engine.

1. Suppose we change color in Coloring Attributes. This indirectly causes a call of ScenegraphModificationsManager.onNodeComponentChanged(), which is empty and thus scenegraph does not consider to be modified. In renderer confition of modManager.hasAnythingChanged() [in latest version as of morning 25 oct CET] prevents scene to be reculled and, most important in this case, atoms to get resorted.

Well, I had the plan to react on a NodeComponent change in the modification manager. But now it is done a different way (see below). I considered a NodeComponent change as not to be an event to force reculling / resorting. Maybe I was wrong. So please correct be in case.

2. Suppose you have many shapes having DIFFERENT instances of ColoringAttributes containing EXACTLY the same information. In this case, all the shaders based on these ColoringAttributes will be created by the "master shader" based on ONLY ONE (the first occured) instance of ColoringAttributes using stateId-based replacement mechanism (Optimization Level 1). Now imagine I am changing color in ONE instance of ColoringAttributes. It is supposed to alter the stateId of changed shader, so generating at least two different shading states for those not changed and one changed ColoringAttributes. Yes, I can see the ShapeAtom.updateShaders(...) method, but it never get called, so after ColoringAttributes change we have problem that the State Change Elimination subsystem (located now in RenderAtomPeer.executeShader(...), Optimization Level 2) treat the updated shader as one equal by its stateId with old ones, so gratefully bypasses its execution. Even more interesting, if we by incident change the "master shader" ColoringAttributes, ALL the shapes will change their colors. [there is also a question of checking the TransparencyAttributes in updateShaders(...), but this I believe implementation point.

ShapeAtom.updateShaders(...) actually is called from Appearance.verifyChange(). This method is called from ShapeAtomPeer.renderAtom(). You can easily trace this by visiting the "Call Hierarchy" in Eclipse. If this way to do it is wrong, we can surely change it. I don't fully understand this shaderId thing. So If I made any mistake, feel free to change it or tell me what I could do better. I certainly want to understant it .

Marvin, I would appreciate if you will attend these topics so I can clarify for myself what are the major architectural changes in the core except the core re-organization. The questions I am asking arise because of I already have code 100% correctly working on the older version of Xith3D, and because of it is very big and highly interactive code it acts as a very good test for the engine.

What do you mean by "attend"? Should I work on it, or should I explain anything?

Such a test is a great thing. And I must say again, that I'm very happy to see you investigating the core code.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org