Wanting to implements hooks/callbacks for changes to Spatial/Vector3f etc. jme3 r7456

Hey,

Is there any good reason why I shouldn’t try to modify jme3 to implement hooks(callbacks) for elements like Vector3f / Spatial / Node with the purpose of having jme3 do no processing when there is no modifications in the scene, like when nothing changes, no nodes or camera move… and if they do move/change then only related stuff/nodes should change - as opposed to always recalculating all .?

By the way, can I modify jme3 and post my own version somewhere ? like on googlecode released under New BSD license or so; but it’s gonna be a pain to keep it up to date with the real jme3 from svn

So far, I’ve hooked Transform, Vector3f & Quaternion with the purpose of having my child Node keep it’s local transform as it it was the world transform (ie. as if it has no parents) such that when any parent (includes grandparents etc.) change this child gets its local transform updated so as to counter the parent’s worldTransform… well anyway the point is, when any of its parents change it will be notified and adjust itself accordingly - I realize there is something similar done with with Spatial refreshFlags but I wanted to update the childNode’s transforms differently than what that does - hence why I implemented hooks: the child hooks on parent’s world transform and is notified when that one changes(by getting called aka callback) and so it can update itself.

Next I intend to hook Node and whatever else, gonna try and track all things down to the scene rendering I guess, to see what needs to be hooked such that when showing the scene nothing needs to be recalculated - if scene hasn’t changed (so far, with only those 3 hooks above, I noticed that there is a lot of recalculations but yeah that’s due to my test example doing intersections on every update hmm)

=======

if you were thinking speed, so far it’s 150fps for my testcase when asserts are enabled (vm arg: “-ea”) and about 941fps when they are disabled. I’d post the testcase but it uses lots of other classes, can’t really post it to be compilable

=====

also I’ll be removing chained calls due to decreased readability; unless there’s a reason unbeknownst to me (please let me know?)

so far it seems only this case could induce more expensiveness:

[java]vars.vect3.set( direction ).normalizeLocal();[/java]

vs

[java]vars.vect3.set( direction )

vars.vect3.normalizeLocal();[/java]

that is, retrieving fields (ie. vect3) is more expensive than having it returned (return this) and chained? possibly

======

by the way, my code is all red - cannot compile it yet but can someone tell me if store and return here are different but supposed to be the same?(I just noticed that now)

[java]public Vector3f transformVector(final Vector3f in, Vector3f store){

if (store == null)

store = new Vector3f();

// multiply with scale first, then rotate, finally translate (cf.

// Eberly)

return rot.mult(store.set(in).multLocal(scale), store).addLocal(translation);

}[/java]

EDIT: nvm, it returns store indeed, but see what I mean about readability? it basically calls .mult( store, store ); that is same ref is both in and out

but check this out (I lol-ed a lot trying to read the Vector3f o part):

[java] /**

  • Calculates the minimum bounding sphere of 4 points. Used in welzl’s
  • algorithm.

    *
  • @param O
  •        The 1st point inside the sphere.<br />
    
  • @param A
  •        The 2nd point inside the sphere.<br />
    
  • @param B
  •        The 3rd point inside the sphere.<br />
    
  • @param C
  •        The 4th point inside the sphere.<br />
    
  • @see #calcWelzl(java.nio.FloatBuffer)

    */

    private void setSphere(Vector3f O, Vector3f A, Vector3f B, Vector3f C) {

    Vector3f a = A.subtract(O);

    Vector3f b = B.subtract(O);

    Vector3f c = C.subtract(O);



    float Denominator = 2.0f * (a.x * (b.y * c.z - c.y * b.z) - b.x
  • (a.y * c.z - c.y * a.z) + c.x * (a.y * b.z - b.y * a.z));

    if (Denominator == 0) {

    center.set(0, 0, 0);

    radius = 0;

    } else {

    Vector3f o = a.cross(b).multLocal(c.lengthSquared()).addLocal(

    c.cross(a).multLocal(b.lengthSquared())).addLocal(

    b.cross©.multLocal(a.lengthSquared())).divideLocal(

    Denominator);



    radius = o.length() * radiusEpsilon;

    O.add(o, center);

    }

    }[/java]

For the first point, I really doubt the use of partially updating the scene graph in a full scale game. And I wonder how it would scale with a very complex scene, with lots of things in movements (vegetation, particle emitters etc…).

What could be interesting is a speed comparison between your changes and the original version of the scene graph on a complex scene.



for the second point i guess



vars.vect3.set( direction ).normalizeLocal();



vs



vars.vect3.set( direction )

vars.vect3.normalizeLocal();



is exactly the same once it’s compiled, some just find the first line more convenient.

So I guess it’s just a matter of taste.

I do find it more convenient and readable in its first form. I’d rather one line, than several.

But it’s just my opinion here, your point is completely valid.

But forbidding this will just lead to frustrating some jME3 users.

1 Like

I’ll agree with @nehon on that second point. It’s entirely a matter of taste. The compiler knows better than most of us and will undoubtedly make things a lot more efficient than we could.



But I have to say that I will, most of the time, use one-liner. I might break it down when it gets confusing for me to reread and to give myself clues. Readability is important. Even then, some code that I revisit after months are not always obvious, hence why I will sometimes cut things into pieces.

1 Like

thanks for reply, I agree about the comparison on a complex scene though I’ve no such scene at the time, also not completed the hooks part…



I also agree that

[java]vars.vect3.set( direction ).normalizeLocal();[/java]

is more readable



but for this one:

[java]Vector3f o = a.cross(b).multLocal(c.lengthSquared()).addLocal(

c.cross(a).multLocal(b.lengthSquared())).addLocal(

b.cross©.multLocal(a.lengthSquared())).divideLocal(

Denominator);[/java]

it’s rather painful for me to even begin to read it lol - it’s rather a turn off which will cause me to postpone doing anything related to it



Or this one took me a while to realize it does return the same store reference:

[java]return rot.mult(store.set(in).multLocal(scale), store).addLocal(translation);[/java]

eventually became:

[java]store.set( in );

store.multLocal( internalScale );

Vector3f ret = internalRotation.mult( store, store );

ret.addLocal( internalTranslation );

assert ret == store;

return ret;[/java]

Hmm, I suppose if when compiled it’s the same thing (thus no speed changes) I would allow call chaining (even though I begun changing code to disallow it, lol?) but I would definitely want to manually change such huge chains as they become rather hard to read. Hmm, so far I guess I will continue with the call chaining disabling (after all I’m not committing them to jme3 xD) - I can always redo them, I wouldn’t mind although there are lots! and I seem to be doing this manually (maybe eclipse has an auto way of doing it that I’m not aware of)



Oh and btw, I’m kind of using lazy onChange hooks, aka it doesn’t notify of change until it gets read ; 'cause it can be changed 100 times and next being read once, it wouldn’t make sense to notify 100 times, just once will do;



I will have a large scene, million of nodes lol - yeah it won’t work if render is sent to vcard for each, but I will need to make something work at that point (and no it’s nothing like minecraft/mythruna xD)

[java]return new Vector3f[] {

center.subtract( axes[0] ).subtractLocal( axes[1] ).subtractLocal( axes[2] ),

center.add( axes[0] ).subtractLocal( axes[1] ).subtractLocal( axes[2] ),

center.add( axes[0] ).addLocal( axes[1] ).subtractLocal( axes[2] ),

center.subtract( axes[0] ).addLocal( axes[1] ).subtractLocal( axes[2] ),

center.add( axes[0] ).subtractLocal( axes[1] ).addLocal( axes[2] ),

center.subtract( axes[0] ).subtractLocal( axes[1] ).addLocal( axes[2] ),

center.add( axes[0] ).addLocal( axes[1] ).addLocal( axes[2] ),

center.subtract( axes[0] ).addLocal( axes[1] ).addLocal( axes[2] )

};[/java]

ok I think I’d better (manually lol)undo the disabling-of-chaining-calls but I will break stuff in pieces where seems confusing, thanks for replies.

I think I shall start a new google code project(under New BSD license) where I drop the entire jme3 latest from svn as is, then attempt to mod it to add hooks and see where this goes, …beats doing nothing :slight_smile:

Is there any reason why I shouldn’t do this? I don’t know, maybe licensing issues? or not using jme3 name without permission stuff? or maybe I can’t use some jme3 data (ie. pictures?) in this way? please let me know if you wanted to do this similar thing, what would you do? or if you think there are or not any issues (unrelated to adding hooks though)



EDIT:

Your project is using approximately 141 MB out of 4096 MB total quota. that’s jme3 r7507 using mercurial

https://code.google.com/p/jme3-with-hooks/source/browse/

If you really want to go this way (which is contrary to all of how jme works, a control would have callback listeners, not spatial or vectors, letting a location vector report its value could even be dangerous as you are not supposed to change it) how about just extending the specific classes or replacing them with a new set of classes instead of copying all of jme3 and having the hassle of merging changes all the time?

1 Like

Slightly a silly project.

Vectors, Transforms, etc. don’t change unless you tell them to.

Perhaps the hooks can be implemented on your side of the code?



Of course you’re free to do it, but from what I see you will be losing more than gaining …

1 Like

excellent :slight_smile: I like comments like this lol really, it’s like constructive

I thank you for replies! feedback == good xD

@normen:

I don’t like com.jme3.scene.control.Control due to always calling update() regardless of state change, which means I can’t have too many of them? like 100 thousand lol,

unless you meant a different one (or I misunderstand)

I would’ve considered extending but since jme won’t be using the extended ones, I’d have to modify it to make sure it uses them, else I don’t know how to make it notify me of changes it makes to ie. Spatial, Vector3f … - or I don’t know, I kinda of superficially dropped the extends variant

Replacing like Spatial and Vector3f would probably mean the same thing I’m doing, having to track down(or eclipse refactor them) every public field accesses (they are everywhere, probably due to desire to optimize for speed, I imagine, that is why no use of getter/setter - well at least not inside jme)

The hassle of merging changes is indeed something crazy, I’ll probably not do it for a while and see where this can lead, if it’s a dead-end , hey at least I’m learning something on the way - you’d hope :wink:

@Momoko_Fan

I’ll definitely be loosing speed, at least until all hooks are implemented everywhere (unless of course I fail to predict).

I definitely want the hooks on my side of the code, but I may have not thought much about it, but as I thought so far, I’d need to hook the Transform of a Node in order to recalculate another Node’s Transform when the previous one changes (but only do the recalc when prev one changes, as opposed to when using a Control maybe). In other words, this Node’s transform depends on some other Node’s transform in this way (characterized by a method which will do the recalc), which is similar to how jme3 does the update of worldTransform of children of a node that changed, I suppose.

I know it’s rather crazy, but I wanna do it until something stops me such as an impossibility or way too low fps. I’d rather do it for the concept of it if not for anything else.

I kinda like what I’ve done so far, not yet committed but soon…

----ignore the following, too lazy to make it readable:

Here’s something to think about, if something’s listening on when a Node’s transform changes and jme3 is currently updating all nodes transforms such that even if updating the transform’s scale’s X coord would trigger the transform to notify it’s been changed, then how would one postpone such notifies(and coalesce them) until all 3 of transform’s fields (translation/rotation/scale) are updated not to mention until all nodes’ transform are in fact updated. PS: the concept for this is already done, it’s as simple as it seems;



EDIT: been hitting some eclipse and mercurialeclipse bugs which discouraged me from doing this, so I’ve aborted it, if I ever continue it, it will be offline (but I doubt it), anyway foo it, I’ll try the simple way until I can build myself an ide in 3d good enuf for me to foop around in it without getting bugs (yeah right, right?!)

jME3 is state based. That means every state is checked on each update and changed according to the circumstances. Looping through millions of objects is no problem for computers nowadays and it makes for a much cleaner game system. You can go the events based way but its much less predictable (also performance wise) and its something you should not hack into jME3 but you should create your own event system then (e.g. create a control that only sends an event when some value changes, yes, it will be called each update() but your event will not be generated each update)

1 Like

Thank you for that, I am inclined to do it your way, sounds simpler, and these days I’m inclined to go simpler rather than safer

Indeed it’s very crazy to complicate things like that because i usually get lost into details and when it’s done, it’s too complicated to use and keep track (in mind) of how to use it, and make sure I don’t forget stuff so that it’s being used correctly. Anyway, using a control should do it for now, I’ll see more when I reach that…



But I am not yet there back to jme, I’m trying to build up some ground for keeping some data persistently in a database and then go back to jme and try to represent it in 3D, I’ll make a new thread and ask how I’d represent such thing…