budnhead/org.budnhead/graphics/GLCamera.cs

158 lines
3.1 KiB
C#

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;
public GLCamera()
{
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,
100000.0f
);
}
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;
}
}
}