/** * 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) { } } }