Jump to content

Spaces (world, parent, pivot, local)


gwenael
 Share

Recommended Posts

Hi,

 

If you're viewing this thread, then you're either curious or you would like to better understand the 3D coodinate system which we all work within - usually Cartesian space (x,y,z) coordinates and how we use this as a common thread to work in graphic development.   Most developers without a background in 3D software applications and GUIs are interested in how we view dimensional space graphically.  I and others will be contributing to the documentation for BabylonJS and how we work and depict three and four dimensional space using several mathematical disciplines.  I'll also be relating this directly to functions used regularly in the BabylonJS framework to explain the arguments and variables we use.

 

In the meantime, I came across a fairly simple explaination of Cartesian space and dimensional coordinate systems; so if you would like to better understand some of these concepts, Wikipedia has a pretty good page in which to begin. I was surprised at how much is covered here - not overly comprehensive, but fairly thorough and well written for the most part.

http://en.wikipedia.org/wiki/Cartesian_coordinate_system

 

Please check the documentation link below for BabylonJS reference and usage of the framework:

http://doc.babylonjs.com/

 

Cheers,

 

DBawel

Link to comment
Share on other sites

Let's talk cameras.  Z is always the direction in Cartesian space in which a ray is fired to hit a triange and return pixel information for the renderer to display a single pixel or sub-pixel.  So move your cameras in (x,y,z) space, but always remember your camera will always fire rays to sample polys in its local Z direction.  If anyone wants to learn more about how this relates to Euler angles (Euler math,) then I'm happy to expand upon this - it's very important for gimble lock on cameras, and changing the order of rotation wil correct this mathematicaly - but should be for another discussion.  Cheers.

Link to comment
Share on other sites

  • 2 months later...

I had mentioned how important it was to freze transforms on objects and then remove its proceeedural history in 3D applications.  As many people use Blender, I found step by step instructions for freezing transforms in Blender.  If you freeze transforms (set their matrice's to be at values 0,0,0 in x,y,z) on bones, this wil allow much more freedom for manipulation in all proceedures.  But it's always a good step for any object.

 

Here is the instructions posted on another site by amamic33431:

 

1. Create your controller, say a nurbs circle. I usually do this in the top view.
 
2. Shape the circle into whatever shape you want. (DO NOT MOVE IT OR ROTATE IT) Keep all locations and rotations at zero. Just shape it and scale it.
 
3. Once you are done shaping the controller go back into Object mode and hit (CTRL-A, 1) The scale transforms should now be set back to 1. The rotation and location transforms should have been 0,0,0 already. Because you did not move or rotate the controller while you were shaping it.
 
4. Now create what Blender calls an "Empty". Maya users call this a NULL. (Space Bar, Add, Empty)
 
5. Right click on the controller curve to select it, then Shift-Right click on the "Empty" to add it to your selection and hit (CTRL-P) on the keyboard to parent the "Empty" to the controller curve. Hit "A" to clear the selection and then right click on the "Empty" and hit "G" to grab it and move it around in 3D space.
 
6. Use the "Empty" to scale, rotate, and position the curve wherever you want it. You can snap it to a joint; rotate it to align with the joint chain, etc. Just be sure you are transforming the "Empty" and not the curve. Once you are done positioning the "Empty" lock all of it's transforms in the transform properties window and hide it by hitting "H" on the keyboard.
 
7. If you've done everything right you can now select the controller curve and all of it's location and rotation transforms should still be set at zero. Scale should still be set at one.
 
I hope this helps.
Link to comment
Share on other sites

I just posted this on another topic, as everyone appears to be afraid of quaternions.  Here's the post below:

 

I beg you to use quaternions when rotating objects.  Otherwise you'll never get your object to rotate beyond -89.9 and 89.9 degrees (approximately.)  And once you reach these limits, your object may appear to rotate on more than one axis - depending on it's beginning orientation.  An example would be to rotate a carousel in your scene - using euler vectors the carousel would flip each time you reached these limits.  However, using a constant function such as f(x) = C to provide a constant delta to a quaternion float, you are able to continually rotate the carousel around a single axis with continuity.  

 

At the bottom of this thread is a little primer on quaternion floats and values - not easy to visuallize, but if you just use:

mesh.rotationQuaternion = new BABYLON.Quaternion(x, y, z, w); 

And place it in a scene and experiment by changing the values based on the explaination below, you'll most often use quaternions to rotate objects.

 

1. A quaternion is a complex number with w as the real part and x,y,z as imaginary parts.

2. When a quaternion represents a rotation, then w = cos(theta / 2), where theta is the rotation anglearound the axis of the quaternion.

3. The axis v(v1,v2,v3) of a rotation is encoded as a quaternion: x = v1 sin (theta /2), y = v2 sin (theta /2), z = v3 sin (theta /2).

4. If w = 1 then the quaternion defines 0 rotation angle around an undefined axis v = (0,0,0).

5. If w = 0 then the quaternion defines a half circle rotation since theta then would be +/- pi.

6. If w = -1 the quaternion defines +/- 2pi rotation angle around an undefined axis v = (0,0,0).

7. And a quarter circle rotation around a single axis causes w to be +/- 0.5 and x/y/z to be +/- 0.5

 

As Quaternions are four-dimensional, you need four properties. The x/y/z properties don't correspond to x/y/z in euler angles. With quaternions, each of the properties is a normalized float between 0 and 1, so for example a euler angle of 45/90/180 is represented by a quaternion as approximately .65/-.27/.65/.27.

Got a headache yet?  I hope not, as you simply cannot apply deltas to euler vectors for rotation transforms and return any reliable rotational behavior beyond the limits above.  Please, just play around with it and you'll get it.

 

Link to comment
Share on other sites

  • 2 weeks later...

I thought I might share a process I use to avoid flipping in euler rotations for animation of objects.  This is nothing special, but perhaps not obvious to some developers.  If I need to rotate on multiple axis', I often use a seperate null as a parent for one or more of these axis.  I then rotate the nulls with the object as a child, and not the object directly.  This will allow you to avoid gimble lock as now you will have multiple matrices' to manipulate.  The only time this fails is in the example of a carousel when you need to exceed 360 degrees of rotation on a single axis.  At this point you will need to use quaternion floats.

Link to comment
Share on other sites

  • 2 weeks later...

For those of you who are working from Blender, hrer is how fov in Blender is caculated.

 

According to the Blender documentation, the lens is calculated using FOV = 2 atan(0.5A/f).
 
Where FOV is the "angle of view" in degrees, A is the image area aperture (which is often defined as the longer of either length or width of the image area), and f is the focal length of the lens. This equation assumes the tan function operates on values in degrees - if calculating in radians (as Blender seems to), multiply the right side of the equation by 180/pi. 
 
It appears that Blender uses a constant (16) for variable (A). This seems to indicate that for some reason, the Blender camera is hard-coded to an image aperture dimension of A = 32 units. As long as the unit system is consistent, it won't matter what these units actually are, but if we assume the variable lensvalue in the function is intended to be a focal length in mm, then the formula will only work if it's also assumed that the aperture of the imaged area is fixed at 32mm. 
 
I hope this helps.
Link to comment
Share on other sites

  • 2 weeks later...

Ok.  I have doubters that this math works 100% of the time or controllers (Iceman, love ya!), but I thought I'd post this as I've seen this question asked many times.  The question as how do you steer a ship on the screen - or use any controller to direct vectors?  Roughly stated. :) Here is the my reply..

 

If you register the pick point on the canvas, the math is easy.  Let's say you have a canvas of 1024X1024 and clicking in the center of the canvas returns a value of (0,0) on our pick point of canvas (x,y).  I know this isn't the case with HTML, but this is simply an example - primarily for using any external controller. Using conditional statements:
 
 
if (x > 512) {
    a = ((x - 512) / 5.12));
}  else  {
    a = 0;
}
 
 
if (x < 512) {
    b = -((x - 512) / 5.12));
}  else  {
    b = 0;
}
 
 
if (y > 512) {
    c = ((y - 512) / 5.12));
}  else  {
    c = 0;
}
 
 
if (y < 512) {
    b = -((y - 512) / 5.12));
}  else  {
    b = 0;
}
 
 
If you look at the math for each of these variables a, b, c, d then you have a value of 0 to 100 for each variable.
Then you'll want to average these so that you can direct your ship in a blended direction, and not simply as an additive.
 
This math is:
 
var Blend = (a + b + c + d)
 
if (Blend > 100) {
    BlendDivide = ((a + b + c + d)/100)
}  else  {
    BlendDivide = 1.0   {
}
 
var dir1 = (a / BlendDivide)
var dir2 = (b / BlendDivide)
var dir3 = (c / BlendDivide)
var dir4 = (d / BlendDivide)
 
And you now have a blended direction for each (x,y) vector from a value of 0.0 in the center of your canvas for whatever the pick point is.  This will give you perfect control in whatever direction the user wants to steer.  If you want your (x,y) center to be in a different position on the canvas or more force in any direction, just change the math.
 
You can also use a Triginometry function, but this math is much simpler and easy to add more controls to the blend.
 
DB
Link to comment
Share on other sites

  • 3 weeks later...

It's in the wee early hours of the morning, and I just wrote a new post for working with bone and joint hierarchies - however, after spending more than one hour crafting the perfect discussion, I tried to attach a screenshot I was referencing of the skeleton I built for the Shrek Donkey, and the forum somehow tossed away my entire post.  So, I give up tonight, and am now pouring a tall glass of bourbon.  I'll come back to skeleton hierarchies and the manipulation thereof another time, when the stars are more properly aligned, and when my work's not flushed away like an old floater.  Happy 4th Everyone!  B)

Link to comment
Share on other sites

  • 8 months later...
  • 4 weeks later...

Hello,

Below is a comment I recently posted on trying to understand the behaviors of Euler values for an object. I've covered some of this previously, but it's always valuable to have a general understanding of what Euler angles/values represent, and why you might choose Quaternion over Euler or Euler over Quaternion when developing in babylon.js. And I often read posts asking questions which might be answered by a better understanding of what Euler values typically represent.

 

Quote

 

@Wingnut-

As usual, you are correct. :rolleyes: Euler angles are generally represented by pitch, roll, and yaw angles/values to set the axis of rotation, as well as an angular vector for translation. Although the order of pitch, roll, and yaw are often ordered differently; these should be re-ordered by the developer when necessary to provide the desired behavior for an object's transforms. Basically every transform applied in most every software application and/or base algorithms for object transforms in most frameworks compute in euler angles, and convert these values to quaternion (x,y,z) values to make these processes simpler for the user - as it is much easier to graphically represent quaternion values in graphic applications for a UI as well as for building function curves and other graphic tools for additional animation control and representation.

The reason gimble lock most often occurs when using euler angles/values is that even though no limit exists for euler values, and they can be set to practically any value (ie. +/-10,000 if necessary), most applications "normalize" euler values to be +/- 180 degrees (you'll often find "normalize" as a function used in most graphic applications), which then can cause "gimble lock" and more often "flipping" in an object's rotation, as euler values of -180 and 180 often produce the exact orientation for an object's vector since normalized euler angles produce no euler vector value < -180 and > 180 degrees. So rotating an object on a single euler axis produces the same orientation state at -180 and 180 degrees, depending on the value of the other two angles. So typically there is no way to rotate an object numerically and avoid "flipping" using only euler angles more than one 360 degree rotation - without additional algorithms. And what is often overlooked is that the order in which you apply values to an object's euler angles changes the transformational behavior dramatically. So if you are using euler angles/values in your scene and experience "gimble lock" on a bone object or "flipping" on objects or cameras, then by simply changing the order of rotation - which is the order in which the euler values are applied - can often correct these undesired behaviors

There is certainly allot more to euler and quaternion math, but I hope this provides a basic understanding of behaviors and when and how to use Euler values on a fundamental level. And I agree completely with Wingnut, that I have almost always found it faster to work with animating objects using quaternion values.

 

DB

Link to comment
Share on other sites

Hello,Below is another post I responded to concerning world spaces which should help many newbies understand how to correctly export FBX and other file formats to the .babylon file format.

Quote
Quote

@foura,

Welcome to the forum. When load your file into MotionBuilder, I see the object and orientation below:rak_basic.jpg

If you are using MotionBuilder, the rotation you see is how the file was saved. I would parent the legs and rotate in MB, Maya, or Max - or an application with a Y axis up world orientation. I use the FBX format most of the time, as it is more flexible for objects and animations than Blender (depending on the scene), as well as most all attributes. I would rotate the objects 270 degrees (not 90 degrees) and freeze or bake all transforms (or just rotations) depending on which application you're using. If I knew which application you exported from, this would help answer your question. There are often orientation differences when exporting from various applications. However, the reason you are seeing a different orientation result in babylon is that the application you exported from must have a Z axis up world orientation, where as the FBX format is a Y axis up world orientation - and this is maintained in the FBX file format. Keep in mind that Blender is also Z axis up, but I believe this is corrected for .babylon during the export process. Also your object is not rotated 90 degrees, but you'll find that there is a 270 degree rotation placed on your models. Keep this in mind, as rotating 90 degrees will look correct, but numerically, your objects might have a 360 degree rotation added if you rotate 90 degrees instead of 270 degrees in the opposite direction.

And FYI - I saw upon loading that your scene contains NURBS surfaces, which I would convert to polygons before exporting, as well as your object is incredibly small, which can also cause a vast number of problems, and would be difficult to work with in babylon.js.

DB

 

 

 

Link to comment
Share on other sites

  • 2 weeks later...

I recently responded to a topic which again asks for support of a Z axis up world orientation. Below is the following:

Quote

 

I believe I MIGHT understand why a Z axis up world coordinate system would be your chosen coordinate system. I also learned this as the way I perceived and approached all work in both CGI and algorithmic development in my earlier days as I was working with magnetic coordinate systems which as (I believe) you might be familiar with as the mathematical standards for Earth's magnetic fields and the math supporting this as Z axis up (outward from the Eath's core as the Z axis.)

However, either the above is the case, or you are working in development environments that use a standard methodlogy of the math construct which pre-dates the most widely (currently) used construct of a Y axis up world orientation which is represented in many graphic APIs and in polygonal rendering resulting from the most widely used development languages in applications today - (please note this is a very remedial description.) I had to make the decision to adopt a Y axis world orientation in most of my development and graphic work years ago - even though all my work previously had been oriented to a Z axis up world coordinate system - which is a simplified explaination applied to the work I was doing at the time - but involved magnetic and other physical property detection devices including motion capture systems and various motion sensors - as well as other devices which anyone else on this forum would most likely not relate to without an unpresidented description of practically no value these days. 

However, if you are not coming from a magnetic coordinate system which I briefly described above, then I would not understand why you would choose to continue to work with a Y axis up world coordinate system in Babylon.js. I can testify from personal experience that you will experience attempting to write functions and applications which will limit you tremedously if you don't either create extensions to handle the conversion to a magnetic construct ( a Z axis up coordinate system), or to adopt Y axis up for your work in WebGL. Otherwise, you wil find yourself limited in the any development you might attempt within the framework(s) in which you are attempting to produce media within. 

However, as I'm certain you most likely know there is a solution (certainly not recommended) to what I believe is your dilemma - which is to re-write the babylon.js framework to adopt a Z axis up world coordinate system - which is for me would be a nightmare as this framework is evolving faster than any I have ever been associated. Not to mention that the knowledge base driving Babylon.js is far outside my experience level to possibly keep up any resemblanse of the features, as well as any backwards compatability. So in no way would I personally choose to take this approach, unless I had immense resourses and I was prepared for not only the adaptation of Babylon.js, but other aspects of WebGL (forget all of the different browsers and versions thereof) and all associated frameworks and extensions which support these frameworks - as I find myself more than often adapting code from many, many sources which all follow a Y axis up world cooordinate system.

I wish you the best of luck, but unless you are working with legacy frameworks as I did with military and other agencies, I would seriously consider adopting the Y axis up world coordinate system as a base coodinate system for any development within the WebGL frameworks currently available. Of course, there's always room for another development framework (as well as a collection of extensions) to support a Z axis up world orientation.

DB

 

 

Link to comment
Share on other sites

  • 1 month later...

Hello,Below is a post which I often see similar questions on the forum - especially when it comes to character animation and rigging. The specific, post is as follows;

Quote

 

@biswazr -

@gryff provided, I forgot to inform you of an essential step in using keyframe animation for characters (meshes bound to a skeleton hierarchy) and also using any motion capture animation as well. This is to always parent your root bone (joint) to a seperate object or objects depending on how you intend on animating your character(s). What @gryff recommends will work, however, I find myself severly limted in many animations if I don't have at least one parent object or bone at the base of the character (generally the origin where hopefully the feet are placed and touching the "ground" position at (0,0,0) to make contact with a ground plane at 0 in the global Y axis.                                                                                                                                  

In addition, it is invaluable to freeze all transforms of this parent null or bone to allow as much flexability for animating the character in world space. I also recommend adding additional objects (nulls or bones) for each unique transform the character might make in world space such as a seperate parent under the translation parent object for rotations which will allow a great deal more freedom to rotate your character and avoid gimble lock, as well as increased rotational flexability. And having the top parent null or bone only for world translation, this allows your character to easily move up and down inclines, on uneven terrian, and up stairs and ladders; whereas attempting to do this using only the character's local skeleton transforms in addition to a world transform on the root joint will severly limit you in the ability for our character to freely translate as well as accomplish "flying" and/or jumping high in world space. And please always try and freeze ALL skeleton transforms prior to attaching any animation (for every bone in the skeleton hierarchy before animating a single key) especially motion capture animations, as this will always provide the greatest range of motion for any character skeleton.    

 

                                                                                                                                                                                                                                                 

If you wish to read the entire topic, then the link to the topic is as follows:

Cheers,

DB

Link to comment
Share on other sites

  • 1 year later...

@dbawel  Great thread, here are... pseudo-random question. : )

So, lots of questions but... the current journey is to understand: transforming points between spaces. 

HOW TO BEST TRANSFORM SINGLE-POINT from WORLDSPACE to LOCALSPACE... and back again?

From a recent SUCCESS of a translation from WORLD to LOCAL:

        /*TRANSFORM WORLD COORDINATES INTO LOCAL*/
        var invertParentWorldMatrix = tgtPlane.getWorldMatrix().clone();
        invertParentWorldMatrix.invert();
        var local_position = BABYLON.Vector3.TransformCoordinates(pickPoint, invertParentWorldMatrix);
         local_position.y=3; //local adjustment.
         pickMesh.position.copyFrom(local_position);

invertParentWorldMatrix... does what now? : )

Oh wait, that is not my 1 question, (niether -> gimble lock - precise moves to break gimble lock? [anyone?] )

Refocus falcon: Here is the question...

How best to TRANSFORM LOCAL COORDINATES from LOCALSPACE to WORLDSPACE?

Looking... and found it. 

mesh.computeWorldMatrix();
var matrix = mesh.getWorldMatrix(true);
var local_position = new BABYLON.Vector3(0,1,0);
var global_position = BABYLON.Vector3.TransformCoordinates(local_position, matrix);

Ok, So what is going on with the transforming, computing and inverting of matrices?

: )

 

Link to comment
Share on other sites

  • 3 weeks later...

@aFalcon-

Sorry, I've been absent for a while. I see you found the function call and best method. Once you're at this point in understanding world matrices' and the difference between local, global, Euler, and Quaternion... It's a simple step to applying vectors to local and world transforms without even thinking about it. If you want to really wrap your head around this to become second nature, I recommend creating a very simple scene and a simple mesh representing a spaceship - and generate a path for the ship to follow. But make certain that you maintain the tangent on the curve for the ship to maintain direction, as well as using the normals and binormals to prevent gimble lock and maintain correct orientation. This simple exercise will teach anyone all they need to know about path animation, euler angles, normals and binormals of a curve, etc. Once this is fully understood, it will become second nature to the point that you will never have any questions as to local and global vectors as well as remaining within the constraints of Euler angles.

Try experimenting around with the order of tangent, normal, and binormal as well - and see what results occur. Once fully understood, all your questions will be answered. Here is a playground scene recently updated by @Deltakosh using group animations - which when they work are incredibly efficient.

https://www.babylonjs-playground.com/#92EYG#24

Note that group animations didn't work using Electron - which is a standalone version of Chromium. But perhaps this bug is fixed now.

Cheers,

DB

Edit - by the way, make sure you create a box as a parent of the mesh and attach the box to the path and animate along the path. This will then allow you to animate the ship's orintation in addition to the path to add additional banking for the ship without any worries of gimble lock.

Link to comment
Share on other sites

Woo-hoo... Yep applying world/local transform no big deal! : )

And about 75% on the space ship challenge...(still need to understand tangent, normal binormals) Guessing there might be a cross product in there somewhere..

Did some updates on the "car following a path" example.Using lookAt as orientation trick...

Also have info from electron app near completion. Fascinating things with animation...interpolation with a config object:. anim({from, to, duration}).done()

Update: wow that is an awesome example. Thanks! 

(ed) CatmullRomSpline yee-haw. Will learn groups (and test in electron app).

Great to see you back @dbawel : )

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...