• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Spa8nky

How are the coordinate axes drawn in this video?

14 posts in this topic

In 3DS Max there is a coordinate cross that allows you to see the current orientation of the camera. See the bottom left hand corner of [url="http://screencast.com/t/41fsAhBT"]this[/url] video.

How are those axes drawn to the screen so they stay in the same place and still give a sense of depth? Is it some kind of orthographic projection?
0

Share this post


Link to post
Share on other sites
Draw three lines in model space as the axis you would expect.

Line 0: <1,0,0>, <0,0,0>
Line 1: <0,1,0>, <0,0,0>
Line 2: <0,0,1>, <0,0,0>

Scale them to the appropriate size. Rotate them based on the camera rotation. Position them in front of the camera, but do not transform them from world to view space. Instead skip the world transform and assume they are in view space already. Also, turn off depth writes so it overlaps anything else that renders (make it essentially part of the UI).

You're are essentially rendering UI, but instead of using an orthographic projection you are using a perspective projection.
1

Share this post


Link to post
Share on other sites
I've been trying to implement this based on your instructions but it's not working out as intended.I have defined my 3 lines that create the coordinates axes along with a quadrangle to label each axis:

[code]
// X
vertices[0] = new VertexPositionColor(Vector3.Zero, Color.Red);
vertices[1] = new VertexPositionColor(Vector3.UnitX, Color.Red);

quadrangles[0] = new Quadrangle(vertices[1].Position, 0.25f, 0.25f, GlobalSettings.FONT_INDEXSTART + 33);

// Y
vertices[2] = new VertexPositionColor(Vector3.Zero, Color.Green);
vertices[3] = new VertexPositionColor(Vector3.UnitY, Color.Green);

quadrangles[1] = new Quadrangle(vertices[3].Position, 0.25f, 0.25f, GlobalSettings.FONT_INDEXSTART + 34);

// Z
vertices[4] = new VertexPositionColor(Vector3.Zero, Color.Blue);
vertices[5] = new VertexPositionColor(-Vector3.UnitZ, Color.Blue);

quadrangles[2] = new Quadrangle(vertices[5].Position, 0.25f, 0.25f, GlobalSettings.FONT_INDEXSTART + 35);
[/code]

For the shader I am just passing through the vertex positions and not transforming them in any way:

[code]
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;

output.Position = input.Position;
output.Colour = input.Colour;

return output;
}
[/code]

The transformation is done in the Draw method instead. Here is what I am using to draw the lines:

[code]
VertexPositionColor[] v = new VertexPositionColor[6];

// Set the translation based on the current camera's position
Vector3 translation = game.ActiveCamera.Position + game.ActiveCamera.Forward;

Matrix transform = Matrix.CreateScale(0.25f);
//transform.Right = game.ActiveCamera.Right;
//transform.Up = game.ActiveCamera.Up;
//transform.Forward = game.ActiveCamera.Forward;
transform.M41 = translation.X;
transform.M42 = translation.Y;
transform.M43 = translation.Z;

//transform *= game.ActiveCamera.ViewMatrix;
//transform *= game.ActiveCamera.ProjectionMatrix;
//transform *= game.ActiveCamera.ViewProjectionMatrix;

// Transform all the vertices
for (int i = 0; i < 6; ++i)
{
v[i].Color = vertices[i].Color;
v[i].Position = Vector3.Transform(vertices[i].Position, transform);
}

Effect effect = game.Effects["PreTransformed"];

// Disable the z buffer so that the axes are drawn on top of all other objects
game.GraphicsDevice.DepthStencilState = DepthStencilState.None;

effect.CurrentTechnique.Passes[0].Apply();

game.GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
PrimitiveType.LineList,
v,
0,
6,
indices,
0,
3
);
[/code]

[quote]Scale them to the appropriate size[/quote]

Done using Matrix.CreateScale()

[quote]Rotate them based on the camera rotation [/quote]

This fixes the axes based on the current camera rotation and does not draw the lines down the cardinal axes as intended. [quote]Position them in front of the camera, but do not transform them from world to view space[/quote]

The translation vector puts them in front of the camera but they will not draw to the screen and be visible unless I transform them by the camera's ViewProjection matrix:

[code]
transform *= game.ActiveCamera.ProjectionMatrix;
[/code]

[quote]Also, turn off depth writes so it overlaps anything else that renders[/quote]

Depth write has been turned off using:

[code]
game.GraphicsDevice.DepthStencilState = DepthStencilState.None;
[/code]

[quote]You're are essentially rendering UI, but instead of using an orthographic projection you are using a perspective projection.[/quote]

I have tried transforming the vertices by just the camera's projection matrix but they will not draw to the screen in the correct position unless I move the camera to the origin.Can you please explain why this is the case as I thought I had followed your instructions precisely?
0

Share this post


Link to post
Share on other sites
I'm now using the followings transforms:

{ Axes }

[code]

// Set the translation based on the current camera's position and an x, y, z offset
float xOffset = 0.4f;
float yOffset = 0.2f;
float zOffset = 1f;

Vector3 translation = camera.Position;
translation += camera.Right * xOffset;
translation += camera.Up * yOffset;
translation += camera.Forward * zOffset;

Matrix transform = new Matrix();
transform.M11 = 0.125f;
transform.M22 = 0.125f;
transform.M33 = 0.125f;
transform.M41 = translation.X;
transform.M42 = translation.Y;
transform.M43 = translation.Z;
transform.M44 = 1f;
[/code]

{ Axis Labels }

[code]

// Transforming by camera rotation will make the fonts always face the camera
transform.Right = game.ActiveCamera.Right * 0.125f;
transform.Up = game.ActiveCamera.Up * 0.125f;
transform.Forward = game.ActiveCamera.Forward * 0.125f;
[/code]

Which produces a final result shown in [url="http://screencast.com/t/Kzi43hzsN"]this[/url] video.

The white quadrangles always face the camera but they have no depth and do not follow the end points of the axes.

Why is this occurring?
0

Share this post


Link to post
Share on other sites
Well, AFAIK the little coordinate system is just an ORTHOGONAL projection there, with the appropriate viewport settings (little square at the bottom-left). And only the rotation is applied to the axes.

I took a closer look at 3DS MAX, I'm positive that it uses orthogonal projection and not perspective. You can see that the axes are somewhat off and not parallel with 3D axis oriented lines in the view.


You really have to learn (you in general) that you can set whatever projection/modelview/viewport whenever you like! Just reset then set everything after drawing the scene. Then reset again to draw the HUD if you have one. Don't be possessed by the idea that if you have set up a projection, you have to stick with it through all the lifespan of the application! This really should be made a sticky. We have this king of question every day.

BTW I implemented the same thing in my paper modeller, so I know what I'm talking about :P
0

Share this post


Link to post
Share on other sites
[quote name='szecs' timestamp='1304685541' post='4807332']
BTW I implemented the same thing in my paper modeller, so I know what I'm talking about :P
[/quote]


I looked at your paper modeler and those axes are ideal. Would you be willing to share that area of code with me/others on the board? If not could you outline that area of the code in pseudo code perhaps?

I've tried an orthogonal projection/camera but it remains 2D with no perspective, and no sense of depth, so I'm struggling a little.
0

Share this post


Link to post
Share on other sites
Well, it's not really educational. I just threw together the whole thing, so immediate mode etc, all the horrible deprecated thing you can imagine.

Hmm, or maybe not, the logic itself is quite clear and nice, only the drawing code is "deprecated".
So the logic (to be honest, that should be pretty obvious):

[list=1][*]set viewport to the bottom left corner[*]disable depth buffer[*]reset projection matrix (load identity)[*]set an orthogonal projection: a cube with the center at 0,0,0[*]get the camera/modelview matrix[*]set it's last column (the translate part) to 0,0,0,1[*]load that as the modelview matrix[*]draw axes:1,0,0; 0,1,0; 0,0,1[*]draw texts[/list]
code
[code]void RenderCoordinateSystem()
{
int old_viewport[4];

glDisable(GL_DEPTH_TEST);

glGetIntegerv(GL_VIEWPORT,old_viewport);

glViewport(0,0,90,90);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

glOrtho(-45,45,-45,45,-45,45);

glMatrixMode(GL_MODELVIEW);

TransformWithCameraRotation();

glBegin(GL_LINES);

glColor4f(1,0,0,1);
glVertex3f(0,0,0);
glVertex3f(38,0,0);

glColor4f(0,1,0,1);
glVertex3f(0,0,0);
glVertex3f(0,38,0);

glColor4f(0,0,1,1);
glVertex3f(0,0,0);
glVertex3f(0,0,38);

glEnd();

glColor4f(1,1,1,1);
glPrint(40,0,0,"x");
glPrint(0,40,0,"y");
glPrint(0,0,40,"z");

glViewport(old_viewport[0],old_viewport[1],old_viewport[2],old_viewport[3]);

glEnable(GL_DEPTH_TEST);
}
void TransformWithCameraRotation()
{
double mvm[16];

mvm[ 0] = MainCamera.mv_matrix[ 0];
mvm[ 1] = MainCamera.mv_matrix[ 1];
mvm[ 2] = MainCamera.mv_matrix[ 2];
mvm[ 3] = MainCamera.mv_matrix[ 3];

mvm[ 4] = MainCamera.mv_matrix[ 4];
mvm[ 5] = MainCamera.mv_matrix[ 5];
mvm[ 6] = MainCamera.mv_matrix[ 6];
mvm[ 7] = MainCamera.mv_matrix[ 7];

mvm[ 8] = MainCamera.mv_matrix[ 8];
mvm[ 9] = MainCamera.mv_matrix[ 9];
mvm[10] = MainCamera.mv_matrix[10];
mvm[11] = MainCamera.mv_matrix[11];

mvm[12] = 0;
mvm[13] = 0;
mvm[14] = 0;
mvm[15] = 1;

glLoadMatrixd(mvm);
}

[/code]
1

Share this post


Link to post
Share on other sites
I've followed your instructions but I can't get the text/quadrangles that label each axis to face the camera. The problem is shown in [url="http://screencast.com/t/w218oVmKTb"]this[/url] video.

I'm drawing the axes as instructed:

[code]

// Set viewport to the bottom left corner
Viewport viewport = game.GraphicsDevice.Viewport;

// Disable the z buffer so that the axes are drawn on top of all other objects
game.GraphicsDevice.DepthStencilState = DepthStencilState.None;

Matrix orthogonal = Matrix.CreateOrthographic(
viewport.Width,
viewport.Height,
-viewport.Width,
viewport.Width
);

Camera camera = game.ActiveCamera;


Effect effect = game.Effects["PreTransformed"];

// Get the camera/modelview matrix
Matrix viewMatrix = camera.ViewMatrix;

// Set it's last column (the translate part) to 0,0,0,1
viewMatrix.M41 = 0f;
viewMatrix.M42 = 0f;
viewMatrix.M43 = 0f;
viewMatrix.M44 = 1f;

effect.Parameters["ViewProjection"].SetValue(viewMatrix * orthogonal);

effect.CurrentTechnique.Passes[0].Apply();

game.GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
PrimitiveType.LineList,
vertices,
0,
6,
indices,
0,
3
);
[/code]


If I use 'viewMatrix * orthogonal' for drawing the labels then they never rotate to face the camera (like a spherical billboard). How do I draw the labels so they rotate correctly?
0

Share this post


Link to post
Share on other sites
Um, I used the built in text Rendering, that's always in screen space.

Anyway: Project the coordinates of the labels (I assume you know what I mean by that), reset the modelview matrix, and render the labels just like you would render a HUD. I can't be more specific, play around and experiment!
0

Share this post


Link to post
Share on other sites
I've been playing around and experimenting all weekend but with little success.

[quote]
[color=#1C2837][size=2]Project the coordinates of the labels (I assume you know what I mean by that)[/size][/color]
[/quote]

This is where I think I am going wrong:

- If I draw the labels just using an orthographic projection they do not move but will always face the camera (like a GUI) when the camera rotates.
- If I transform them by the camera's view matrix with 0,0,0 for the translation they will be in the correct location but they will not face the camera.

Can you please explain what you mean by "project the coordinates of the labels"?
0

Share this post


Link to post
Share on other sites
look into "world coordinates to screen coordinates"

To be honest, you should learn how to solve these problems. I could do it, no one showed me. All the pieces of the puzzle (or terms to look into) are here in the thread. You just need to put together these few pieces.
0

Share this post


Link to post
Share on other sites
After a day away from this, I came back to it today and solved the problem.

[quote]look into "world coordinates to screen coordinates"[/quote]

Can you please explain why I should use this method? I've seen it used as a Unity add on [url="http://www.unifycommunity.com/wiki/index.php?title=ObjectLabel"]here[/url] but I have solved it by doing the following:


[code]

// Always use the active camera to get the label to face the current camera
Camera camera = game.ActiveCamera;
Viewport viewport = game.GraphicsDevice.Viewport;

// Scale
//Matrix worldMatrix = Matrix.CreateScale(0.5f);
Matrix worldMatrix = Matrix.CreateScale(50f);

// Rotate
worldMatrix *= camera.ViewMatrix;

// Set its last column (the translation part) to (0, 0, 0, 1)
worldMatrix.M41 = 0f;
worldMatrix.M42 = 0f;
worldMatrix.M43 = 0f;
worldMatrix.M44 = 1f;

// The transpose of view matrix to make the vertices face the current camera
Matrix.Transpose(ref worldMatrix, out worldMatrix);

// Translate
worldMatrix.M41 = ObjectPosition.X;
worldMatrix.M42 = ObjectPosition.Y;
worldMatrix.M43 = ObjectPosition.Z;

vertices[0] = Vector3.Transform(corners[0], worldMatrix);
vertices[1] = Vector3.Transform(corners[1], worldMatrix);
vertices[2] = Vector3.Transform(corners[2], worldMatrix);
vertices[3] = Vector3.Transform(corners[3], worldMatrix);


Matrix orthogonal = Matrix.CreateOrthographic(
viewport.Width,
viewport.Height,
-viewport.Width,
viewport.Width
);

Matrix viewMatrix = camera.ViewMatrix;

// Set its last column (the translation part) to (0, 0, 0, 1)
viewMatrix.M41 = 0f;
viewMatrix.M42 = 0f;
viewMatrix.M43 = 0f;
viewMatrix.M44 = 1f;

game.WireShapeDrawer.Begin(viewMatrix, orthogonal);

game.WireShapeDrawer.DrawLine(vertices[0], vertices[1], Color.White);
game.WireShapeDrawer.DrawLine(vertices[1], vertices[3], Color.White);
game.WireShapeDrawer.DrawLine(vertices[3], vertices[2], Color.White);
game.WireShapeDrawer.DrawLine(vertices[2], vertices[0], Color.White);

game.WireShapeDrawer.End();
[/code]

The video of the results are shown [url="http://screencast.com/t/3NcxNKvoiE"]here[/url]

I hope that someone can enlighten me why conversion to screen space coordinates are often used instead.
0

Share this post


Link to post
Share on other sites
There are more ways to solve a problem, that's an important lesson. You can use billboarding, or conversion of coordinate systems, or maybe other stuff too.
0

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
Sign in to follow this  
Followers 0