- Main Page
- Packages
- Classes
- Files

- File List
- File Members

# D:/guillaume/guillara/3D/DXGfx/DXGfxLib/FreeCamera.cs

Go to the documentation of this file.

    00001 //BSD License
    00002 //DXGfx® - http://www.eteractions.com
    00003 //Copyright (c) 2005
    00004 //by Guillaume Randon
    00005 //Permission is hereby granted, free of charge, to any person obtaining a copy of this software
    00006 //and associated documentation files (the "Software"), to deal in the Software without restriction,
    00007 //including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
    00008 //and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
    00009 //subject to the following conditions:
    00010 //The above copyright notice and this permission notice shall be included in all copies or substantial
    00011 //portions of the Software.
    00012 //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
    00013 //INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
    00014 //AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    00015 //DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    00016 //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    00017 using System;
    00018 using System.Collections.Generic;
    00019 using System.Text;
    00020 using System.Windows.Forms;
    00021 using Microsoft.DirectX;
    00022 using Microsoft.DirectX.Direct3D;
    00023 using Microsoft.Samples.DirectX.UtilityToolkit;
    00024
    00025 namespace DXGfxLib
    00026 {
    00031     public class FreeCamera : Camera
    00032     {
    00036         public SceneNode person;
    00037
    00041         public SceneNode camera;
    00042
    00043         public Vector3 position;
    00044
    00045         public Vector3 up;
    00046
    00050         public float radius = 49.0f;
    00051
    00055         public float maxRadius = 150.0f;
    00056
    00060         public float minRadius = 4.0f;
    00061
    00065         protected int rotateButtonMask = (int)MouseButtonMask.Right;
    00066
    00070         protected int zoomButtonMask = (int)MouseButtonMask.Wheel;
    00071
    00075         public Matrix WorldMatrix = Matrix.Identity;
    00076
    00080         protected float angle = (float)Math.PI / 8;
    00081
    00082
    00083         protected float behindAngle = 0.0f;
    00084
    00085         protected bool rightDown = false;
    00086         protected float lastX = 0.0f;
    00087         protected float lastY = 0.0f;
    00088
    00089         protected float maxAngle = (float)(0.9*Math.PI);
    00090         protected float minAngle = -(float)(0.9*Math.PI);
    00091         protected float maxAngleVert = 0.5f * (float)Math.PI;
    00092         protected float minAngleVert = 0.0f;
    00093         protected float angleMult = 0.0005f * (float)Math.PI;
    00094
    00098         public SceneNode Person
    00099         {
    00100             set
    00101             {
    00102                 person = value;
    00103
    00104                 camera.parent = person;
    00105                 person.AddChild(camera);
    00106
    00107                 Matrix trans = Matrix.Translation(0.0f, radius * (float)Math.Sin(angle), -radius * (float)Math.Cos(angle));
    00108                 Matrix rot = Matrix.RotationX(angle);
    00109
    00110                 camera.LocalMat = Matrix.Multiply(rot, trans);
    00111             }
    00112             get { return person; }
    00113         }
    00114
    00119         public FreeCamera()
    00120         {
    00121             camera = new SceneNode();
    00122             Person = new SceneNode();
    00123         }
    00124
    00133         public override bool HandleMessages(IntPtr hWnd, NativeMethods.WindowMessage msg, IntPtr wParam, IntPtr lParam)
    00134         {
    00135             // Call base first
    00136             base.HandleMessages(hWnd, msg, wParam, lParam);
    00137
    00138             // Current mouse position
    00139             short mouseX = NativeMethods.LoWord((uint)lParam.ToInt32());
    00140             short mouseY = NativeMethods.HiWord((uint)lParam.ToInt32());
    00141
    00142             if (msg == NativeMethods.WindowMessage.RightButtonDown)
    00143             {
    00144                 rightDown = true;
    00145                 lastX = mouseX;
    00146                 lastY = mouseY;
    00147             }
    00148             if ((msg == NativeMethods.WindowMessage.MouseMove) && rightDown)
    00149             {
    00150                 behindAngle += angleMult * (mouseX - lastX);
    00151                 if (behindAngle > maxAngle)
    00152                     behindAngle = maxAngle;
    00153                 if (behindAngle < minAngle)
    00154                     behindAngle = minAngle;
    00155                 angle += angleMult * (mouseY - lastY);
    00156                 if (angle > maxAngleVert)
    00157                     angle = maxAngleVert;
    00158                 if (angle < minAngleVert)
    00159                     angle = minAngleVert;
    00160             }
    00161
    00162             if (msg == NativeMethods.WindowMessage.RightButtonUp)
    00163             {
    00164                 rightDown = false;
    00165             }
    00166
    00167             return false;
    00168         }
    00169
    00174         public override void FrameMove(float elapsedTime)
    00175         {
    00176             // Change the radius from the camera to the model based on wheel scrolling
    00177             if ((mouseWheelDelta != 0) && (zoomButtonMask == (int)MouseButtonMask.Wheel))
    00178             {
    00179                 radius -= mouseWheelDelta * radius * 0.1f;
    00180                 radius = Math.Min(maxRadius, radius);
    00181                 radius = Math.Max(minRadius, radius);
    00182                 mouseWheelDelta = 0;
    00183             }
    00184             Matrix trans = Matrix.Translation(0.0f, radius * (float)Math.Sin(angle), -radius * (float)Math.Cos(angle));
    00185             Matrix rot = Matrix.RotationX(angle);
    00186
    00187             camera.LocalMat = Matrix.Multiply(rot, trans);
    00188
    00189             // Get the mouse movement (if any) if the mouse buttons are down
    00190             if (currentButtonMask != 0)
    00191                 UpdateMouseDelta(elapsedTime);
    00192
    00193             // Get amount of velocity based on the keyboard input and drag (if any)
    00194             UpdateVelocity(elapsedTime);
    00195
    00196             // Simple euler method to calculate position delta
    00197             Vector3 posDelta = velocity * elapsedTime;
    00198
    00199             person.ApplyLocalTransform(Matrix.RotationY(0.1f * posDelta.X));
    00200
    00201             posDelta.X = 0.0f;
    00202             posDelta.Y = 0.0f;
    00203
    00204             person.ApplyLocalTransform(Matrix.Translation(posDelta));
    00205
    00206             camera.PositionToParent = Vector3.TransformCoordinate(camera.PositionToParent,
    00207                 Matrix.RotationY(behindAngle));
    00208
    00209             //if (person.positionConstraint != null)
    00210             //{
    00211             //    person.positionConstraint.ValidateOrMove(ref person);
    00212             //}
    00213             if (camera.positionConstraint != null)
    00214             {
    00215                 camera.positionConstraint.ValidateCameraOrMove(ref camera, ref person);
    00216             }
    00217
    00218             Vector3 localUp = new Vector3(0.0f, 1.0f, 0.0f);
    00219
    00220             position = camera.Position;
    00221             lookAt = person.Position;
    00222             up = localUp;
    00223             viewMatrix = Matrix.LookAtLH(camera.Position, person.Position, localUp);
    00224         }
    00225     }
    00226 }