Still scratching my head in regards to spaces

Started by
12 comments, last by Dahkex 13 years, 7 months ago
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?




Advertisement
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.
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?
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.
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?

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Btw in the example given, what's the point of multiplying by the identity matrix?
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?
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 object's[\b] local z-axis correct?

[Edited by - Dahkex on August 29, 2010 6:52:16 AM]
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.
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.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

This topic is closed to new replies.

Advertisement