[SOLVED] Models are Spatials, but CollisionResults return Geometries

Hi guys,



As everything worked so great with Box Meshes (thus Geometries), I wanted to try it with models.



Scenario: Hello Picking - I shoot at a Model. it works.



However I need to trigger his Control when I shoot him.



My code was:

[java]

CollisionResult hit = results.getClosestCollision();

HitControl hitControl = hit.getGeometry().getControl(HitControl.class);

hitControl.hit(Parameters);

[/java]



Now as of using a model, it gives me a nullpointer for the control, because my Models scene tree looks like:


  • Models/box/box-scene_node

    – Cube

    — cube-entity

    ---- Cube-ogremesh

Cube-geom-1 <<<<<<<<<< this is returned by hit.getGeometry
Mesh

This situation looks quite wrong.

Well you can only hit geometry, while the exporter exports you a node (wich makes perfectly sens for more complex models that cannot be represented as a geometry)



Just do a recursive approch upwards to the rootnode

Code:
current = hitGeometry while(true){ if the needed controll is null then if current.getParent != null current = current.getParent else throw new RuntimeException("We scanned up to the rootnode, but no fitting control was found"); end else return current end

->test with cube-geom-1 , has not the controll has parent
->test with cube-ogremesh , has not the controll has parent
-> ...
-> test with Cube i assume this si where the controll is)
returns the cube

Thanks, then thats the way I must go.



is there a way to save a reference to the models Node in its geometries?

I doubt I want to crawl through nodes at every hit.

Would it be a good idea to save the reference as UserData in the Geometry?

well i guess tahts possible alternativly the opposite, when loading test if node and if recursivly go down till you reach the geometrys, add such a controller to any geometry.

Going up the tree is not at all expensive. Make a method for it and you’re done.

Okay I just dont get it how computers can be so fast.

Guess I will look back at stuff like this when I optimize someday.



But for now, yes, I can crawl the tree all I want and dont have any performance drop at all.



Crazy :smiley:



Thanks for this awesome support

@zanval88 said:
Okay I just dont get it how computers can be so fast.
Guess I will look back at stuff like this when I optimize someday.

But for now, yes, I can crawl the tree all I want and dont have any performance drop at all.

Crazy :D

Thanks for this awesome support

Yes, always do that. Just write clean, readable code without many hacks, don't try to extend existing systems but build your own around them and their workings. Then later when you got a working application you can micro-optimize and put in hacks to gain speed if needed. Its a) more fun and b) giving more realistic and better results ;) Also if you don't hack into existing libraries (e.g. extending stuff to do other things or reusing some existing list of animations or something) but have your own systems to access and manage the other libraries data you have a much easier time to either replace the library with another or accommodate to changes in its code base.

Also don't think you can optimize by just writing stuff different in code, the compiler and JVM are much smarter than you and best understand what you want to do if you again write clean, readable code. Even using a getter to access a variable in an object is basically a null operation, which is why its always recommended in java for readability and consistency reasons. Even the old logic of "not creating too many objects" isn't really valid on modern JVMs as if you create and directly drop them in a stack like situation (that is in one block of code, like a method or something) they will cause basically zero GC overhead :)
1 Like

Premature optimization is a really bad thing.



I don’t like that traverse code though, all you need is:



[java]Spatial search = found geometry



while (search != null && search.getControl(whatever)!=null) {

search =search .getParent();

}

[/java]



At the end of the loop x is either null or the required spatial.



while(true) is generally (not always, but often) a bad sign in code.

Hey @zanval88 you should take a look at this audio. It’s really, really good.



http://www.myplick.com/view/7CRyJCWLM71/CSUA-talk



Remember: First you solve the problem, then you see if the solution is well designed, then you see if you need optmization (that part of the code is slowing down the program), then you see if it’s possible to optmize, finally you optmize.

@zarch said:
Premature optimization is a really bad thing.

I don't like that traverse code though, all you need is:

[java]Spatial search = *found geometry*

while (search != null &amp;&amp; search.getControl(*whatever*)!=null) {
search =search .getParent();
}
[/java]

At the end of the loop x is either null or the required spatial.

while(true) is generally (not always, but often) a bad sign in code.


Zarch's version is exactly right and very straight-forward. I just thought I'd provide a small alternative that keeps the looping logic together because for() is a preferred idiom for me:

[java]
// To me "for" is just slightly more self-documenting because it indicates
// "looping over something" and not just "doing things while some condition"
// It also has the loop condition and advance all together.
for( ; search != null; search = search.getParent() ) {
if( search.getControl( ... ) != null ) {
break;
}

// The nice thing now is that the loop exit logic can be as complicated as
// required in cases where "does it have this control" is not a good enough
// question. Maybe you also want to stop at a certain spatial... or you are
// looking for a control with a certain parameter... or... whatever.
}
[/java]

For similar reasons, I will often invert the logic in the loop, also:
[java]
// To me "for" is just slightly more self-documenting because it indicates
// "looping over something" and not just "doing things while some condition"
// It also has the loop condition and advance all together.
for( ; search != null; search = search.getParent() ) {
if( search.getControl( ... ) == null )
continue;
if( someOther control-specific condition )
continue;
break;
}
[/java]

It allows flatter arrangement of multiple AND'ed loop exit requirements since the NOT versions can just do continue.

Actually I did have one mistake, it should have getControl == null not getControl != null :slight_smile:



Yes, for more complex conditionals something like the for loop there would work well (although you can do the same continue/break tricks with the while loop).

@zarch said:
Actually I did have one mistake, it should have getControl == null not getControl != null :)

Yes, for more complex conditionals something like the for loop there would work well (although you can do the same continue/break tricks with the while loop).


Of course. I just like having the loop logic self-contained. The break/continue logic becomes more complicated in a while loop because you have to make sure to always pass through the loop advance or you create an endless loop.