KinPortal/Game/Camera.cs
2020-05-15 12:18:51 +02:00

136 lines
3.3 KiB
C#
Executable File

using System;
using Microsoft.Xna.Framework;
namespace KinPortal {
public class Camera : GameComponent {
public Matrix LookAtMatrix {
get {return Matrix.CreateLookAt(Pos, Eye + Pos, Up);}
}
public Matrix ProjectionMatrix {
get {return Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(Fov),
Game.GraphicsDevice.Viewport.AspectRatio,
NearDist,
FarDist
);
}
}
public float Fov {get; set;}
public float NearDist {get; set;}
public float FarDist {get; set;}
public Vector3 Pos {get; set;}
public Vector3 Eye {get; set;}
public Vector3 Up {get; set;}
private float m_tangage;
public float Tangage {
get {return m_tangage;}
set {
m_tangage = value;
Eye = GetEyeFromAngle(Lacet, Tangage);
}
}
private float m_lacet;
public float Lacet {
get {return m_lacet;}
set {
m_lacet = value;
Eye = GetEyeFromAngle(Lacet, Tangage);
}
}
private float m_roulis;
public float Roulis {
get {return m_roulis;}
set {
m_roulis = value;
// TODO : compute up vector
Up = new Vector3(0, 0, 1);
}
}
public Camera(Game game, Vector3 pos, Vector3 eye, Vector3 up, float fov, float near, float far)
: base(game) {
Pos = pos;
Eye = eye;
Up = up;
Fov = fov;
NearDist = near;
FarDist = far;
UpdateOrder = 1;
}
public Camera(Game game, Vector3 pos, float lacet, float tangage, float roulis, float fov, float near, float far)
: base(game) {
Pos = pos;
Lacet = lacet;
Tangage = tangage;
Roulis = roulis;
Fov = fov;
NearDist = near;
FarDist = far;
}
public void MoveForward(float step) {
Pos = Eye * step + Pos;
}
public void MoveBackward(float step) {
Pos = Eye * step * -1.0f + Pos;
}
public void MoveLeft(float step) {
Pos = GetEyeFromAngle(Lacet + 90.0f, 0) * step + Pos;
}
public void MoveRight(float step) {
Pos = GetEyeFromAngle(Lacet + 90.0f, 0) * step * -1.0f + Pos;
}
public void MoveUp(float step) {
Pos = Up * step + Pos;
}
public void MoveDown(float step) {
Pos = Up * step * -1.0f + Pos;
}
public void Rotate(float lacet, float tangage, float roulis) {
Lacet = (Lacet + lacet) % 360.0f;
Tangage = (Tangage + tangage) % 360.0f;
Roulis = (Roulis + roulis) % 360.0f;
}
private Vector3 GetEyeFromAngle(float lacet, float tangage) {
float lacet_rad = MathHelper.ToRadians(lacet);
float tangage_rad = MathHelper.ToRadians(tangage);
Vector3 eye = new Vector3(
(float) (Math.Cos(tangage_rad) * Math.Cos(lacet_rad)),
(float) (Math.Cos(tangage_rad) * Math.Sin(lacet_rad)),
(float) (Math.Sin(tangage_rad))
);
return Vector3.Normalize(eye);
}
public Vector3 Unproject(int x, int y) {
Vector3 nearSource = new Vector3(x, y, 0);
Vector3 farSource = new Vector3(x, y, 1);
Matrix world = Matrix.Identity;
Matrix proj = ProjectionMatrix;
Matrix view = LookAtMatrix;
Vector3 nearPoint = Game.GraphicsDevice.Viewport.Unproject(nearSource, proj, view, world);
Vector3 farPoint = Game.GraphicsDevice.Viewport.Unproject(farSource, proj, view, world);
return farPoint - nearPoint;
}
}
}