Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

Options
Go to last post Go to first unread
Offline Michael Koch  
#1 Posted : Wednesday, February 5, 2014 9:52:15 PM(UTC)
Michael Koch

Joined: 12/27/2013(UTC)
Posts: 41
Location: Regensburg

Thanks: 3 times
Was thanked: 1 time(s) in 1 post(s)
Hey there,

as I had some problems to get the built-in FreeCam's axis and rotations right, I tried to roll one of my own. It is not completely finished yet, but I thought I might present it here for comments and/or usage by others (me running on [Nightly 1.0.013]). Attached a small (and totally pointless, yay) demo level as well - use WASD to move (zipped Release folder).

Code:
using DeltaEngine.Core;
using DeltaEngine.Datatypes;
using DeltaEngine.Graphics;
using DeltaEngine.Rendering3D;
using DeltaEngine.Rendering3D.Cameras;

namespace FreeCamTest
{
	/// <summary>
	/// A camera that can be moved in local and world directions and rotate around own axes. 
    /// MiKo version 1.0 - 2/2014. Thanks to http://www.madgamedev.com and others
	/// </summary>
	public class myFreeCamera : Camera
	{
        private Quaternion m_rRotation;
        private Vector3D m_vPosition;
        private Matrix m_mCameraMatrix;

        private Vector3D m_vLocalX;  // Right
        private Vector3D m_vLocalY;  // Fwd
        private Vector3D m_vLocalZ;  // Up

        private Vector3D C_vX = Vector3D.UnitX; // Need this for Vector3D.Transform(ref...) below
        private Vector3D C_vY = Vector3D.UnitY;
        private Vector3D C_vZ = Vector3D.UnitZ;

        // Properties
        // ---------------------------------------------------------------------------

        public Quaternion Rotation 
        { 
            get { return m_rRotation; }
            set 
            { 
                m_rRotation = value;
                UpdateCameraAxes(); // Need to call this before Matrix update
                UpdateCameraMatrix();
            } 
        }

        override public Vector3D Position
        {
            get { return m_vPosition; }
            set
            {
                m_vPosition = value;
                UpdateCameraMatrix(); // No need to update axes here
            }
        }

        public Matrix CamMatrix
        {
            get { return m_mCameraMatrix; }
            private set { }
        }
 
        // Methods
        // ---------------------------------------------------------------------------

        static private float ClampAngle(float fAngle)
        {
            if (fAngle > 360.0f) return (fAngle - 360.0f);
            if (fAngle < 0.0f) return (fAngle + 360.0f);
            return (fAngle);
        }
        
        public myFreeCamera(Device device, Window window) : base(device, window)
		{
            m_vPosition = Vector3D.Zero;
            m_rRotation = Quaternion.Identity;

            UpdateCameraAxes(); // Need to call this before Matrix update
            UpdateCameraMatrix();           
		}

        public void RotateLocal(Vector3D vDegrees)
        {
            Vector3D vX = Vector3D.UnitX.Transform(m_rRotation);
            Vector3D vY = Vector3D.UnitY.Transform(m_rRotation);
            Vector3D vZ = Vector3D.UnitZ.Transform(m_rRotation);
            
            Quaternion qX = Quaternion.FromAxisAngle(vX, vDegrees.X);
            Quaternion qY = Quaternion.FromAxisAngle(vY, vDegrees.Y);
            Quaternion qZ = Quaternion.FromAxisAngle(vZ, vDegrees.Z);

            m_rRotation *= qX;
            m_rRotation *= qY;
            m_rRotation *= qZ;

            UpdateCameraAxes(); // Need to call this before Matrix update
            UpdateCameraMatrix();    
        }

        private void UpdateCameraMatrix()
        {
            m_mCameraMatrix = Matrix.CreateLookAt(m_vPosition, m_vPosition + m_vLocalY, m_vLocalZ);
        }

        private void UpdateCameraAxes()
        {
            Vector3D.Transform(ref C_vX, ref m_rRotation, out m_vLocalX);
            Vector3D.Transform(ref C_vY, ref m_rRotation, out m_vLocalY);
            Vector3D.Transform(ref C_vZ, ref m_rRotation, out m_vLocalZ);

            m_vLocalX.Normalize();
            m_vLocalY.Normalize();
            m_vLocalZ.Normalize();
        }

        public void MoveLocalX(float fDistance) // Right-Left
        {
            m_vPosition += m_vLocalX * fDistance;
            UpdateCameraMatrix(); // No need to update axes here
        }

        public void MoveLocalY(float fDistance) // Forward-Back
        {
            m_vPosition += m_vLocalY * fDistance;
            UpdateCameraMatrix(); // No need to update axes here
        }

		public void MoveLocalZ(float fDistance) // Up-down
		{
            m_vPosition += m_vLocalZ * fDistance;
            UpdateCameraMatrix(); // No need to update axes here
		}

        public void MoveWorldX(float fDistance) // Right-Left
        {
            m_vPosition += C_vX * fDistance;
            UpdateCameraMatrix(); // No need to update axes here
        }

        public void MoveWorldY(float fDistance) // Forward-Back
        {
            m_vPosition += C_vY * fDistance;
            UpdateCameraMatrix(); // No need to update axes here
        }

        public void MoveWorldZ(float fDistance) // Up-down
        {
            m_vPosition += C_vZ * fDistance;
            UpdateCameraMatrix(); // No need to update axes here
        }

        // Overrides
        // ---------------------------------------------------------------------------

		public override void ResetDefaults() {}

		protected override Matrix GetCurrentViewMatrix()
		{
            return m_mCameraMatrix;
		}
	}
}
File Attachment(s):
Release.zip (2,591kb) downloaded 0 time(s).
Michael Koch attached the following image(s):
Image1.png (206kb) downloaded 245 time(s).

You cannot view/download attachments. Try to login or register.

Wanna join the discussion?! Login to your forum accountregister a new account. Or Connect via Facebook Twitter Google

Offline Benjamin  
#2 Posted : Wednesday, February 5, 2014 11:32:33 PM(UTC)
Benjamin

Medals: Admin

Joined: 8/20/2011(UTC)
Posts: 1,421
Location: Hannover

Thanks: 18 times
Was thanked: 97 time(s) in 92 post(s)
Looks cool, great demo! Seems like you are using it like a FPS (First Person Shooter) Camera, which is much easier to handle and control than a completely free camera (like in Space Sims or Descent-like games).
Rss Feed  Atom Feed
Users browsing this topic
OceanSpiders 2.0
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Powered by YAF.NET | YAF.NET © 2003-2023, Yet Another Forum.NET
This page was generated in 0.043 seconds.