3d Camera Design -solved-

Started by
4 comments, last by Etherstar 18 years, 10 months ago
I am trying to build a basic camera for my current 3D project, but I am having no luck. I'm using C# as my language and Managed DirectX3D as my graphical API. Basically I can set up a camera a camera easily enough, but when I perform rotations and movements, things just get all out of whack. All I really want is for the camera to do the following: -Rotate on each of the cameras Axes -Move around while retaining orientation. After I learn how to perform these basic tasks I'll add more functionality as necessary. So if anyone could basicly point me in the direction of either math or programming resources that might help (other than what is found on this site) I'd appreciate it. I'll post my pathetic camera class code below.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace Camera
{
    class Camera
    {
        public Camera()
        {
            cameraUp = new Vector3(0, 1.0f, 0);
            cameraPointAt = new Vector3(0, 0, 1.0f);
        }

        public Camera(Vector3 pos)
        {
            cameraUp = new Vector3(0, 1.0f, 0);
            cameraPointAt = new Vector3(0, 0, 1.0f);

            worldPosition = pos;
            worldUp = cameraUp + pos;
            worldPointAt = cameraPointAt + pos;
        }

        /// <summary>
        /// Sets the position of the camera in world space.
        /// Also updates the worldUp and worldPointAt vectors.
        /// </summary>
        /// <param name="pos">World space position.</param>
        public void SetPosition(Vector3 pos)
        {
            worldPosition = pos;
            worldUp = cameraUp + pos;
            worldPointAt = cameraPointAt + pos;
        }

        /// <summary>
        /// Moves the camera by an offset along the x axis.
        /// Also updates the worldUp and worldPointAt vectors.
        /// </summary>
        /// <param name="m">Offset of movement along x axis.</param>
        public void MoveX(float m)
        {
            worldPosition += new Vector3(m, 0, 0);
            worldUp = cameraUp + worldPosition;
            worldPointAt = cameraPointAt + worldPosition;
        }

        /// <summary>
        /// Moves the camera by an offset along the y axis.
        /// Also updates the worldUp and worldPointAt vectors.
        /// </summary>
        /// <param name="m">Offset of movement along y axis.</param>
        public void MoveY(float m)
        {
            worldPosition += new Vector3(0, m, 0);
            worldUp = cameraUp + worldPosition;
            worldPointAt = cameraPointAt + worldPosition;
        }

        /// <summary>
        /// Moves the camera by an offset along the z axis.
        /// Also updates the worldUp and worldPointAt vectors.
        /// </summary>
        /// <param name="m">Offset of movement along y axis.</param>
        public void MoveZ(float m)
        {
            worldPosition += new Vector3(0, 0, m);
            worldUp += new Vector3(0, 0, m);
            worldPointAt += new Vector3(0, 0, m);
        }

        /// <summary>
        /// Rotates the camera on the x axis by a 
        /// given angle.
        /// </summary>
        /// <param name="theta">Angle of rotation.</param>
        public void RotateX(float theta)
        {
            // Construct Rotation Matrix
            Matrix M = Matrix.RotationX(theta);
            // Transform vectors
            cameraUp.TransformCoordinate(M);
            cameraPointAt.TransformCoordinate(M);
            // Translate vectors
            worldUp = cameraUp + pos;
            worldPointAt = cameraPointAt + pos;
        }

        /// <summary>
        /// Rotates the camera on the y axis by a 
        /// given angle.
        /// </summary>
        /// <param name="theta">Angle of rotation.</param>
        public void RotateY(float theta)
        {
            // Construct Rotation Matrix
            Matrix M = Matrix.RotationY(theta);
            // Transform vectors
            cameraUp.TransformNormal(M);
            cameraPointAt.TransformNormal(M);
            // Translate vectors
            worldUp = cameraUp + worldPosition;
            worldPointAt = cameraPointAt + worldPosition;
        }
        
        /// <summary>
        /// Rotates the camera on the z axis by a 
        /// given angle.
        /// </summary>
        /// <param name="theta">Angle of rotation.</param>
        public void RotateZ(float theta)
        {
            // Construct Rotation Matrix
            Matrix M = Matrix.RotationZ(theta);
            // Transform vectors
            cameraUp.TransformNormal(M);
            cameraPointAt.TransformNormal(M);
            // Translate vectors
            worldUp = cameraUp + worldPosition;
            worldPointAt = cameraPointAt + worldPosition;
        }

        public void LookAtPoint(Vector3 point)
        {
            // Translate point vector to camera space.
            // That way we can easily perform transformations
            // using unit vectors.
            point -= worldPosition;
            point.Normalize();

            float xDisplacement = point.X - cameraPointAt.X;
            float yDisplacement = point.Y - cameraPointAt.Y;

            // Assign point as the PointAt vector and 
            // apply displacement to the Up vector.
            cameraPointAt = point;
            cameraUp.X += xDisplacement;
            cameraUp.Y += yDisplacement;

            // Update the camera in word space.
            worldPointAt = cameraPointAt + worldPosition;
            worldUp = cameraUp + worldPosition;

        }

        public void NormalizeAll()
        {
            worldPointAt.Normalize();
            worldUp.Normalize();
            cameraPointAt.Normalize();
            cameraUp.Normalize();
        }
           
        // These properties describe the camera in world space.
        public Vector3 worldPosition;
        public Vector3 worldUp;
        public Vector3 worldPointAt;

        // These properties describe the camera in its object space.
        // There is no camera position because it is at the origin.
        // Translations of these points can be done based off the worldPosition.
        private Vector3 cameraUp;
        private Vector3 cameraPointAt;
        
    }

}


[Edited by - Etherstar on May 30, 2005 2:05:22 PM]
Advertisement
Quote:All I really want is for the camera to do the following:

-Rotate on each of the cameras Axes
-Move around while retaining orientation.
It sounds like you want 6dof motion such as in a space shooter, is that correct? That is, the camera can have any orientation - upside down, sideways, etc - and rotation always takes place around the camera's local forward, up, and side axes.

Or are you looking for a simple FPS Quake-style camera, where only yaw and pitch are applied and the camera always remains upright?
This specific camera is being used in a Turn Based Strategy game. It will have a couple of fixed heights and will be able to rotate 90 degrees so that the player can view the map from all 4 sides (in case of object obstruction). There will also be a straight 90 degree topdown view available as well.
Basically your camera class/struct/whatever needs to hold the current camera position and viewing angles. Every frame you perform the local->world->camera transformations.

Local coordinates (also called object space) are the object's vertices relative to the object's origin. World coordinates are the object's vertices relative to the world's origin. And, you guessed it, camera coordinates are the object's vertices relative to the camera's origin.

So in your game loop you need to calculate these for every object:

Rotate the object locally using the object's orientation values.
Translate the object into world space using the object's position values.
Translate the object into camera space using your camera's position.
Rotate the object using the inverse of your camera's orientation.

And that's pretty much it. Ask if I was unclear.
Yes, but if you notice my code that's what I'm trying to do. If you have a quick moment to check it over could you see if I'm doing my translations wrong? I think that's where my problem lies but I can't pinpoint the problem in my math logic. Thanks!
solved: was inputting my camera space up vector into my view matrix instead of my world space up vector. DOH!

This topic is closed to new replies.

Advertisement