using System; using OpenTK.Graphics.OpenGL; using OpenTK.Graphics; using OpenTK; using org.budnhead.audio; namespace org.budnhead.graphics { public class GLCamera : GLSceneOrientation { float fov; float width, height; float aspect; Vector3 vPosition, vView, vTop; GLCameraController controller; public GLCamera() { controller = new GLCameraController(this); fov = MathHelper.PiOver2; width = 100; height = 100; aspect = 1; vPosition = new Vector3(0,0,1000); vView = new Vector3(0,0,-1); vTop = new Vector3(0,1,0); buildProjection(); buildMatrices(); } override public void setViewport(int width, int height) { this.width = (float)width; this.height = (float)height; buildProjection(); } public void setFoV(float fov){ this.fov = fov; buildProjection(); } private void buildProjection(){ aspect = width / height; _mProjection = Matrix4.CreatePerspectiveFieldOfView( fov, aspect, 1.0f, 50000.0f ); } public GLCameraController CameraController { get { return this.controller; } set { this.controller = value; } } public Vector3 Position { get { return new Vector3(vPosition); } set { this.vPosition = new Vector3(value); buildMatrices(); nhListener.setPosition(this.vPosition);} } public Vector3 View { get { return new Vector3(vView); } set { this.vView = new Vector3(value).Normalized(); buildMatrices(); nhListener.setView(this.vView); } } public Vector3 Top { get { return new Vector3(vTop); } set { this.vTop = new Vector3(value).Normalized(); buildMatrices(); nhListener.setTop(this.vTop);} } private void buildMatrices(){ Matrix4 mTranslation = Matrix4.CreateTranslation( -this.vPosition ); Vector3 x,y,z; z = -vView; x = Vector3.Cross( vTop, z ).Normalized(); y = Vector3.Cross( z, x ); Matrix4 mRotation = new Matrix4( new Vector4(x,0), new Vector4(y,0), new Vector4(z,0), new Vector4(0,0,0,1) ); mRotation.Transpose(); _mCamera = mTranslation * mRotation; } public Vector3 pickRay(float x,float y){ float y_arc,x_arc; x_arc = (( (2*x) ) - width) * aspect; y_arc = height - ( (2*y) ); x_arc /= width; y_arc /= height; Vector4 ray = new Vector4(x_arc,y_arc,1,1); Console.WriteLine("Pick Ray: {0}",ray); Matrix4 mpi = _mProjection.Inverted(); mpi.Transpose(); ray = mpi * ray; ray.Normalize(); Console.WriteLine("Pick Ray (PROJ): {0}",ray); // ray.Z = -1; // ray.W = 0; //Console.WriteLine("Pick Ray (CAM): {0}",ray); Matrix4 mci = _mCamera.Inverted(); mci.Transpose(); ray = mci * ray; Console.WriteLine("Pick Ray (CAM): {0}",ray); //Console.WriteLine("Pick Ray Angles: x:{0} / y:{1}",x_arc,y_arc); //ray = Matrix4.CreateRotationY(-y_arc) * Matrix4.CreateRotationX( x_arc ) * ray; Vector3 pr = ray.Xyz.Normalized(); if (pr.Z > 0){ pr *= -1; } Console.WriteLine("Pick Ray (World): {0}",pr); Console.WriteLine("--------------------------------------------------"); return pr; } /** * Group of Methods: LookXXXX * * Arrange Camera to point on/to/... * **/ public void lookAt(Vector3 position){ Vector3 v = position - Position; v.Normalize(); View = v; } } }