Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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)

share|improve this question
add comment

2 Answers 2

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:

alt text

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

alt text

Now we translate it to the left and up:

alt text

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

alt text

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);
        }
    }
}

I hope this answers your question. :)

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;
}
share|improve this answer
    
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 –  paines Jul 23 '10 at 9:49
add comment

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

share|improve this answer
    
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 –  paines Jul 23 '10 at 13:33
    
i think i made a mistake with inverse matrix, i think it should be called negative matrix. damn math vocabulary.. –  thbusch Jul 23 '10 at 13:52
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.