using System; using System.Collections.Generic; using System.Linq; using System.Text; using Aiwaz.Contracts; using Aiwaz.Core; using Aiwaz.Common.Animations; using Aiwaz.Resources.Attributes; namespace Aiwaz.Resources { [CreationParameters("Standard orthographic camera")] public class OrthographicCameraParams { public float width; public float height; public OrthographicCameraParams() { width = 512; height = 512; } } [AiwazResource("Orthographic Camera", "An orthographic camera for orthogonal views.")] public class OrthographicCamera : BaseCamera, IOrthographicCamera { #region IOrthographicCamera Members private float width; private float height; private OrthographicCamera() : base() { } public OrthographicCamera(OrthographicCameraParams parameters) : this() { Console.WriteLine(string.Format("Creating OrthographicCamera ({0}x{1})..", parameters.width, parameters.height)); this.Width = parameters.width; this.Height = parameters.height; } public float Width { get { return width; } set { width = value; WantsUpdate = true; } } public float Height { get { return height; } set { height = value; WantsUpdate = true; } } public override void Update(bool forceUpdate) { base.Update(forceUpdate); this.ProjectionMatrix = SlimDX.Matrix.OrthoLH(width, height, this.NearClip, this.FarClip); this.ViewMatrix = SlimDX.Matrix.LookAtLH(this.WorldPosition, this.WorldPosition + this.WorldDirection, this.WorldUpDirection); // generate view frustum var viewProj = this.ViewMatrix * this.ProjectionMatrix; // Left plane this.ViewFrustum.Plane[0] = new SlimDX.Plane(viewProj.M14 + viewProj.M11, viewProj.M24 + viewProj.M21, viewProj.M34 + viewProj.M31, viewProj.M44 + viewProj.M41); // Right plane this.ViewFrustum.Plane[1] = new SlimDX.Plane(viewProj.M14 - viewProj.M11, viewProj.M24 - viewProj.M21, viewProj.M34 - viewProj.M31, viewProj.M44 - viewProj.M41); // Top plane this.ViewFrustum.Plane[2] = new SlimDX.Plane(viewProj.M14 - viewProj.M12, viewProj.M24 - viewProj.M22, viewProj.M34 - viewProj.M32, viewProj.M44 - viewProj.M42); // Bottom plane this.ViewFrustum.Plane[3] = new SlimDX.Plane(viewProj.M14 + viewProj.M12, viewProj.M24 + viewProj.M22, viewProj.M34 + viewProj.M32, viewProj.M44 + viewProj.M42); // Near plane this.ViewFrustum.Plane[4] = new SlimDX.Plane(viewProj.M13, viewProj.M23, viewProj.M33, viewProj.M43); // Far plane this.ViewFrustum.Plane[5] = new SlimDX.Plane(viewProj.M14 - viewProj.M13, viewProj.M24 - viewProj.M23, viewProj.M34 - viewProj.M33, viewProj.M44 - viewProj.M43); } #endregion } [CreationParameters("Standard orthographic camera")] public class PerspectiveCameraParams { public float fov; public float aspectRatio; public PerspectiveCameraParams() { fov = 90.0f; aspectRatio = 1.0f; } } [AiwazResource("Perspective Camera", "An perspective camera for perspective correct views.")] public class PerspectiveCamera : BaseCamera, IPerspectiveCamera { #region IPerspectiveCamera Members private float fov; private float aspectRatio; private PerspectiveCamera() : base() { } public PerspectiveCamera(PerspectiveCameraParams parameters) : this() { Console.WriteLine(string.Format("Creating PerspectiveCamera (Fov: {0} AspectRatio: {1})..", parameters.fov, parameters.aspectRatio)); this.Fov = parameters.fov; this.AspectRatio = parameters.aspectRatio; } [Animateable] public float Fov { get { return fov; } set { fov = value; WantsUpdate = true; } } [Animateable] public float AspectRatio { get { return aspectRatio; } set { aspectRatio = value; WantsUpdate = true; } } public override void Update(bool forceUpdate) { base.Update(forceUpdate); this.ProjectionMatrix = SlimDX.Matrix.PerspectiveFovLH((float)((Math.PI / 180) * fov), this.AspectRatio, this.NearClip, this.FarClip); this.ViewMatrix = SlimDX.Matrix.LookAtLH(this.WorldPosition, this.WorldPosition + this.WorldDirection, this.WorldUpDirection); // generate view frustum var viewProj = this.ViewMatrix * this.ProjectionMatrix; // Left plane this.ViewFrustum.Plane[0] = new SlimDX.Plane( viewProj.M14 + viewProj.M11, viewProj.M24 + viewProj.M21, viewProj.M34 + viewProj.M31, viewProj.M44 + viewProj.M41); // Right plane this.ViewFrustum.Plane[1] = new SlimDX.Plane(viewProj.M14 - viewProj.M11, viewProj.M24 - viewProj.M21, viewProj.M34 - viewProj.M31, viewProj.M44 - viewProj.M41); // Top plane this.ViewFrustum.Plane[2] = new SlimDX.Plane(viewProj.M14 - viewProj.M12, viewProj.M24 - viewProj.M22, viewProj.M34 - viewProj.M32, viewProj.M44 - viewProj.M42); // Bottom plane this.ViewFrustum.Plane[3] = new SlimDX.Plane(viewProj.M14 + viewProj.M12, viewProj.M24 + viewProj.M22, viewProj.M34 + viewProj.M32, viewProj.M44 + viewProj.M42); // Near plane this.ViewFrustum.Plane[4] = new SlimDX.Plane(viewProj.M13, viewProj.M23, viewProj.M33, viewProj.M43); // Far plane this.ViewFrustum.Plane[5] = new SlimDX.Plane(viewProj.M14 - viewProj.M13, viewProj.M24 - viewProj.M23, viewProj.M34 - viewProj.M33, viewProj.M44 - viewProj.M43); } #endregion } public abstract class BaseCamera : Transformation, ICamera { #region ICamera Members private float nearClip = 1.0f; private float farClip = 1000.0f; Reference projectionMatrix = new Reference(new SlimDX.Matrix()); Reference viewMatrix = new Reference(new SlimDX.Matrix()); public SlimDX.Matrix ProjectionMatrix { get { return (SlimDX.Matrix)projectionMatrix.RawValue; } protected set { projectionMatrix.RawValue = value; } } public SlimDX.Matrix ViewMatrix { get { return (SlimDX.Matrix)viewMatrix.RawValue; } protected set { viewMatrix.RawValue = value; } } public BaseCamera() : base(new CameraTransformationBindings()) { this.ViewFrustum = new ViewFrustum(); this.IsPreconditionForFollowingShaders = true; this.RecreateAllShaderParameters(); } public float FarClip { get { return farClip; } set { farClip = value; WantsUpdate = true; } } public float NearClip { get { return nearClip; } set { nearClip = value; WantsUpdate = true; } } public ViewFrustum ViewFrustum { get; protected set; } protected override void RecreateAllShaderParameters() { this.SetParameter("ViewMatrix", viewMatrix, ParameterBindType.BindBySemantic); this.SetParameter("ProjectionMatrix", projectionMatrix, ParameterBindType.BindBySemantic); base.RecreateAllShaderParameters(); } #endregion } }