public TrackballWidget() : base() { base.GLSetup += GtkGL.GLWidget.EnableLighting; // Create and initialize the quaternion quat = new GtkGL.Quaternion(0.0, 0.0, 0.0, 1.0); connectHandlers(); }
public void Rotate(GtkGL.Quaternion q) { Quat *= q; Console.WriteLine("q: " + Quat.ToString()); // Tell our handlers that we have been updated if (Updated != null) { Updated(this, null); } }
public static Quaternion operator *(Quaternion q1, Quaternion q2) { if(q1 == null) return null; if(q2 == null) return null; Vector3b v1 = new Vector3b(q1.x, q1.y, q1.z); Vector3b v2 = new Vector3b(q2.x, q2.y, q2.z); double angle = ((q1.w * q2.w) - Vector3b.Dot(v1, v2)); Vector3b cross = Vector3b.Cross(v1, v2); v1 *= q2.w; v2 *= q1.w; Quaternion result = new Quaternion(angle, (v1.x + v2.x + cross.x), (v1.y + v2.y + cross.y), (v1.z + v2.z + cross.z) ); return result; }
// Track mouse dragging void OnMotionNotify(object o, Gtk.MotionNotifyEventArgs e) { int ix, iy; double x, y; Gdk.ModifierType m; // Find the current mouse X and Y positions if (e.Event.IsHint) { e.Event.Window.GetPointer(out ix, out iy, out m); x = (double)ix; y = (double)iy; } else { x = e.Event.X; y = e.Event.Y; } if(button1Pressed == true){ // Create a quaternion based on the mouse movement float[] spinQuat = new float[4]; tb.trackball(ref spinQuat, (float) ((2.0 * beginX - this.Allocation.Width) / this.Allocation.Width), (float) ((this.Allocation.Height - 2.0 * beginY) / this.Allocation.Height), (float) ((2.0 * x - this.Allocation.Width) / this.Allocation.Width), (float) ((this.Allocation.Height - 2.0 * y) / this.Allocation.Height)); // Add created quaternion to the current quat to get the new spin // Quaternion newQuat = new Quaternion(spinQuat); Quaternion newQuat = new Quaternion((double) spinQuat[3], (double) spinQuat[0], (double) spinQuat[1], (double) spinQuat[2] ); // Apply rotation to all objects System.Collections.IEnumerator enumerator = GLObjectList.GetEnumerator(); while(enumerator.MoveNext()){ ( (GtkGL.IGLObject) enumerator.Current ).Rotate(newQuat); } // Reset the "old" X and Y positions beginX = x; beginY = y; } }