# Rotate around a 3d Object (Software Renderer)

I have a simple 3d software renderer (SDL / C++) which can load a 3ds Model and render it (shaded) and rotate it around X Y Z - Axis. Now I would like to rotate / move around the object, meaning, the object itself stands still, and everything in the scene is displayed from the angle of the view. Is that what a camera in 3d engines does, and how would I implement something like this ?

(No OpenGL / DirectX is used, just plain software)

EDIT: What the hell, I completely misinterpreted the question! Saved for posterity (I thought the question was "how do I get an object to spin around another object):

What you need to learn about is something called a scene graph. The basic principle is very simple:

Suppose you have a 2D field. You have an X-axis and a Y-axis. Define a cube with four coordinates:

Now we rotate it 45 degrees. The blue box is the result:

Now we translate it to the left and up:

Let's do this in reverse. First we translate and then we rotate:

The result is completely different!

What you want to do in a scene graph is multiply a node's matrix with its parent. You want to translate the coordinates of a node from local space (hand) to world space (hand -> arm -> body -> world).

Effectively, you want to have a top node (your root node) with a bunch of children. When you want to render, you start at the top node and tell its children to render with the top matrix:

void SceneNode::Render(Mat4x4* a_Matrix)
{
Mat4x4 final = a_Matrix * m_Matrix;

if (m_Model)
{
m_Model->Render(final);
}

if (m_Children.size() > 0)
{
for (std::vector<SceneNode*>::iterator i = m_Children.begin(); i != m_Children.end(); ++i)
{
(*i)->Render(&final);
}
}
}


EDIT: After you've done this, you now have both the object and the camera in world space. The main thing about rasterization is that you have to transform the world coordinates into screen coordinates somehow.

The easiest way to do this is to ignore z:

screen.x = world.x;
screen.y = world.y;


If you have a rotating teapot, you will see a rotating teapot on the screen. However this isn't a very good implementation. If you want to do it correctly, you will have to subtract from the world position the camera position (effectively turning world space positions into camera space positions) and use the camera matrix to transform the coordinates.

Here's how I project a triangle in my own software rasterizer:

Vec3 camera_space;

for (int i = 0; i < 3; i++)
{
Vec3 translated = a_Triangle->v[i] - m_Position;

camera_space.x =
(translated.x * m_Rotation[Mat4x4::X1]) +
(translated.y * m_Rotation[Mat4x4::Y1]) +
(translated.z * m_Rotation[Mat4x4::Z1]);

camera_space.y =
(translated.x * m_Rotation[Mat4x4::X2]) +
(translated.y * m_Rotation[Mat4x4::Y2]) +
(translated.z * m_Rotation[Mat4x4::Z2]);

camera_space.z =
(translated.x * m_Rotation[Mat4x4::X3]) +
(translated.y * m_Rotation[Mat4x4::Y3]) +
(translated.z * m_Rotation[Mat4x4::Z3]);

//#define FOV_ANGLE                 60.f
//static const float FOV_TAN      = tanf(Math::RadToDeg(FOV_ANGLE) / 2);
const float distance = m_TargetHeightHalf / (FOV_TAN * camera_space.z);

a_Triangle->p[i].x = m_TargetWidthHalf  + (camera_space.x *  distance);
a_Triangle->p[i].y = m_TargetHeightHalf + (camera_space.y * -distance);
a_Triangle->depth[i] = -distance;
}

• I see. very interesting. I have read about world and screen coordinates in the past, but forgotten completely about that. I will try you suggestions. Thank you very much. BR Commented Jul 23, 2010 at 9:49

You could simply add the negative camera matrix to all your transforms, but I think it depends on how you implemented your renderer.

• Hmmm. I have to look up what the inverse matrix does. Besides that, the renderer isn't so komplex at the moment, so this could be done/changed/added easily. Thanks for the hint. I will try it. BR Commented Jul 23, 2010 at 13:33
• i think i made a mistake with inverse matrix, i think it should be called negative matrix. damn math vocabulary.. Commented Jul 23, 2010 at 13:52