gwenael

Spaces (world, parent, pivot, local)

Recommended Posts

Hi everyone,

 

For those who may be a little confused about all these spaces (like I was), I made a jsfiddle you can play with.

 

http://jsfiddle.net/gwenaelhagenmuller/Wcegj/

 

It draws the axis of the different spaces thanks to the following function

var drawAxis = function(camera, mesh, drawAncestors, pivot) {...}

drawAncestors must be set to true to draw spaces of the ancestors of the mesh and the world space (but you can also set mesh to null or undefined to draw them). pivot must be set to true to also draw the pivot space.

 

The axis of the pivot space are drawn lighter and smaller to see the difference with those of the local spaces.

 

The white dashes lines represent the 3D hierarchy (parent-child).

 

Things to remember:

 

- position, rotation, scale are used to set the matrix to pass from the parent to the pivot

- pivotMatrix is the matrix to pass from the pivot to the local space

- combined they are the local matrix (from parent to mesh)

- vertices are expressed in local space

- world matrix is the matrix to pass from the local space to the world

- local matrix combined to parent world matrix is the world matrix

 

Enjoy playing with rotation, position, scale, pivotMatrix...

Share this post


Link to post
Share on other sites

That would be a pleasure. That's a great idea to have a Debug object. I think we could also parametize it to log into the console (info and/or warnings and/or errors) and the corresponding calls to it could be removed by JSKompactor.exe I guess.

Share this post


Link to post
Share on other sites

hey gwenael, in looking through the docs and the Mesh class, I can't seem to locate a method, property or simple way to set world coordinates for a parented object.  I know position is local space, and I was hoping for something like "setAbsolutePosition()" to go along with "getAbsolutePosition()" and even tried prototyping my own method to set _absolutePosition, but it's not having any affect on the actual position of the mesh.

 

How should I go about that?

 

thanks for your help,

 

John

Share this post


Link to post
Share on other sites

Hi neoRiley,

 

For now, I think there is no direct way for you to achieve this but here's a gift for you :)

 

http://jsfiddle.net/gwenaelhagenmuller/75WJt/

 

I'll do a pull-request for it tomorrow

very nice!  Thanks very much for your time and response, I apologize that it took me so long to reply - I keep forgetting to subscribe to posts I'm interested in!  I hadn't realized you replied :)

Share this post


Link to post
Share on other sites

Hey Gwenael, In using setAbsolutePosition(), if I do multiple calls to it within a render, the final call is the only one reflected on the transform.  So, I assumed the other changes were being overwritten, and I added computeWorldMatrix(true) and that fixed the issue.  

 

I'm guessing that we don't need all of what's happening in computeWorldMatrix and I'm concerned with impacting performance needlessly.  Could you take a look at what the most efficient way to fix this is?

 

PS> I also tried computeWorldMatrix() without the force flag and that did not work

this.computeWorldMatrix(true);// without this, the final call in a frame overwrites any other calls to setAbsolutePosition()this.setAbsolutePosition(...);

Share this post


Link to post
Share on other sites

Don't be sorry, I only wanted to be sure to understand what you meant. I don't really get why you want to call several times setAbsolutePosition() on a mesh during the computation of a frame. Or is it one call per mesh for several meshes?

Share this post


Link to post
Share on other sites

it's multiple calls on setAbsolutePosition to one object.

 

Scenario - you need to test an objects position based on different conditions within a frame.  

 

Or

 

You want to place an object in a particular location, but you don't know the x/y/z.   So you move/translate the object on x, then y individually to achieve the location you want. example:  you need to define and entry point for your fish into a fish tank.  You didn't create the original model, so you have to create an blank 3d object, and nudge it until it's located in the tank where fish are supposed to spawn.  So, whether I figure out the position and then set it directly or just use the setAbsolutePosition 3x's I still can't do it if the last call erases the first 1 or 2.

 

Or

 

Real world example: You want to create a chase cam - step 1) move camera to same location as target.  Step 2) translate camera on z axis  Step 3) translate camera on y axis to rise above the target to look over shoulder.

 

Hope that helps

Share this post


Link to post
Share on other sites

Ok, now I better understand the reason.

 

You're right, you could figure out the position and then set it with setAbsolutePosition but if you prefer the different approach (using setAbsolutePosition 3 times in a row), we could add parameters to getAbsolutePosition and then pass it to computeWorldMatrix to force recompute only parts which need to be updated. I guess that between 2 calls of setAbsolutePosition, only the local position changed in your case. If you look at the code of setAbsolutePosition, I only set position so if nothing else has changed between two calls (parent matrix, pivot matrix, rotation...), only _localTranslation and _localWorld must be computed to get the new worldMatrix. The parameter passed to getAbsolutePosition and then to computeWorldMatrix would be "onlyLocalTranslationCouldHaveChanged". 

BABYLON.Mesh.prototype.computeWorldMatrix = function (force, onlyLocalTranslationCouldHaveChanged) {    // by default onlyLocalTranslationCouldHaveChanged = false}

Did I understand you well? Is it something that you would like to have? For sure, it would be faster than forcing computeWorldMatrix. It would force to compute only some parts.

Share this post


Link to post
Share on other sites

Something even faster would be to only recompute elements of _localTranslation and _localWorld which are used to compute _worldMatrix.m[12],  _worldMatrix.m[13],  _worldMatrix.m[14]. I didn't think about it but if we are lucky we don't need all the elements of the matrices to compute _worldMatrix.m[12],  _worldMatrix.m[13],  _worldMatrix.m[14].

Share this post


Link to post
Share on other sites

yeah that's essentially what I think would be expected - if I update the position, it should force an update on the matrix for position only.  Something like a getter/setter for position would seem like a good pattern in that the setter takes the new value and manages the translation math in the setter.

 

Same for rotation and scale.  That way we're isolating the math to just whatever we're updating.  I think it's more flexible at that point as well.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Recently Browsing   0 members

    No registered users viewing this page.