• Advertisement
Sign in to follow this  

[MDX] Camera screws up [SOLVED]

This topic is 4330 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

*Shakes head in disappointment* Every time I make a little progress I hit a snag. So I'm using a camera class that I got mostly from the book "Introduction to 3D Game Programming with DirectX 9.0" by Frank D. Luna. I didn't copy the implementation at all, I just looked at the implementation and figured what I thought I needed and added it to my code. And it worked...kind of. When I first start out with my scene, it works beautifully, but the more I rotate around the right vector (I forget which one that is, pitch, maybe?) away from the starting position, the more screwed up the camera gets. At its extreme, when I want it to yaw, it ends up rolling, and when I want it to go forward and backward, it ends up going barely forward and up/barely backward and down, respectively. I tried resetting the view matrix every frame, but that just made things worse. I was wondering if anyone could take a look at the class and my implementation of it and see if there's anything I might want to change (I'm looking at you, Armadon [smile]). Camera.cs:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using Microsoft;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace TerrainGen
{
    class Camera
    {
        public enum CameraType
        {
            LANDOBJ,
            AIRCRAFT
        }

        public CameraType cameraType;
        public Vector3 right;
        public Vector3 up;
        public Vector3 look;
        public Vector3 pos;

        public Camera()
        {
            cameraType = CameraType.LANDOBJ;
            pos = new Vector3(0.0f, 0.0f, -5.0f);
            look = new Vector3(.0f, 0.0f, 1.0f);
            up = new Vector3(0.0f, 1.0f, 0.0f);
            right = new Vector3(1.0f, 0.0f, 0.0f);
        }

        public Camera(CameraType CT)
        {
            cameraType = CT;
            pos = new Vector3(0.0f, 0.0f, -5.0f);
            look = new Vector3(0.0f, 0.0f, 1.0f);
            up = new Vector3(0.0f, 1.0f, 0.0f);
            right = new Vector3(1.0f, 0.0f, 0.0f);
        }

        public void Strafe(float units)
        {
            if (cameraType == CameraType.LANDOBJ)
                pos += new Vector3(right.X, 0.0f, right.Z) * units;
            if (cameraType == CameraType.AIRCRAFT)
                pos += right * units;
        }

        public void Fly(float units)
        {
            if (cameraType == CameraType.AIRCRAFT)
                pos += up * units;
        }

        public void Walk(float units)
        {
            if (cameraType == CameraType.LANDOBJ)
                pos += new Vector3(look.X, 0.0f, look.Z) * units;
            if (cameraType == CameraType.AIRCRAFT)
                pos += look * units;
        }

        public void Pitch(float angle)
        {
            Matrix T = Matrix.RotationAxis(right, angle);

            up = Vector3.TransformCoordinate(up, T);
            look = Vector3.TransformCoordinate(look, T);
        }

        public void Yaw(float angle)
        {
            Matrix T;

            if (cameraType == CameraType.LANDOBJ)
                T = Matrix.RotationY(angle);
            else if (cameraType == CameraType.AIRCRAFT)
                T = Matrix.RotationAxis(up, angle);
            else
                return;

            right = Vector3.TransformCoordinate(right, T);
            look = Vector3.TransformCoordinate(look, T);
        }

        public void Roll(float angle)
        {
            if (cameraType == CameraType.AIRCRAFT)
            {
                Matrix T = Matrix.RotationAxis(look, angle);

                right = Vector3.TransformCoordinate(right, T);
                up = Vector3.TransformCoordinate(up, T);
            }
        }

        public Matrix GetViewMatrix()
        {
            Matrix v;

            look = Vector3.Normalize(look);

            up = Vector3.Cross(look, right);
            up = Vector3.Normalize(up);

            right = Vector3.Cross(up, look);

            float x = -Vector3.Dot(right, pos);
            float y = -Vector3.Dot(up, pos);
            float z = -Vector3.Dot(look, pos);

            v.M11 = right.X;
            v.M12 = up.X;
            v.M13 = look.X;
            v.M14 = 0.0f;

            v.M21 = right.Y;
            v.M22 = up.Y;
            v.M23 = look.Y;
            v.M24 = 0.0f;

            v.M31 = right.Z;
            v.M32 = up.Z;
            v.M33 = look.Z;
            v.M34 = 0.0f;

            v.M41 = x;
            v.M42 = y;
            v.M43 = z;
            v.M44 = 1.0f;

            return v;
        }

        public void SetCameraType(CameraType CT)
        {
            cameraType = CT;
        }

        public Vector3 GetPosition()
        {
            return pos;
        }

        public void SetPosition(Vector3 Position)
        {
            pos = Position;
        }

        public Vector3 GetRight()
        {
            return right;
        }

        public Vector3 GetUp()
        {
            return up;
        }

        public Vector3 GetLook()
        {
            return look;
        }
    }
}


And my implementation of it:
Camera cam = new Camera(Camera.CameraType.LANDOBJ);
Device device = null;

public void initDevice()
{
    //PresentParameters stuff
    device = new Device(//standard stuff in here);
    device.SetTramsform(TransformType.View, cam.GetViewMatrix());
    //RenderState stuff
}

//A bunch of other stuff that does vertex buffer, index buffer, file i/o, etc.

public void ProcessInput()
{
    KeyboardState keys = kb.GetCurrentKeyboardState();
    if (keys[Key.Up])
        cam.Walk(0.5f);
    if (keys[Key.Down])
        cam.Walk(-0.5f);
    if (keys[Key.Left])
        cam.Yaw(0.05f);
    if (keys[Key.Right])
        cam.Yaw(-0.05f);
    if (keys[Key.Home])
        cam.Pitch(-0.05f);
    if (keys[Key.End])
        cam.Pitch(0.05f);
    if (keys[Key.Escape])
        this.Close();
}

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {
            device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black , 1.0f, 0);
            ProcessInput();
            device.BeginScene();
            device.SetTransform(TransformType.View, cam.GetViewMatrix());
            device.VertexFormat = CustomVertex.PositionColored.Format;
            device.SetStreamSource(0, vb, 0);
            device.Indices = ib;
 

            device.Transform.World = Matrix.Translation(-HEIGHT/2, -WIDTH/2, 0);
            device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, WIDTH*HEIGHT, 0, indices.Length/3);
            device.EndScene();
  
            device.Present();
  
            this.Invalidate();
         }


I've limited the code presented to that which actually implements functions from the Camera class for brevity. I hope someone can help me out here. I've tried a few things, myself, but nothing seems to works. Thanks very much for your time. -AJ [Edited by - u235 on April 19, 2006 7:20:26 PM]

Share this post


Link to post
Share on other sites
Advertisement
One of the things I noticed is that you don't renormalize the right vector in GetViewMatrix(). For right now, that's all I noticed.

Share this post


Link to post
Share on other sites
Actually, I just realized that the camera isn't screwing up, it just looked like it was due to the fact that my terrain doesn't really look like anything right now. For exaple, when I pitch 90 degrees from starting position, I can say my camera is looking up relative to the world. So when I try to turn right, I will just spin in a circle, thus it appears the the camera is rolling, when actually it's doing exactly what it is supposed to.

Damn, that's the second time this week, I've made a post and then realized my error after doing so. Methinks I have a problem with maintaining my patience, eh? [grin].

Thanks for the reply though, and props to you for doing so.

-AJ

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement