Sign in to follow this  

Still scratching my head in regards to spaces

This topic is 2664 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I know this is a simple issue but I need someone to explain this to me as barebones as possible. I'm using XNA btw and my examples will just be simple 2D.

1. So I draw a sprite in XNA at some position. This sprite I assume has its own local space right? If so, how can I tell the difference between doing something to that sprite in my local space versus doing it in world space? Is this sprite's local space still some x/y axis in the middle of the screen? Is the world's space origin 0,0,0 to the upper-left like the screen space? For example, the sprite draw method under the hood does world transformations as I've read so I am kind of confused in this regard.

2. This is a leadup to the major source of my confusion. In Riemer's tutorial on this page:

http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series2D/Coll_Detection_Matrices.php

He explains how this:

Matrix carriageMat = Matrix.CreateTranslation(0, -carriage.Height, 0) * Matrix.CreateScale(playerScaling) * Matrix.CreateTranslation(xPos, yPos, 0) * Matrix.Identity;

is equivalent to a draw method where you translate, scale and set the origin. So multiplying by a translation matrix for principle reasons brings you into the world space. Alright, that's fine. However, at the last matrix applied, he does a final translation along the height of the carriage. The thing which messes me up is that he says we are translating along the object's y-axis. How the heck did we go from translating in the world space to now translating up the local axis of the object?




Share this post


Link to post
Share on other sites
Convention?
Every matrix other than Matrix.Identity is in some other space. You can however divide up the matrix chain into parts. Some common terms for these divisions are: "projection", "view" "model", and "bone" space.
The idea is, that where you draw the line helps you determine where something is. Your projection mat will contain only the information to do the perspective/orthographic projection. The view mat will contain the transform to move the camera. The model will place your object in relation to the origin, and rotate and scale it. Your bone will place something like a hand in relation to your body.

In your case, you have your base world matrix (Matrix.Identity) and perform a model translation and scale (xPos,yPos, playerScaling) then find an offset from your model that is -carriage.Height down. You could just as easily say you have a model at (xPos,yPos) and you are finding an offset at (-carriage.Height * playerScaling) down.

Since the graphics hardware doesn't really care, you just end up with all the matricies for any one draw call multiplied together. But in your code, you'll want to break things up to be clear about it. The link you posted could be a lot more clear on the whole description to give you a better idea where he is coming from and going to.

Share this post


Link to post
Share on other sites
Quote:
Original post by KulSeran
Convention?


Convention meaning why the author stated the end matrix translation goes back on the object axis instead of the world axis?

Quote:
Original post by KulSeran
In your case, you have your base world matrix (Matrix.Identity) and perform a model translation and scale (xPos,yPos, playerScaling) then find an offset from your model that is -carriage.Height down. You could just as easily say you have a model at (xPos,yPos) and you are finding an offset at (-carriage.Height * playerScaling) down.



Alright, I guess I was just worried that I was missing something about matrix multiplication, that this chain somehow brings you back to the local object's Y-axis as he mentioned. So then this begs the ultimate question, what operations can I do where I only use the local axis of my 2D object?

For example, when I want to go to a new vector position, I pass this as a parameter in the Draw method and then the draw uses a world matrix to translate to that new position. However, what if I wanted to just go up along my own local Y-axis for that art object? That's the key piece I'm either not getting or misinterpreting.

Also, in the world matrix that I am seeing, is the origin placed at some arbitrary point in the middle of the screen or also on the upper-left like the screen coordinate?

Share this post


Link to post
Share on other sites
Quote:

Also, in the world matrix that I am seeing, is the origin placed at some arbitrary point in the middle of the screen or also on the upper-left like the screen coordinate?

The world origin is (0,0,0). Where that is on screen depends on your camera, projection, and viewport. In an orthographic projection, with a properly setup viewport you could make (0,0) the center, bottom right, top left, etc. With a perspective projection, you're better off just thinking about it like the fly-mode cameras in your favorite online shooters while you wait to respawn.

It would seem from a quick glance over that webpage, that he already has an orthographic-2D projection setup, and that the viewport is setup to place (0,0) in the top left of the screen.


Quote:

Alright, I guess I was just worried that I was missing something about matrix multiplication, that this chain somehow brings you back to the local object's Y-axis as he mentioned. So then this begs the ultimate question, what operations can I do where I only use the local axis of my 2D object?

You can do any operation. Some like rotation however can be tricky to get right due to issues of gimble lock and the like if you use the wrong notation.

Quote:

For example, when I want to go to a new vector position, I pass this as a parameter in the Draw method and then the draw uses a world matrix to translate to that new position. However, what if I wanted to just go up along my own local Y-axis for that art object? That's the key piece I'm either not getting or misinterpreting.

Then you just take your Object's matrix, and apply a transform to it to get a new matrix.
To put a gun up and behind the carriage, IN carriage space, you'd do:
Matrix gunMat = Matrix.CreateTranslation( 0, 1.0, -1.0 ) * carriageMat;

To place a flame on your rocket you'd do
Matrix flameMatix = Matrix.CreateTranslation( 0, 0, -1.0 ) * rocketMat;

etc.

And, just to give you a better feel for it, lets make a "camera" to zoom out of the image.

Matrix cameraMat = Matrix.CreateScale( zoomFactor );
Matrix displayMatrix = rocketMat * cameraMat;
// pass displayMatrix into the draw call.



Sorry if this doesn't quite help you make the leap to understanding. Hopefully some other helpful poster will come along in the morning.

Share this post


Link to post
Share on other sites
Quote:
Also, in the world matrix that I am seeing, is the origin placed at some arbitrary point in the middle of the screen or also on the upper-left like the screen coordinate?

Actually, those locations aren't arbitrary at all. They're determined by the view and projection matrices that you set for the rendering engine.

Consider a 3D world. That world has a world origin. There are objects in that world. Each of those objects "begins life" at the origin of the world. When you create a 3D sphere for instance, it (normally) starts out with a center located at the origin of the world. The radius of that sphere determines vertices on its surface at a variety of x, y and z coordinates.

You can change the orientation of that sphere (combinations of scale, rotation and translation) through the use of matrices that describe the object's "local" space. That is, if I'm at the origin of the world, facing north, and I want to stand at the local origin of an object, facing that object's north direction, I can multiply my matrix by the object's matrix to orientation myself in the object's space.

Now consider drawing a 3D world with several objects in it to a 2D screen.

First choice: Where do I want to view the world from? What location, and facing what direction? That's the view matrix. You may call it "camera" space. It will translate and rotate objects in the world into the view space. If the view point is high above the origin (say, along the Y axis) and facing north, an object that's located to the west of the world origin will be off to the left in view space.

Second choice: Given the view I've chosen, do I want to see it in perspective, or orthogonally? That's the projection matrix. It describes a volume of space relative to view space. Objects in view space within that volume will be rendered. Objects outside that volume will not be rendered.

The next part of the process is to render the objects in projection space to the screen. That's done by yet another manipulation that's based on how big the backbuffer is in pixels. The backbuffer is then "blt'd" to the screen.

The end result of all these operations is to render the center of the camera's view to the center of the screen.

Does that help?

Share this post


Link to post
Share on other sites
[quote]Original post by Buckeye
Quote:


You can change the orientation of that sphere (combinations of scale, rotation and translation) through the use of matrices that describe the object's "local" space. That is, if I'm at the origin of the world, facing north, and I want to stand at the local origin of an object, facing that object's north direction, I can multiply my matrix by the object's matrix to orientation myself in the object's space.


From your post and above I completely now understand the differences those spaces go through in relation to choosing where to view and my axis.

One small thing though and I should have an almost understanding. Yours and the poster above mentions the object's matrix. How do I exactly represent the object space through a matrix?

In other words, I get how to bring out an object to world space like so:

newPosition = Vector2.Transform(oldposition, MatrixRotation * MatrixScale * MatrixIdentity);

but I don't get what the matrix describing my object space exactly is. Does this also mean that I can create some matrix in the world, let's say:

Matrix rotMatrix = Matrix.CreateRotationZ(MathHelper.ToRadian(45.0f));

then do

rotMatrix * myObjectMatrix

Will I now rotate my sprite in its own object space around its own z-axis space?

Share this post


Link to post
Share on other sites
Quote:
Original post by KulSeran
Quote:

Also, in the world matrix that I am seeing, is the origin placed at some arbitrary point in the middle of the screen or also on the upper-left like the screen coordinate?

The world origin is (0,0,0). Where that is on screen depends on your camera, projection, and viewport. In an orthographic projection, with a properly setup viewport you could make (0,0) the center, bottom right, top left, etc. With a perspective projection, you're better off just thinking about it like the fly-mode cameras in your favorite online shooters while you wait to respawn.

It would seem from a quick glance over that webpage, that he already has an orthographic-2D projection setup, and that the viewport is setup to place (0,0) in the top left of the screen.


Quote:

Alright, I guess I was just worried that I was missing something about matrix multiplication, that this chain somehow brings you back to the local object's Y-axis as he mentioned. So then this begs the ultimate question, what operations can I do where I only use the local axis of my 2D object?

You can do any operation. Some like rotation however can be tricky to get right due to issues of gimble lock and the like if you use the wrong notation.

Quote:

For example, when I want to go to a new vector position, I pass this as a parameter in the Draw method and then the draw uses a world matrix to translate to that new position. However, what if I wanted to just go up along my own local Y-axis for that art object? That's the key piece I'm either not getting or misinterpreting.

Then you just take your Object's matrix, and apply a transform to it to get a new matrix.
To put a gun up and behind the carriage, IN carriage space, you'd do:
Matrix gunMat = Matrix.CreateTranslation( 0, 1.0, -1.0 ) * carriageMat;

To place a flame on your rocket you'd do
Matrix flameMatix = Matrix.CreateTranslation( 0, 0, -1.0 ) * rocketMat;

etc.

And, just to give you a better feel for it, lets make a "camera" to zoom out of the image.

Matrix cameraMat = Matrix.CreateScale( zoomFactor );
Matrix displayMatrix = rocketMat * cameraMat;
// pass displayMatrix into the draw call.



Sorry if this doesn't quite help you make the leap to understanding. Hopefully some other helpful poster will come along in the morning.


Like I mentioned in the previous post, very helpful into understanding that my origin can be whatever I want it to define but I need clarification as to what exactly I would use to represent my object space through a matrix...that's probably the remaining thing I'm confused about.

Aside from that, by doing what you mentioned:

Matrix.CreateTranslation( 0, 0, -1.0 ) * rocketMat;

Won't multiplying the rocketMatrix and then by CreateTranslation be a world transformation or would that only occur if I did rocketMat * Matrix.CreateTranslation(0,0,-1.0)? Aside from that, what you would be doing would be positioning the flame above the rocket one unit in the z-direction on the [b]object's[\b] local z-axis correct?

[Edited by - Dahkex on August 29, 2010 6:52:16 AM]

Share this post


Link to post
Share on other sites
By the way guys, I really do appreciate the time you put into these explanations, especially for some people who initially can't off the bat visualize these things.

Share this post


Link to post
Share on other sites
Quote:
I don't get what the matrix describing my object space exactly is.

First of all: get in the habit right now (for XNA and DirectX) of thinking for most transformations --> "SRT" - scale, then rotate, then translate. Generally speaking, changing the order of those multiplications is guaranteed to give you results you won't like.

Second: Generally speaking, always think about rotations being down with respect to the world origin. That is, if you rotate an object and then translate it, it will appear to be rotating about its own axis (like the Earth spinning in space). If you translate the object first, then rotate it, it will appear to be orbiting around the origin (like the Earth orbiting the Sun). Make sure you have a good grasp on that.

A matrix is nothing more than a structure of values used by math manipulation routines. I'm not an XNA person, so this is pseudo-code.

Assume you create a world matrix for an object:

objectMatrix = rotateY( 23 degrees ) * translate( 10, 20, 30 ); // NOTE --> rotate, then translate

When you render the object and you set objectMatrix as it's world transform, the rendering pipeline will rotate the object (locally) by 23 degrees and then translate the object to position (10,20,30) with respect to the world origin.

Remember, before you rotate or translate the object, it's local axes coincide with the world axes.

Share this post


Link to post
Share on other sites
Quote:

Matrix.CreateTranslation( 0, 0, -1.0 ) * rocketMat;

Won't multiplying the rocketMatrix and then by CreateTranslation be a world transformation or would that only occur if I did rocketMat * Matrix.CreateTranslation(0,0,-1.0)? Aside from that, what you would be doing would be positioning the flame above the rocket one unit in the z-direction on the [b]object's[\b] local z-axis correct?

Sure, it is a "world transformation" but all transformations end up in the world.
See, you have your OBJECTS matrix "rocketMat", and you wanted some point in world space that is RELATIVE to your OBJECT. So, you take the OBJECT matrix, and use it as the starting point. If you don't care about any one object, you take the ORIGIN (matrix.identity) as your starting point.

Quote:

Like I mentioned in the previous post, very helpful into understanding that my origin can be whatever I want it to define but I need clarification as to what exactly I would use to represent my object space through a matrix...that's probably the remaining thing I'm confused about.

Yeah. Your "Object space" of the rocket is rocketMat. If you took the columns (rows in directx?) of the matrix, you'd get the X,Y,Z, axis and position of the rocket. Multiplying in another translation after your object's matrix is equivelent to using those local XYZ axis to move away from the local position described in the rocketMat.

Maybe picking up some reading on linear algebra would help?

Share this post


Link to post
Share on other sites
Quote:
Original post by KulSeran
Quote:

Matrix.CreateTranslation( 0, 0, -1.0 ) * rocketMat;

Won't multiplying the rocketMatrix and then by CreateTranslation be a world transformation or would that only occur if I did rocketMat * Matrix.CreateTranslation(0,0,-1.0)? Aside from that, what you would be doing would be positioning the flame above the rocket one unit in the z-direction on the [b]object's[\b] local z-axis correct?

Sure, it is a "world transformation" but all transformations end up in the world.
See, you have your OBJECTS matrix "rocketMat", and you wanted some point in world space that is RELATIVE to your OBJECT. So, you take the OBJECT matrix, and use it as the starting point. If you don't care about any one object, you take the ORIGIN (matrix.identity) as your starting point.

Quote:

Like I mentioned in the previous post, very helpful into understanding that my origin can be whatever I want it to define but I need clarification as to what exactly I would use to represent my object space through a matrix...that's probably the remaining thing I'm confused about.

Yeah. Your "Object space" of the rocket is rocketMat. If you took the columns (rows in directx?) of the matrix, you'd get the X,Y,Z, axis and position of the rocket. Multiplying in another translation after your object's matrix is equivelent to using those local XYZ axis to move away from the local position described in the rocketMat.

Maybe picking up some reading on linear algebra would help?


I finally get it I believe.

Relating to the rotation and translation thing vs translation then rotation:

My object space is initially aligned with my world space. If I do a rotation at the beginning, both my X and Y axis will rotate around my local space's origin. It spins because I am literally shifting the axis as I rotate and thus I can achieve the spinning motion. If I then do a translation, I am now in my world space which makes sense, I am just saying "here is my object origin in relation to the world origin" which in my case is set the same as my screen space at (0,0). When I specify to rotate in this space, I am actually rotating the object itself, not the axis as I was doing in local space which is why it orbits.

In relation to to the transformations of the missile let's say above the carriage. I first can do something like this (doing this from left to right):

Rotate carriage 50 degrees around local space's origin, translate to (10,10,0)

Now, if I want some missile to be on top of the carriage rotated, I would do:

Rotate missle 50 degrees around local space origin, Translate to (1,1,0).

Now, reading from left to right, I would then multiply my world transformation for my carriage by the world transformation of my rocket and will get this rocket above.

So my order is if I wanted to do it out (from left to right):

rotMatrixCarriage(50) * tranMatrixCarriage(10,10,0) * rotMatrixRocket(50) * tranMatrixRocket(1,1,0).

or

1.Rotate my rocket 50 degrees around the local origin.
2.Put the rocket (10,10,0) in the world space
3. Rotate rocket by 50 degrees (I'm assuming this is in local space but am unsure)
4. Put the rocket above the carriage so right 1 and up 1

I would apply this sequence to my origin of my rocket and end up where I want.

One final question. After the first two transformations of the carriage, is rotMatrixRocket doing 50 around the world origin or my local object origin? I ask because after my two matrix transformations for the carriage, I am now in world space so naturally in my head I would think that something like a rotation in the world space would orbit around the world origin. If it is in the local space, why does rotation occur in the local space vs the world space?

Share this post


Link to post
Share on other sites
Quote:
rotMatrixCarriage(50) * tranMatrixCarriage(10,10,10) * rotMatrixRocket(50) * tranMatrixRocket(1,1,0).

Not quite there yet. That would rotate the rocket twice.

You're right about the carriage - rotate it 50 degs, then translate it where you want it.

If you want a rocket on top of it - rotate the rocket by 50 degs, translate it where you want it.

If you want to use the carriage's orientation, which is a good idea - since the carriage may move:
Set the carriageMatrix = rotate(50)*translate(10,10,0)

Set the rocketMatrix = carriageMatrix * translate(1,1,0)

The rocket matrix is now rotate(50)*translate(10,10,0)*translate(1,1,0)

Since consequetive translations can be "additive" the rocket is rotated 50 degress, like the carriage, and translated 11,11,0. That puts it in the same direction as the carriage, and 1 unit above it.

EDIT: You're worrying a bit too much about which "space" you're in right now. Just visualize the object starting at the origin. Now decide how much you want it to be rotated when it's at its final location. Then translate it to its final location.

EDIT2:
Quote:
is rotMatrixRocket doing 50 around the world origin or my local object origin?

When the rocket is at the origin, its local axes coincide with the world axes. However, you should think of it as rotating the axes of the rocket. After you rotate it 50 degrees (for example, about the Y axis), the rocket's local X and Z axis will now be rotated with respect to the world.

Share this post


Link to post
Share on other sites
Quote:
Original post by Buckeye
Quote:
rotMatrixCarriage(50) * tranMatrixCarriage(10,10,10) * rotMatrixRocket(50) * tranMatrixRocket(1,1,0).

Not quite there yet. That would rotate the rocket twice.

You're right about the carriage - rotate it 50 degs, then translate it where you want it.

If you want a rocket on top of it - rotate the rocket by 50 degs, translate it where you want it.

If you want to use the carriage's orientation, which is a good idea - since the carriage may move:
Set the carriageMatrix = rotate(50)*translate(10,10,0)

Set the rocketMatrix = carriageMatrix * translate(1,1,0)

The rocket matrix is now rotate(50)*translate(10,10,0)*translate(1,1,0)

Since consequetive translations can be "additive" the rocket is rotated 50 degress, like the carriage, and translated 11,11,0. That puts it in the same direction as the carriage, and 1 unit above it.

EDIT: You're worrying a bit too much about which "space" you're in right now. Just visualize the object starting at the origin. Now decide how much you want it to be rotated when it's at its final location. Then translate it to its final location.

EDIT2:
Quote:
is rotMatrixRocket doing 50 around the world origin or my local object origin?

When the rocket is at the origin, its local axes coincide with the world axes. However, you should think of it as rotating the axes of the rocket. After you rotate it 50 degrees (for example, about the Y axis), the rocket's local X and Z axis will now be rotated with respect to the world.


Awesome, played around in XNA passing in my custom transformation and luckily it worked as I expected. Thanks

[Edited by - Dahkex on August 30, 2010 12:23:57 AM]

Share this post


Link to post
Share on other sites

This topic is 2664 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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

Sign in to follow this