Jump to content

  • Log In with Google      Sign In   
  • Create Account

Multiple Coordinate Systems

  • You cannot reply to this topic
5 replies to this topic

#1 fs1   Members   -  Reputation: 301


Posted 23 August 2014 - 05:15 PM

I have been examing some games and sometimes it seems they have multiple coordinate systems. For example you have several sprites that have different world scales, and one group of sprites are "nested" or child of another goup of sprites - they have world coordinates relative to their parent's world. Is this possible? If so, how do you connect world spaces when you want to render the scene?


Edited by fs1, 23 August 2014 - 05:29 PM.


#2 KulSeran   Members   -  Reputation: 2488


Posted 23 August 2014 - 06:56 PM

Of course it's possible.


Chances are you don't want to do things like create every model with every possible weapon attached.  You want to create a base model, several base attack animations, and all the weapons seperate from the base models.  So you want to attach things together.


In 2d or 3d, the basics of this are that a matrix multiplication will take you from one coordinate space to another.  So you can chain multiple matrix multiplications together to create a hierarchy that takes you from the world space all the way to your object space (or the other way around).

weaponMatrix = IdentityMatrix * MatrixOfPlatformPlayerIsStandingOn * MatrixOfPlayerRelativeToPlatform * MatrixOfGunRelativeToPlayer;

But you probably don't want to hard-code this, so you can build a tree of parenting.  Each object holds a reference to its parent.  The gun is parented to the player at some offset from the player's hand.  The hand is at some offset based on the player's animation.  The player is parented to either the world, or a moving platform, or a vehicle, etc.  The platforms/vehicles are parented to the world.  To resolve that, you just recursively walk

Matrix myMatrix() {
  if (hasParent) {
     return parent->myMatrix() * relativeMatrix;
  } else {
     return absoluteMatrix;

You can make things more flexiable (read complicated) by also allowing the parents to hold more than one matrix (read animated bones) that you would retrieve instead of the base matrix of the parent.

#3 fs1   Members   -  Reputation: 301


Posted 23 August 2014 - 08:15 PM

Ok, thanks. Interesting insights.

Now a quick question, once you draw both groups, with 2 different world matrix, how do you tell the engine that they are related and to calculate the composed 'world matrix' ?

I inspected some shaders and didn't find these composition (they have only their world matrix, but not their parent one). Is it done on the c++ side? Any hints?


#4 wodinoneeye   Members   -  Reputation: 757


Posted 23 August 2014 - 08:26 PM

At some point the coordinates have to be converted to a common system for operations like rendering relative to one clients point of view or for projectile path resolution....   AI might be handled at several levels also - like an 'entity' object which has a swarm of sub-objects where the entity does alot of the AI processing and then the sub-objects behave at a lower (simpler/less CPU intensive) level.


Complications happen when there are multiple borders between the various local coordinate systems and other objects see/interact across several borders (And other objects see a different subset).  Some systems just flatten everything into one coordinate system for the part of the world actively operating and add or remove sections on-the-fly  (continuous world) doing the conversions only at the add/remove times 


Usually vehicles with their own coordinate system and changing orientations/etc interacting with the larger world map have these issues  (notice many games DONT have such vehicles and its largely because of the complications)



--------------------------------------------Ratings are Opinion, not Fact

#5 KulSeran   Members   -  Reputation: 2488


Posted 23 August 2014 - 08:57 PM

I inspected some shaders and didn't find these composition (they have only their world matrix, but not their parent one). Is it done on the c++ side? Any hints?

By the time you get to the shader, you should have already composed the "world matrix" of the object.


Lets say I'm drawing a player.  The player doesn't have a parent. His current matrix is precisely his "world matrix".

He has a hand, driven by an animation.  The animation happens in "player space".

He has a sword in his hand.  The sword is in "hand space".


To draw the objects, you decide how you're going to walk down the list of things to draw, and generate a set of matricies.

playerWorldMat = player.matrix;
handWorldMat = player.matrix * player.animation.hand.matrix;
swordWorldMat = handWorldMat * sword.matrix;

By multiplying the player and hand, you move the hand from player space to world space.

By multiplying the sword by the hand, you move the sword from hand space to world space.

Everything is now in the same space, and if you were to draw each item, they'd all show up where you'd expect them to.


Lets do an example in 2d.

playerWorldMat =   [ 0, 1, 5,
                     1, 0, 8,
                     0, 0, 0 ];  // he's at the position <5, 8>, and facing to the east
handAnimationMat = [ 1, 0, 1,
                     0, 1, 0,
                     0, 0, 0];  // His hand is pointing north, and positioned directly infront of him
swordMat =         [ 1, 0, 0,
                     0, 1, 0,
                     0, 0, 0];  // His sword is pointing north, and positioned directly ontop of his hand

handWorldMat = playerWorldMat * handAnimationMat;
handWorldMat =     [ 0, 1, 6,
                     1, 0, 8,
                     0, 0, 0];  // Player was facing east, thus his hand is actually also facing east. and is one unit east of him.
swordWorldMat = handWorldMat * swordMat;
// thus
swordWorldMat =    [ 0, 1, 6,
                     1, 0, 8,
                     0, 0, 0]; // Hand was facing east, thus the sword is actually also facing east, and is directly ontop of the hand.

So the engine needs to keep track of SOME data structure that lets you know "sword is on hand", "hand is on person", "person is in world" so that you can generate the world matrix for each object after every frame.  Like I'd said, this is usually some kind of tree structure that devolves to

struct {
   Object *parent;
   list<Object *> children;

And you either walk up that attachment tree from the bottom (children look for their parent), or down from the top (parents dictate information to their children).

Edited by KulSeran, 23 August 2014 - 09:00 PM.

#6 fs1   Members   -  Reputation: 301


Posted 25 August 2014 - 01:41 PM

KurlSeran, thank you so much for your reply and example.


Very helpful. Thanks so much all !