budnhead/org.budnhead/graphics/GLCameraController.cs

182 lines
3.7 KiB
C#

/**
* GLCameraController
*
* Default camera controller using mouse dragging
*
**/
using System;
using System.Drawing;
using OpenTK;
using System.Drawing.Drawing2D;
using org.budnhead.core;
namespace org.budnhead.graphics
{
public class GLCameraController
{
private SceneWindow sceneWindow;
private GLCamera camera;
private Point mouseCapturePosition;
private bool mouseCaptured;
public Limits LimitUpDown { get; set; } = new Limits(-MathHelper.PiOver2,-MathHelper.Pi / 16);
public Limits LimitLeftRight { get; set; } = new Limits(-Math.PI, Math.PI);
public GLCameraController(GLCamera camera, SceneWindow sceneWindow){
this.sceneWindow = sceneWindow;
this.camera = camera;
}
public GLCameraController(GLCamera camera){
this.sceneWindow = null;
this.camera = camera;
}
public SceneWindow SceneWindow {
get { return sceneWindow; }
set {
releaseSceneWindow();
sceneWindow = value;
allocSceneWindow();
}
}
public GLCamera Camera {
get { return this.camera; }
set { this.camera = value; }
}
private void releaseSceneWindow(){
if (sceneWindow != null){
sceneWindow.MouseWheel -= SceneWindow_MouseWheel;
sceneWindow.MouseDown -= SceneWindow_MouseDown;
sceneWindow.MouseUp -= SceneWindow_MouseUp;
sceneWindow.MouseMove -= SceneWindow_MouseMove;
}
}
private void allocSceneWindow(){
if (sceneWindow != null){
sceneWindow.MouseWheel += SceneWindow_MouseWheel;
sceneWindow.MouseDown += SceneWindow_MouseDown;
sceneWindow.MouseUp += SceneWindow_MouseUp;
sceneWindow.MouseMove += SceneWindow_MouseMove;
}
}
private void captureMouse()
{
mouseCapturePosition = new Point(sceneWindow.Mouse.X, sceneWindow.Mouse.Y);
mouseCaptured = true;
SceneWindow.CursorVisible = false;
}
private void releaseMouse()
{
mouseCaptured = false;
SceneWindow.CursorVisible = true;
}
void SceneWindow_MouseWheel(object sender, OpenTK.Input.MouseWheelEventArgs e)
{
Vector3 p, // Camera position
v; // Camera viewing direction
p = camera.Position;
v = camera.View;
p += v * e.Delta;
camera.Position = p;
}
void SceneWindow_MouseDown(object sender, OpenTK.Input.MouseButtonEventArgs e)
{
switch (e.Button)
{
case OpenTK.Input.MouseButton.Left:
//markMouse(e.X,e.Y);
break;
case OpenTK.Input.MouseButton.Right:
captureMouse();
break;
}
}
void SceneWindow_MouseUp(object sender, OpenTK.Input.MouseButtonEventArgs e)
{
releaseMouse();
}
void SceneWindow_MouseMove(object sender, OpenTK.Input.MouseMoveEventArgs e)
{
if (mouseCaptured)
{
Point delta = new Point(e.X - mouseCapturePosition.X, e.Y - mouseCapturePosition.Y);
onMouseCapturedMove(delta);
mouseCapturePosition = e.Position;
}
else {
}
}
protected virtual void onMouseCapturedMove(Point delta)
{
rotateLeftRight(((float)delta.X) / -50.0f);
rotateUpDown(((float)delta.Y) / -50.0f);
}
public void rotateUpDown(float arc)
{
Vector3 v, // view direction
t, // top direction
r; // rotation axis
v = camera.View;
t = camera.Top;
r = Vector3.Cross(v, t);
Matrix3 mrot = Matrix3.CreateFromAxisAngle(r, arc);
v *= mrot;
t *= mrot;
camera.View = v;
camera.Top = t;
}
public void rotateLeftRight(float arc)
{
Vector3 v, // view direction
t, // top direction
r; // rotation axis
v = camera.View;
t = camera.Top;
r = Vector3.UnitZ;
Matrix3 mrot = Matrix3.CreateFromAxisAngle(r, arc);
v *= mrot;
t *= mrot;
camera.View = v;
camera.Top = t;
}
public void walk(float distance)
{
}
public void strafe(float distance)
{
}
}
}