diff --git a/.gitignore b/.gitignore
index 0dcea4d8..73da0d91 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@ Binaries/
OpenTK.userprefs
Source/GlobalAssemblyInfo.cs
Version.txt
+Source/OpenTK/OpenTK.xml
# OpenTK Resource files that seem like they should be ignored:
Source/Compatibility/Properties/Resources.resources
diff --git a/Source/Examples/Main.cs b/Source/Examples/Main.cs
index 213948be..cb940537 100644
--- a/Source/Examples/Main.cs
+++ b/Source/Examples/Main.cs
@@ -52,6 +52,7 @@ namespace Examples
// The ExampleBrowser works pretty poorly on some platforms, so you may want to start examples directly.
// for example: Examples.Tutorial.T12_GLSL_Parallax.Main ();
// Examples.Tutorial.T10_GLSL_Cube.Main ();
+ Examples.Tests.BasicMouseInput.Main ();
using (Form browser = new ExampleBrowser())
{
diff --git a/Source/Examples/OpenTK/Test/BasicMouseInput.cs b/Source/Examples/OpenTK/Test/BasicMouseInput.cs
index c106782e..a66d8268 100644
--- a/Source/Examples/OpenTK/Test/BasicMouseInput.cs
+++ b/Source/Examples/OpenTK/Test/BasicMouseInput.cs
@@ -25,7 +25,7 @@ namespace Examples.Tests
{
public BasicMouseInput()
- : base(800, 600, GraphicsMode.Default)
+ : base(800, 600)
{ }
protected override void OnLoad(EventArgs e)
@@ -42,6 +42,8 @@ namespace Examples.Tests
protected override void OnUpdateFrame(FrameEventArgs e)
{
+ base.OnUpdateFrame(e);
+
// Here's the big test!
if(OpenTK.Input.Mouse.GetState()[MouseButton.Left]){
Console.WriteLine("The left mouse button is down!");
@@ -66,7 +68,7 @@ namespace Examples.Tests
protected override void OnRenderFrame(FrameEventArgs e)
{
- GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
+ GL.Clear(ClearBufferMask.ColorBufferBit);
SwapBuffers();
}
@@ -78,7 +80,8 @@ namespace Examples.Tests
// Get the title and category of this example using reflection.
ExampleAttribute info = ((ExampleAttribute)example.GetType().GetCustomAttributes(false)[0]);
example.Title = String.Format("OpenTK | {0} {1}: {2}", info.Category, info.Difficulty, info.Title);
- example.Run(30.0, 0.0);
+
+ example.Run(30.0);
}
}
diff --git a/Source/OpenTK/Input/KeyboardDevice.cs b/Source/OpenTK/Input/KeyboardDevice.cs
index b1a14b9c..d21ca5a7 100644
--- a/Source/OpenTK/Input/KeyboardDevice.cs
+++ b/Source/OpenTK/Input/KeyboardDevice.cs
@@ -22,6 +22,7 @@ namespace OpenTK.Input
{
//private IKeyboard keyboard;
private bool[] keys = new bool[Enum.GetValues(typeof(Key)).Length];
+ private bool[] scancodes = new bool[256];
private string description;
private int numKeys, numFKeys, numLeds;
private IntPtr devID;
@@ -44,24 +45,16 @@ namespace OpenTK.Input
public bool this[Key key]
{
get { return keys[(int)key]; }
- internal set
- {
- if (keys[(int)key] != value || KeyRepeat)
- {
- keys[(int)key] = value;
+ }
- if (value && KeyDown != null)
- {
- args.Key = key;
- KeyDown(this, args);
- }
- else if (!value && KeyUp != null)
- {
- args.Key = key;
- KeyUp(this, args);
- }
- }
- }
+ ///
+ /// Gets a value indicating the status of the specified Key.
+ ///
+ /// The scancode to check.
+ /// True if the scancode is pressed, false otherwise.
+ public bool this[uint scancode]
+ {
+ get { return scancodes[scancode]; }
}
///
@@ -197,12 +190,34 @@ namespace OpenTK.Input
internal void ClearKeys()
{
for (int i = 0; i < keys.Length; i++)
- if (this[(Key)i]) // Make sure KeyUp events are *not* raised for keys that are up, even if key repeat is on.
- this[(Key)i] = false;
+ keys[i] = false;
+ for (uint i = 0; i < scancodes.Length; i++)
+ scancodes[i] = false;
}
#endregion
+ internal void SetKey(Key key, uint scancode, bool state)
+ {
+ if (keys[(int)key] != state || KeyRepeat)
+ {
+ keys[(int)key] = scancodes[scancode] = state;
+
+ if (state && KeyDown != null)
+ {
+ args.Key = key;
+ args.ScanCode = scancode;
+ KeyDown(this, args);
+ }
+ else if (!state && KeyUp != null)
+ {
+ args.Key = key;
+ args.ScanCode = scancode;
+ KeyUp(this, args);
+ }
+ }
+ }
+
#endregion
}
}
\ No newline at end of file
diff --git a/Source/OpenTK/Input/KeyboardKeyEventArgs.cs b/Source/OpenTK/Input/KeyboardKeyEventArgs.cs
index ac3ce8af..f607090c 100644
--- a/Source/OpenTK/Input/KeyboardKeyEventArgs.cs
+++ b/Source/OpenTK/Input/KeyboardKeyEventArgs.cs
@@ -1,83 +1,95 @@
-#region License
-//
-// The Open Toolkit Library License
-//
-// Copyright (c) 2006 - 2009 the Open Toolkit library.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights to
-// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-// the Software, and to permit persons to whom the Software is furnished to do
-// so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-// OTHER DEALINGS IN THE SOFTWARE.
-//
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace OpenTK.Input
-{
- ///
- /// Defines the event data for events.
- ///
- ///
- ///
- /// Do not cache instances of this type outside their event handler.
- /// If necessary, you can clone a KeyboardEventArgs instance using the
- /// constructor.
- ///
- ///
- public class KeyboardKeyEventArgs : EventArgs
- {
- #region Fields
-
- Key key;
-
- #endregion
-
- #region Constructors
-
- ///
- /// Constructs a new KeyboardEventArgs instance.
- ///
- public KeyboardKeyEventArgs() { }
-
- ///
- /// Constructs a new KeyboardEventArgs instance.
- ///
- /// An existing KeyboardEventArgs instance to clone.
- public KeyboardKeyEventArgs(KeyboardKeyEventArgs args)
- {
- Key = args.Key;
- }
-
- #endregion
-
- #region Public Members
-
- ///
- /// Gets the that generated this event.
- ///
- public Key Key
- {
- get { return key; }
- internal set { key = value; }
- }
-
- #endregion
- }
-}
+#region License
+//
+// The Open Toolkit Library License
+//
+// Copyright (c) 2006 - 2009 the Open Toolkit library.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace OpenTK.Input
+{
+ ///
+ /// Defines the event data for events.
+ ///
+ ///
+ ///
+ /// Do not cache instances of this type outside their event handler.
+ /// If necessary, you can clone a KeyboardEventArgs instance using the
+ /// constructor.
+ ///
+ ///
+ public class KeyboardKeyEventArgs : EventArgs
+ {
+ #region Fields
+
+ Key key;
+ uint scancode;
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Constructs a new KeyboardEventArgs instance.
+ ///
+ public KeyboardKeyEventArgs() { }
+
+ ///
+ /// Constructs a new KeyboardEventArgs instance.
+ ///
+ /// An existing KeyboardEventArgs instance to clone.
+ public KeyboardKeyEventArgs(KeyboardKeyEventArgs args)
+ {
+ Key = args.Key;
+ ScanCode = args.ScanCode;
+ }
+
+ #endregion
+
+ #region Public Members
+
+ ///
+ /// Gets the that generated this event.
+ ///
+ public Key Key
+ {
+ get { return key; }
+ internal set { key = value; }
+ }
+
+ ///
+ /// Gets the scancode which generated this event.
+ ///
+ public uint ScanCode
+ {
+ get { return scancode; }
+ internal set { scancode = value; }
+ }
+
+
+ #endregion
+ }
+}
diff --git a/Source/OpenTK/Input/KeyboardState.cs b/Source/OpenTK/Input/KeyboardState.cs
index d37c60da..839fa2cd 100644
--- a/Source/OpenTK/Input/KeyboardState.cs
+++ b/Source/OpenTK/Input/KeyboardState.cs
@@ -43,6 +43,7 @@ namespace OpenTK.Input
const int NumInts = ((int)Key.LastKey + IntSize - 1) / IntSize;
// The following line triggers bogus CS0214 in gmcs 2.0.1, sigh...
unsafe fixed int Keys[NumInts];
+ unsafe fixed int Codes[256];
bool is_connected;
#endregion
@@ -58,13 +59,17 @@ namespace OpenTK.Input
public bool this[Key key]
{
get { return IsKeyDown(key); }
- internal set
- {
- if (value)
- EnableBit((int)key);
- else
- DisableBit((int)key);
- }
+ }
+
+ ///
+ /// Gets a indicating whether the specified
+ /// is pressed.
+ ///
+ /// The to check.
+ /// True if key is pressed; false otherwise.
+ public bool this[short code]
+ {
+ get { return IsKeyDown(code); }
}
///
@@ -76,6 +81,15 @@ namespace OpenTK.Input
return ReadBit((int)key);
}
+ ///
+ /// Gets a indicating whether this scan code is down.
+ ///
+ /// The scan code to check.
+ public bool IsKeyDown(short code)
+ {
+ return ReadBit(code,true);
+ }
+
///
/// Gets a indicating whether this key is up.
///
@@ -85,6 +99,15 @@ namespace OpenTK.Input
return !ReadBit((int)key);
}
+ ///
+ /// Gets a indicating whether this scan code is down.
+ ///
+ /// The scan code to check.
+ public bool IsKeyUp(short code)
+ {
+ return !ReadBit(code,true);
+ }
+
///
/// Gets a indicating whether this keyboard
/// is connected.
@@ -187,48 +210,62 @@ namespace OpenTK.Input
#region Internal Members
- internal bool ReadBit(int offset)
+ internal void SetKeyState(Key key, byte code, bool down)
{
- ValidateOffset(offset);
-
- int int_offset = offset / 32;
- int bit_offset = offset % 32;
- unsafe
+ if (down)
{
- fixed (int* k = Keys)
- {
- return (*(k + int_offset) & (1 << bit_offset)) != 0u;
- }
+ EnableBit((int)key);
+ EnableBit(code,true);
+ }
+ else
+ {
+ DisableBit((int)key);
+ DisableBit(code, true);
}
}
- internal void EnableBit(int offset)
+ internal bool ReadBit(int offset, bool ScanCode = false)
{
- ValidateOffset(offset);
+ ValidateOffset(offset, ScanCode);
int int_offset = offset / 32;
int bit_offset = offset % 32;
unsafe
{
- fixed (int* k = Keys)
- {
- *(k + int_offset) |= 1 << bit_offset;
- }
+ if (ScanCode)
+ fixed (int* c = Codes) { return (*(c + int_offset) & (1 << bit_offset)) != 0u; }
+ else
+ fixed (int* k = Keys) { return (*(k + int_offset) & (1 << bit_offset)) != 0u; }
}
}
- internal void DisableBit(int offset)
+ internal void EnableBit(int offset, bool ScanCode = false)
{
- ValidateOffset(offset);
+ ValidateOffset(offset, ScanCode);
int int_offset = offset / 32;
int bit_offset = offset % 32;
unsafe
{
- fixed (int* k = Keys)
- {
- *(k + int_offset) &= ~(1 << bit_offset);
- }
+ if (ScanCode)
+ fixed (int* c = Codes) { *(c + int_offset) |= 1 << bit_offset; }
+ else
+ fixed (int* k = Keys) { *(k + int_offset) |= 1 << bit_offset; }
+ }
+ }
+
+ internal void DisableBit(int offset, bool ScanCode = false)
+ {
+ ValidateOffset(offset, ScanCode);
+
+ int int_offset = offset / 32;
+ int bit_offset = offset % 32;
+ unsafe
+ {
+ if (ScanCode)
+ fixed (int* c = Codes) { *(c + int_offset) &= ~(1 << bit_offset); }
+ else
+ fixed (int* k = Keys) { *(k + int_offset) &= ~(1 << bit_offset); }
}
}
@@ -242,6 +279,12 @@ namespace OpenTK.Input
for (int i = 0; i < NumInts; i++)
*(k1 + i) |= *(k2 + i);
}
+ int* c2 = other.Codes;
+ fixed (int* c1 = Codes)
+ {
+ for (int i = 0; i < short.MaxValue; i++)
+ *(c1 + i) |= *(c2 + i);
+ }
}
IsConnected |= other.IsConnected;
}
@@ -250,9 +293,9 @@ namespace OpenTK.Input
#region Private Members
- static void ValidateOffset(int offset)
+ static void ValidateOffset(int offset, bool ScanCode)
{
- if (offset < 0 || offset >= NumInts * IntSize)
+ if (offset < 0 || offset >= (ScanCode ? 256 : NumInts * IntSize))
throw new ArgumentOutOfRangeException("offset");
}
diff --git a/Source/OpenTK/Math/Matrix3.cs b/Source/OpenTK/Math/Matrix3.cs
index 11816206..3fb8e2e5 100644
--- a/Source/OpenTK/Math/Matrix3.cs
+++ b/Source/OpenTK/Math/Matrix3.cs
@@ -28,7 +28,7 @@ using System.Runtime.InteropServices;
namespace OpenTK
{
///
- /// Represents a 3x3 Matrix
+ /// Represents a 3x3 matrix containing 3D rotation and scale.
///
[Serializable]
[StructLayout(LayoutKind.Sequential)]
@@ -254,7 +254,111 @@ namespace OpenTK
}
#endregion
-
+
+ ///
+ /// Returns a normalised copy of this instance.
+ ///
+ public Matrix3 Normalized()
+ {
+ Matrix3 m = this;
+ m.Normalize();
+ return m;
+ }
+
+ ///
+ /// Divides each element in the Matrix by the .
+ ///
+ public void Normalize()
+ {
+ var determinant = this.Determinant;
+ Row0 /= determinant;
+ Row1 /= determinant;
+ Row2 /= determinant;
+ }
+
+ ///
+ /// Returns an inverted copy of this instance.
+ ///
+ public Matrix3 Inverted()
+ {
+ Matrix3 m = this;
+ if (m.Determinant != 0)
+ m.Invert();
+ return m;
+ }
+
+ ///
+ /// Returns the scale component of this instance.
+ ///
+ public Vector3 ExtractScale() { return new Vector3(Row0.Length, Row1.Length, Row2.Length); }
+
+ ///
+ /// Returns the rotation component of this instance. Quite slow.
+ ///
+ /// Whether the method should row-normalise (i.e. remove scale from) the Matrix. Pass false if you know it's already normalised.
+ public Quaternion ExtractRotation(bool row_normalise = true)
+ {
+ var row0 = Row0;
+ var row1 = Row1;
+ var row2 = Row2;
+
+ if (row_normalise)
+ {
+ row0 = row0.Normalized();
+ row1 = row1.Normalized();
+ row2 = row2.Normalized();
+ }
+
+ // code below adapted from Blender
+
+ Quaternion q = new Quaternion();
+ double trace = 0.25 * (row0[0] + row1[1] + row2[2] + 1.0);
+
+ if (trace > 0)
+ {
+ double sq = Math.Sqrt(trace);
+
+ q.W = (float)sq;
+ sq = 1.0 / (4.0 * sq);
+ q.X = (float)((row1[2] - row2[1]) * sq);
+ q.Y = (float)((row2[0] - row0[2]) * sq);
+ q.Z = (float)((row0[1] - row1[0]) * sq);
+ }
+ else if (row0[0] > row1[1] && row0[0] > row2[2])
+ {
+ double sq = 2.0 * Math.Sqrt(1.0 + row0[0] - row1[1] - row2[2]);
+
+ q.X = (float)(0.25 * sq);
+ sq = 1.0 / sq;
+ q.W = (float)((row2[1] - row1[2]) * sq);
+ q.Y = (float)((row1[0] + row0[1]) * sq);
+ q.Z = (float)((row2[0] + row0[2]) * sq);
+ }
+ else if (row1[1] > row2[2])
+ {
+ double sq = 2.0 * Math.Sqrt(1.0 + row1[1] - row0[0] - row2[2]);
+
+ q.Y = (float)(0.25 * sq);
+ sq = 1.0 / sq;
+ q.W = (float)((row2[0] - row0[2]) * sq);
+ q.X = (float)((row1[0] + row0[1]) * sq);
+ q.Z = (float)((row2[1] + row1[2]) * sq);
+ }
+ else
+ {
+ double sq = 2.0 * Math.Sqrt(1.0 + row2[2] - row0[0] - row1[1]);
+
+ q.Z = (float)(0.25 * sq);
+ sq = 1.0 / sq;
+ q.W = (float)((row1[0] - row0[1]) * sq);
+ q.X = (float)((row2[0] + row0[2]) * sq);
+ q.Y = (float)((row2[1] + row1[2]) * sq);
+ }
+
+ q.Normalize();
+ return q;
+ }
+
#endregion
#region Static
diff --git a/Source/OpenTK/Math/Matrix3d.cs b/Source/OpenTK/Math/Matrix3d.cs
index 7a717666..d98da9c9 100644
--- a/Source/OpenTK/Math/Matrix3d.cs
+++ b/Source/OpenTK/Math/Matrix3d.cs
@@ -28,7 +28,7 @@ using System.Runtime.InteropServices;
namespace OpenTK
{
///
- /// Represents a 3x3 Matrix
+ /// Represents a 3x3 matrix containing 3D rotation and scale with double-precision components.
///
[Serializable]
[StructLayout(LayoutKind.Sequential)]
@@ -250,7 +250,111 @@ namespace OpenTK
}
#endregion
-
+
+ ///
+ /// Returns a normalised copy of this instance.
+ ///
+ public Matrix3d Normalized()
+ {
+ Matrix3d m = this;
+ m.Normalize();
+ return m;
+ }
+
+ ///
+ /// Divides each element in the Matrix by the .
+ ///
+ public void Normalize()
+ {
+ var determinant = this.Determinant;
+ Row0 /= determinant;
+ Row1 /= determinant;
+ Row2 /= determinant;
+ }
+
+ ///
+ /// Returns an inverted copy of this instance.
+ ///
+ public Matrix3d Inverted()
+ {
+ Matrix3d m = this;
+ if (m.Determinant != 0)
+ m.Invert();
+ return m;
+ }
+
+ ///
+ /// Returns the scale component of this instance.
+ ///
+ public Vector3d ExtractScale() { return new Vector3d(Row0.Length, Row1.Length, Row2.Length); }
+
+ ///
+ /// Returns the rotation component of this instance. Quite slow.
+ ///
+ /// Whether the method should row-normalise (i.e. remove scale from) the Matrix. Pass false if you know it's already normalised.
+ public Quaterniond ExtractRotation(bool row_normalise = true)
+ {
+ var row0 = Row0;
+ var row1 = Row1;
+ var row2 = Row2;
+
+ if (row_normalise)
+ {
+ row0 = row0.Normalized();
+ row1 = row1.Normalized();
+ row2 = row2.Normalized();
+ }
+
+ // code below adapted from Blender
+
+ Quaterniond q = new Quaterniond();
+ double trace = 0.25 * (row0[0] + row1[1] + row2[2] + 1.0);
+
+ if (trace > 0)
+ {
+ double sq = Math.Sqrt(trace);
+
+ q.W = sq;
+ sq = 1.0 / (4.0 * sq);
+ q.X = (row1[2] - row2[1]) * sq;
+ q.Y = (row2[0] - row0[2]) * sq;
+ q.Z = (row0[1] - row1[0]) * sq;
+ }
+ else if (row0[0] > row1[1] && row0[0] > row2[2])
+ {
+ double sq = 2.0 * Math.Sqrt(1.0 + row0[0] - row1[1] - row2[2]);
+
+ q.X = 0.25 * sq;
+ sq = 1.0 / sq;
+ q.W = (row2[1] - row1[2]) * sq;
+ q.Y = (row1[0] + row0[1]) * sq;
+ q.Z = (row2[0] + row0[2]) * sq;
+ }
+ else if (row1[1] > row2[2])
+ {
+ double sq = 2.0 * Math.Sqrt(1.0 + row1[1] - row0[0] - row2[2]);
+
+ q.Y = 0.25 * sq;
+ sq = 1.0 / sq;
+ q.W = (row2[0] - row0[2]) * sq;
+ q.X = (row1[0] + row0[1]) * sq;
+ q.Z = (row2[1] + row1[2]) * sq;
+ }
+ else
+ {
+ double sq = 2.0 * Math.Sqrt(1.0 + row2[2] - row0[0] - row1[1]);
+
+ q.Z = 0.25 * sq;
+ sq = 1.0 / sq;
+ q.W = (row1[0] - row0[1]) * sq;
+ q.X = (row2[0] + row0[2]) * sq;
+ q.Y = (row2[1] + row1[2]) * sq;
+ }
+
+ q.Normalize();
+ return q;
+ }
+
#endregion
#region Static
diff --git a/Source/OpenTK/Math/Matrix4.cs b/Source/OpenTK/Math/Matrix4.cs
index 8bd12347..756c1e22 100644
--- a/Source/OpenTK/Math/Matrix4.cs
+++ b/Source/OpenTK/Math/Matrix4.cs
@@ -28,8 +28,9 @@ using System.Runtime.InteropServices;
namespace OpenTK
{
///
- /// Represents a 4x4 Matrix
+ /// Represents a 4x4 matrix containing 3D rotation, scale, transform, and projection.
///
+ ///
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Matrix4 : IEquatable
@@ -259,7 +260,7 @@ namespace OpenTK
/// Gets or sets the value at row 4, column 4 of this instance.
///
public float M44 { get { return Row3.W; } set { Row3.W = value; } }
-
+
#endregion
#region Indexers
@@ -315,6 +316,116 @@ namespace OpenTK
#endregion
+ ///
+ /// Returns a normalised copy of this instance.
+ ///
+ public Matrix4 Normalized()
+ {
+ Matrix4 m = this;
+ m.Normalize();
+ return m;
+ }
+
+ ///
+ /// Divides each element in the Matrix by the .
+ ///
+ public void Normalize()
+ {
+ var determinant = this.Determinant;
+ Row0 /= determinant;
+ Row1 /= determinant;
+ Row2 /= determinant;
+ Row3 /= determinant;
+ }
+
+ ///
+ /// Returns an inverted copy of this instance.
+ ///
+ public Matrix4 Inverted()
+ {
+ Matrix4 m = this;
+ if (m.Determinant != 0)
+ m.Invert();
+ return m;
+ }
+
+ ///
+ /// Returns the translation component of this instance.
+ ///
+ public Vector3 ExtractTranslation() { return Row3.Xyz; }
+
+ ///
+ /// Returns the scale component of this instance.
+ ///
+ public Vector3 ExtractScale() { return new Vector3(Row0.Length, Row1.Length, Row2.Length); }
+
+ ///
+ /// Returns the rotation component of this instance. Quite slow.
+ ///
+ /// Whether the method should row-normalise (i.e. remove scale from) the Matrix. Pass false if you know it's already normalised.
+ public Quaternion ExtractRotation(bool row_normalise = true)
+ {
+ var row0 = Row0.Xyz;
+ var row1 = Row1.Xyz;
+ var row2 = Row2.Xyz;
+
+ if (row_normalise)
+ {
+ row0 = row0.Normalized();
+ row1 = row1.Normalized();
+ row2 = row2.Normalized();
+ }
+
+ // code below adapted from Blender
+
+ Quaternion q = new Quaternion();
+ double trace = 0.25 * (row0[0] + row1[1] + row2[2] + 1.0);
+
+ if (trace > 0)
+ {
+ double sq = Math.Sqrt(trace);
+
+ q.W = (float)sq;
+ sq = 1.0 / (4.0 * sq);
+ q.X = (float)((row1[2] - row2[1]) * sq);
+ q.Y = (float)((row2[0] - row0[2]) * sq);
+ q.Z = (float)((row0[1] - row1[0]) * sq);
+ }
+ else if (row0[0] > row1[1] && row0[0] > row2[2])
+ {
+ double sq = 2.0 * Math.Sqrt(1.0 + row0[0] - row1[1] - row2[2]);
+
+ q.X = (float)(0.25 * sq);
+ sq = 1.0 / sq;
+ q.W = (float)((row2[1] - row1[2]) * sq);
+ q.Y = (float)((row1[0] + row0[1]) * sq);
+ q.Z = (float)((row2[0] + row0[2]) * sq);
+ }
+ else if (row1[1] > row2[2])
+ {
+ double sq = 2.0 * Math.Sqrt(1.0 + row1[1] - row0[0] - row2[2]);
+
+ q.Y = (float)(0.25 * sq);
+ sq = 1.0 / sq;
+ q.W = (float)((row2[0] - row0[2]) * sq);
+ q.X = (float)((row1[0] + row0[1]) * sq);
+ q.Z = (float)((row2[1] + row1[2]) * sq);
+ }
+ else
+ {
+ double sq = 2.0 * Math.Sqrt(1.0 + row2[2] - row0[0] - row1[1]);
+
+ q.Z = (float)(0.25 * sq);
+ sq = 1.0 / sq;
+ q.W = (float)((row1[0] - row0[1]) * sq);
+ q.X = (float)((row2[0] + row0[2]) * sq);
+ q.Y = (float)((row2[1] + row1[2]) * sq);
+ }
+
+ q.Normalize();
+ return q;
+ }
+
#endregion
#region Static
diff --git a/Source/OpenTK/Math/Matrix4d.cs b/Source/OpenTK/Math/Matrix4d.cs
index 39059169..108c9ff5 100644
--- a/Source/OpenTK/Math/Matrix4d.cs
+++ b/Source/OpenTK/Math/Matrix4d.cs
@@ -28,8 +28,9 @@ using System.Runtime.InteropServices;
namespace OpenTK
{
///
- /// Represents a 4x4 Matrix with double-precision components.
+ /// Represents a 4x4 matrix containing 3D rotation, scale, transform, and projection with double-precision components.
///
+ ///
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Matrix4d : IEquatable
@@ -298,6 +299,116 @@ namespace OpenTK
#endregion
+ ///
+ /// Returns a normalised copy of this instance.
+ ///
+ public Matrix4d Normalized()
+ {
+ Matrix4d m = this;
+ m.Normalize();
+ return m;
+ }
+
+ ///
+ /// Divides each element in the Matrix by the .
+ ///
+ public void Normalize()
+ {
+ var determinant = this.Determinant;
+ Row0 /= determinant;
+ Row1 /= determinant;
+ Row2 /= determinant;
+ Row3 /= determinant;
+ }
+
+ ///
+ /// Returns an inverted copy of this instance.
+ ///
+ public Matrix4d Inverted()
+ {
+ Matrix4d m = this;
+ if (m.Determinant != 0)
+ m.Invert();
+ return m;
+ }
+
+ ///
+ /// Returns the translation component of this instance.
+ ///
+ public Vector3d ExtractTranslation() { return Row3.Xyz; }
+
+ ///
+ /// Returns the scale component of this instance.
+ ///
+ public Vector3d ExtractScale() { return new Vector3d(Row0.Length, Row1.Length, Row2.Length); }
+
+ ///
+ /// Returns the rotation component of this instance. Quite slow.
+ ///
+ /// Whether the method should row-normalise (i.e. remove scale from) the Matrix. Pass false if you know it's already normalised.
+ public Quaterniond ExtractRotation(bool row_normalise = true)
+ {
+ var row0 = Row0.Xyz;
+ var row1 = Row1.Xyz;
+ var row2 = Row2.Xyz;
+
+ if (row_normalise)
+ {
+ row0 = row0.Normalized();
+ row1 = row1.Normalized();
+ row2 = row2.Normalized();
+ }
+
+ // code below adapted from Blender
+
+ Quaterniond q = new Quaterniond();
+ double trace = 0.25 * (row0[0] + row1[1] + row2[2] + 1.0);
+
+ if (trace > 0)
+ {
+ double sq = Math.Sqrt(trace);
+
+ q.W = sq;
+ sq = 1.0 / (4.0 * sq);
+ q.X = (row1[2] - row2[1]) * sq;
+ q.Y = (row2[0] - row0[2]) * sq;
+ q.Z = (row0[1] - row1[0]) * sq;
+ }
+ else if (row0[0] > row1[1] && row0[0] > row2[2])
+ {
+ double sq = 2.0 * Math.Sqrt(1.0 + row0[0] - row1[1] - row2[2]);
+
+ q.X = 0.25 * sq;
+ sq = 1.0 / sq;
+ q.W = (row2[1] - row1[2]) * sq;
+ q.Y = (row1[0] + row0[1]) * sq;
+ q.Z = (row2[0] + row0[2]) * sq;
+ }
+ else if (row1[1] > row2[2])
+ {
+ double sq = 2.0 * Math.Sqrt(1.0 + row1[1] - row0[0] - row2[2]);
+
+ q.Y = 0.25 * sq;
+ sq = 1.0 / sq;
+ q.W = (row2[0] - row0[2]) * sq;
+ q.X = (row1[0] + row0[1]) * sq;
+ q.Z = (row2[1] + row1[2]) * sq;
+ }
+ else
+ {
+ double sq = 2.0 * Math.Sqrt(1.0 + row2[2] - row0[0] - row1[1]);
+
+ q.Z = 0.25 * sq;
+ sq = 1.0 / sq;
+ q.W = (row1[0] - row0[1]) * sq;
+ q.X = (row2[0] + row0[2]) * sq;
+ q.Y = (row2[1] + row1[2]) * sq;
+ }
+
+ q.Normalize();
+ return q;
+ }
+
#endregion
#region Static
diff --git a/Source/OpenTK/Math/Quaternion.cs b/Source/OpenTK/Math/Quaternion.cs
index 8ee0fc01..57f93bb9 100644
--- a/Source/OpenTK/Math/Quaternion.cs
+++ b/Source/OpenTK/Math/Quaternion.cs
@@ -189,6 +189,34 @@ namespace OpenTK
#endregion
+ ///
+ /// Returns a copy of the Quaternion scaled to unit length.
+ ///
+ public Quaternion Normalized()
+ {
+ Quaternion q = this;
+ q.Normalize();
+ return q;
+ }
+
+ ///
+ /// Reverses the rotation angle of this Quaterniond.
+ ///
+ public void Invert()
+ {
+ W = -W;
+ }
+
+ ///
+ /// Returns a copy of this Quaterniond with its rotation angle reversed.
+ ///
+ public Quaternion Inverted()
+ {
+ var q = this;
+ q.Invert();
+ return q;
+ }
+
#region public void Normalize()
///
@@ -206,7 +234,7 @@ namespace OpenTK
#region public void Conjugate()
///
- /// Convert this quaternion to its conjugate
+ /// Inverts the Vector3 component of this Quaternion.
///
public void Conjugate()
{
diff --git a/Source/OpenTK/Math/Quaterniond.cs b/Source/OpenTK/Math/Quaterniond.cs
index 46aec949..8d384312 100644
--- a/Source/OpenTK/Math/Quaterniond.cs
+++ b/Source/OpenTK/Math/Quaterniond.cs
@@ -189,6 +189,34 @@ namespace OpenTK
#endregion
+ ///
+ /// Returns a copy of the Quaterniond scaled to unit length.
+ ///
+ public Quaterniond Normalized()
+ {
+ Quaterniond q = this;
+ q.Normalize();
+ return q;
+ }
+
+ ///
+ /// Reverses the rotation angle of this Quaterniond.
+ ///
+ public void Invert()
+ {
+ W = -W;
+ }
+
+ ///
+ /// Returns a copy of this Quaterniond with its rotation angle reversed.
+ ///
+ public Quaterniond Inverted()
+ {
+ var q = this;
+ q.Invert();
+ return q;
+ }
+
#region public void Normalize()
///
@@ -206,7 +234,7 @@ namespace OpenTK
#region public void Conjugate()
///
- /// Convert this Quaterniond to its conjugate
+ /// Inverts the Vector3d component of this Quaterniond.
///
public void Conjugate()
{
diff --git a/Source/OpenTK/Math/Vector2.cs b/Source/OpenTK/Math/Vector2.cs
index a5c0afd9..8714e354 100644
--- a/Source/OpenTK/Math/Vector2.cs
+++ b/Source/OpenTK/Math/Vector2.cs
@@ -289,6 +289,16 @@ namespace OpenTK
#endregion
+ ///
+ /// Returns a copy of the Vector2 scaled to unit length.
+ ///
+ ///
+ public Vector2 Normalized()
+ {
+ Vector2 v = this;
+ v.Normalize();
+ return v;
+ }
#region public void Normalize()
///
diff --git a/Source/OpenTK/Math/Vector2d.cs b/Source/OpenTK/Math/Vector2d.cs
index 82c89722..c6f50ab7 100644
--- a/Source/OpenTK/Math/Vector2d.cs
+++ b/Source/OpenTK/Math/Vector2d.cs
@@ -249,6 +249,17 @@ namespace OpenTK
#endregion
+ ///
+ /// Returns a copy of the Vector2d scaled to unit length.
+ ///
+ ///
+ public Vector2d Normalized()
+ {
+ Vector2d v = this;
+ v.Normalize();
+ return v;
+ }
+
#region public void Normalize()
///
diff --git a/Source/OpenTK/Math/Vector3.cs b/Source/OpenTK/Math/Vector3.cs
index 9953d8d9..4fe1a7bc 100644
--- a/Source/OpenTK/Math/Vector3.cs
+++ b/Source/OpenTK/Math/Vector3.cs
@@ -277,6 +277,16 @@ namespace OpenTK
#endregion
+ ///
+ /// Returns a copy of the Vector3 scaled to unit length.
+ ///
+ public Vector3 Normalized()
+ {
+ Vector3 v = this;
+ v.Normalize();
+ return v;
+ }
+
#region public void Normalize()
///
diff --git a/Source/OpenTK/Math/Vector3d.cs b/Source/OpenTK/Math/Vector3d.cs
index e00a04b6..3b67ce44 100644
--- a/Source/OpenTK/Math/Vector3d.cs
+++ b/Source/OpenTK/Math/Vector3d.cs
@@ -275,6 +275,17 @@ namespace OpenTK
#endregion
+ ///
+ /// Returns a copy of the Vector3d scaled to unit length.
+ ///
+ ///
+ public Vector3d Normalized()
+ {
+ Vector3d v = this;
+ v.Normalize();
+ return v;
+ }
+
#region public void Normalize()
///
diff --git a/Source/OpenTK/Math/Vector4.cs b/Source/OpenTK/Math/Vector4.cs
index 40b23bfb..198066f9 100644
--- a/Source/OpenTK/Math/Vector4.cs
+++ b/Source/OpenTK/Math/Vector4.cs
@@ -343,6 +343,16 @@ namespace OpenTK
#endregion
+ ///
+ /// Returns a copy of the Vector4 scaled to unit length.
+ ///
+ public Vector4 Normalized()
+ {
+ Vector4 v = this;
+ v.Normalize();
+ return v;
+ }
+
#region public void Normalize()
///
diff --git a/Source/OpenTK/Math/Vector4d.cs b/Source/OpenTK/Math/Vector4d.cs
index 0480460f..236d6db0 100644
--- a/Source/OpenTK/Math/Vector4d.cs
+++ b/Source/OpenTK/Math/Vector4d.cs
@@ -340,6 +340,16 @@ namespace OpenTK
#endregion
+ ///
+ /// Returns a copy of the Vector4d scaled to unit length.
+ ///
+ public Vector4d Normalized()
+ {
+ Vector4d v = this;
+ v.Normalize();
+ return v;
+ }
+
#region public void Normalize()
///
diff --git a/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs b/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs
index 01696252..742847f9 100644
--- a/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs
+++ b/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs
@@ -368,6 +368,7 @@ namespace OpenTK.Platform.MacOS
break;
}
+ OpenTK.Input.Key key;
switch (evt.KeyboardEventKind)
{
case KeyboardEventKind.RawKeyRepeat:
@@ -376,25 +377,15 @@ namespace OpenTK.Platform.MacOS
break;
case KeyboardEventKind.RawKeyDown:
- {
- OpenTK.Input.Key key;
- if (Keymap.TryGetValue(code, out key))
- {
- InputDriver.Keyboard[0][key] = true;
- OnKeyPress(mKeyPressArgs);
- }
+ Keymap.TryGetValue(code, out key);
+ InputDriver.Keyboard[0].SetKey(key, (uint)code, true);
+ OnKeyPress(mKeyPressArgs);
return OSStatus.NoError;
- }
case KeyboardEventKind.RawKeyUp:
- {
- OpenTK.Input.Key key;
- if (Keymap.TryGetValue(code, out key))
- {
- InputDriver.Keyboard[0][key] = false;
- }
+ Keymap.TryGetValue(code, out key);
+ InputDriver.Keyboard[0].SetKey(key, (uint)code, false);
return OSStatus.NoError;
- }
case KeyboardEventKind.RawKeyModifiersChanged:
ProcessModifierKey(inEvent);
@@ -614,21 +605,21 @@ namespace OpenTK.Platform.MacOS
Debug.Print("Modifiers Changed: {0}", modifiers);
Input.KeyboardDevice keyboard = InputDriver.Keyboard[0];
-
+
if (keyboard[OpenTK.Input.Key.AltLeft] ^ option)
- keyboard[OpenTK.Input.Key.AltLeft] = option;
+ keyboard.SetKey(OpenTK.Input.Key.AltLeft, (uint)MacOSKeyModifiers.Option, option);
if (keyboard[OpenTK.Input.Key.ShiftLeft] ^ shift)
- keyboard[OpenTK.Input.Key.ShiftLeft] = shift;
+ keyboard.SetKey(OpenTK.Input.Key.ShiftLeft, (uint)MacOSKeyModifiers.Shift, shift);
if (keyboard[OpenTK.Input.Key.WinLeft] ^ command)
- keyboard[OpenTK.Input.Key.WinLeft] = command;
+ keyboard.SetKey(OpenTK.Input.Key.WinLeft, (uint)MacOSKeyModifiers.Command, command);
if (keyboard[OpenTK.Input.Key.ControlLeft] ^ control)
- keyboard[OpenTK.Input.Key.ControlLeft] = control;
+ keyboard.SetKey(OpenTK.Input.Key.ControlLeft, (uint)MacOSKeyModifiers.Control, control);
if (keyboard[OpenTK.Input.Key.CapsLock] ^ caps)
- keyboard[OpenTK.Input.Key.CapsLock] = caps;
+ keyboard.SetKey(OpenTK.Input.Key.CapsLock, (uint)MacOSKeyModifiers.CapsLock, caps);
}
diff --git a/Source/OpenTK/Platform/MacOS/HIDInput.cs b/Source/OpenTK/Platform/MacOS/HIDInput.cs
index daa88f3f..c040ff6d 100755
--- a/Source/OpenTK/Platform/MacOS/HIDInput.cs
+++ b/Source/OpenTK/Platform/MacOS/HIDInput.cs
@@ -263,14 +263,12 @@ namespace OpenTK.Platform.MacOS
{
case HIDPage.GenericDesktop:
case HIDPage.KeyboardOrKeypad:
- int raw = (int) usage;
- if (raw >= RawKeyMap.Length)
+ if (usage >= RawKeyMap.Length)
{
- Debug.Print("[Warning] Key {0} not mapped.", raw);
+ Debug.Print("[Warning] Key {0} not mapped.", usage);
return state;
}
- Key key = RawKeyMap[raw];
- state[key] = v_int != 0;
+ state.SetKeyState(RawKeyMap[usage], (byte)usage, v_int != 0);
break;
}
diff --git a/Source/OpenTK/Platform/Windows/WMInput.cs b/Source/OpenTK/Platform/Windows/WMInput.cs
index f0fd2956..084f20fb 100644
--- a/Source/OpenTK/Platform/Windows/WMInput.cs
+++ b/Source/OpenTK/Platform/Windows/WMInput.cs
@@ -70,14 +70,12 @@ namespace OpenTK.Platform.Windows
void UpdateKeyboard()
{
- for (int i = 0; i < 256; i++)
+ for (byte i = 0; i < byte.MaxValue; i++)
{
- VirtualKeys key = (VirtualKeys)i;
- bool pressed = (Functions.GetAsyncKeyState(key) >> 8) != 0;
- if (KeyMap.ContainsKey(key))
- {
- keyboard[KeyMap[key]] = pressed;
- }
+ bool pressed = (Functions.GetAsyncKeyState((VirtualKeys)i) >> 8) != 0;
+ Key key;
+ KeyMap.TryGetValue((VirtualKeys)i,out key);
+ keyboard.SetKeyState(key, i, pressed);
}
}
diff --git a/Source/OpenTK/Platform/Windows/WinGLNative.cs b/Source/OpenTK/Platform/Windows/WinGLNative.cs
index 261cfacf..18cbd3dd 100644
--- a/Source/OpenTK/Platform/Windows/WinGLNative.cs
+++ b/Source/OpenTK/Platform/Windows/WinGLNative.cs
@@ -89,7 +89,13 @@ namespace OpenTK.Platform.Windows
IList keyboards = new List(1);
IList mice = new List(1);
const long ExtendedBit = 1 << 24; // Used to distinguish left and right control, alt and enter keys.
- static readonly uint ShiftRightScanCode = Functions.MapVirtualKey(VirtualKeys.RSHIFT, 0); // Used to distinguish left and right shift keys.
+
+ public static readonly uint ShiftLeftScanCode = Functions.MapVirtualKey(VirtualKeys.LSHIFT, 0);
+ public static readonly uint ShiftRightScanCode = Functions.MapVirtualKey(VirtualKeys.RSHIFT, 0);
+ public static readonly uint ControlLeftScanCode = Functions.MapVirtualKey(VirtualKeys.LCONTROL, 0);
+ public static readonly uint ControlRightScanCode = Functions.MapVirtualKey(VirtualKeys.RCONTROL, 0);
+ public static readonly uint AltLeftScanCode = Functions.MapVirtualKey(VirtualKeys.LMENU, 0);
+ public static readonly uint AltRightScanCode = Functions.MapVirtualKey(VirtualKeys.RMENU, 0);
KeyPressEventArgs key_press = new KeyPressEventArgs((char)0);
@@ -369,6 +375,8 @@ namespace OpenTK.Platform.Windows
// In this case, both keys will be reported as pressed.
bool extended = (lParam.ToInt64() & ExtendedBit) != 0;
+ uint scancode = (uint)((lParam.ToInt64() >> 16) & 0xFF);
+ Key key = Key.Unknown;
switch ((VirtualKeys)wParam)
{
case VirtualKeys.SHIFT:
@@ -382,55 +390,50 @@ namespace OpenTK.Platform.Windows
// Otherwise, the state of one key might be stuck to pressed.
if (ShiftRightScanCode != 0 && pressed)
{
- unchecked
- {
- if (((lParam.ToInt64() >> 16) & 0xFF) == ShiftRightScanCode)
- keyboard[Input.Key.ShiftRight] = pressed;
- else
- keyboard[Input.Key.ShiftLeft] = pressed;
- }
+ if (scancode == ShiftRightScanCode)
+ key = Input.Key.ShiftRight;
+ else
+ key = Input.Key.ShiftLeft;
}
else
{
// Windows 9x and NT4.0 or key release event.
- keyboard[Input.Key.ShiftLeft] = keyboard[Input.Key.ShiftRight] = pressed;
+ keyboard.SetKey(Input.Key.ShiftLeft, ShiftLeftScanCode, pressed);
+ keyboard.SetKey(Input.Key.ShiftRight, ShiftRightScanCode, pressed);
}
- return IntPtr.Zero;
+ break;
case VirtualKeys.CONTROL:
if (extended)
- keyboard[Input.Key.ControlRight] = pressed;
+ key = Input.Key.ControlRight;
else
- keyboard[Input.Key.ControlLeft] = pressed;
- return IntPtr.Zero;
+ key = Input.Key.ControlLeft;
+ break;
case VirtualKeys.MENU:
if (extended)
- keyboard[Input.Key.AltRight] = pressed;
+ key = Input.Key.AltRight;
else
- keyboard[Input.Key.AltLeft] = pressed;
- return IntPtr.Zero;
+ key = Input.Key.AltLeft;
+ break;
case VirtualKeys.RETURN:
if (extended)
- keyboard[Key.KeypadEnter] = pressed;
+ key = Key.KeypadEnter;
else
- keyboard[Key.Enter] = pressed;
- return IntPtr.Zero;
+ key = Key.Enter;
+ break;
default:
if (!KeyMap.ContainsKey((VirtualKeys)wParam))
- {
Debug.Print("Virtual key {0} ({1}) not mapped.", (VirtualKeys)wParam, (long)lParam);
- break;
- }
else
- {
- keyboard[KeyMap[(VirtualKeys)wParam]] = pressed;
- }
- return IntPtr.Zero;
+ key = KeyMap[(VirtualKeys)wParam];
+ break;
}
- break;
+
+ keyboard.SetKey(key, scancode, pressed);
+ return IntPtr.Zero;
case WindowMessage.SYSCHAR:
return IntPtr.Zero;
diff --git a/Source/OpenTK/Platform/Windows/WinRawKeyboard.cs b/Source/OpenTK/Platform/Windows/WinRawKeyboard.cs
index 32faae1c..f439a361 100644
--- a/Source/OpenTK/Platform/Windows/WinRawKeyboard.cs
+++ b/Source/OpenTK/Platform/Windows/WinRawKeyboard.cs
@@ -180,31 +180,30 @@ namespace OpenTK.Platform.Windows
switch (rin.Data.Keyboard.VKey)
{
case VirtualKeys.SHIFT:
- keyboard[Input.Key.ShiftLeft] = keyboard[Input.Key.ShiftRight] = pressed;
+ keyboard.SetKeyState(Key.ShiftLeft, (byte)WinGLNative.ShiftLeftScanCode, pressed);
+ keyboard.SetKeyState(Key.ShiftRight, (byte)WinGLNative.ShiftRightScanCode, pressed);
processed = true;
break;
case VirtualKeys.CONTROL:
- keyboard[Input.Key.ControlLeft] = keyboard[Input.Key.ControlRight] = pressed;
+ keyboard.SetKeyState(Key.ControlLeft, (byte)WinGLNative.ControlLeftScanCode, pressed);
+ keyboard.SetKeyState(Key.ControlRight, (byte)WinGLNative.ControlRightScanCode, pressed);
processed = true;
break;
case VirtualKeys.MENU:
- keyboard[Input.Key.AltLeft] = keyboard[Input.Key.AltRight] = pressed;
+ keyboard.SetKeyState(Key.AltLeft, (byte)WinGLNative.AltLeftScanCode, pressed);
+ keyboard.SetKeyState(Key.AltRight, (byte)WinGLNative.AltRightScanCode, pressed);
processed = true;
break;
default:
- if (!KeyMap.ContainsKey(rin.Data.Keyboard.VKey))
- {
- Debug.Print("Virtual key {0} ({1}) not mapped.",
- rin.Data.Keyboard.VKey, (int)rin.Data.Keyboard.VKey);
- }
- else
- {
- keyboard[KeyMap[rin.Data.Keyboard.VKey]] = pressed;
- processed = true;
- }
+ Key key;
+ KeyMap.TryGetValue(rin.Data.Keyboard.VKey, out key);
+ if (key == Key.Unknown)
+ Debug.Print("Virtual key {0} ({1}) not mapped.", rin.Data.Keyboard.VKey, (int)rin.Data.Keyboard.VKey);
+ keyboard.SetKeyState(key, BitConverter.GetBytes(rin.Data.Keyboard.MakeCode)[0], pressed);
+ processed = true;
break;
}
diff --git a/Source/OpenTK/Platform/X11/X11Input.cs b/Source/OpenTK/Platform/X11/X11Input.cs
index 10978019..a9193a40 100644
--- a/Source/OpenTK/Platform/X11/X11Input.cs
+++ b/Source/OpenTK/Platform/X11/X11Input.cs
@@ -157,20 +157,22 @@ namespace OpenTK.Platform.X11
case XEventName.KeyPress:
case XEventName.KeyRelease:
bool pressed = e.type == XEventName.KeyPress;
+ XKey keysym = (XKey)API.LookupKeysym(ref e.KeyEvent, 0);
+ XKey keysym2 = (XKey)API.LookupKeysym(ref e.KeyEvent, 1);
+ Key key = Key.Unknown;
- IntPtr keysym = API.LookupKeysym(ref e.KeyEvent, 0);
- IntPtr keysym2 = API.LookupKeysym(ref e.KeyEvent, 1);
-
- if (keymap.ContainsKey((XKey)keysym))
- keyboard[keymap[(XKey)keysym]] = pressed;
- else if (keymap.ContainsKey((XKey)keysym2))
- keyboard[keymap[(XKey)keysym2]] = pressed;
+ if (keymap.ContainsKey(keysym))
+ key = keymap[keysym];
+ else if (keymap.ContainsKey(keysym2))
+ key = keymap[keysym2];
else
Debug.Print("KeyCode {0} (Keysym: {1}, {2}) not mapped.", e.KeyEvent.keycode, (XKey)keysym, (XKey)keysym2);
+
+ keyboard.SetKey(key, (uint)e.KeyEvent.keycode, pressed);
break;
case XEventName.ButtonPress:
- if (e.ButtonEvent.button == 1) mouse[OpenTK.Input.MouseButton.Left] = true;
+ if (e.ButtonEvent.button == 1) mouse[OpenTK.Input.MouseButton.Left] = true;
else if (e.ButtonEvent.button == 2) mouse[OpenTK.Input.MouseButton.Middle] = true;
else if (e.ButtonEvent.button == 3) mouse[OpenTK.Input.MouseButton.Right] = true;
else if (e.ButtonEvent.button == 4) mouse.Wheel++;
@@ -190,7 +192,7 @@ namespace OpenTK.Platform.X11
break;
case XEventName.ButtonRelease:
- if (e.ButtonEvent.button == 1) mouse[OpenTK.Input.MouseButton.Left] = false;
+ if (e.ButtonEvent.button == 1) mouse[OpenTK.Input.MouseButton.Left] = false;
else if (e.ButtonEvent.button == 2) mouse[OpenTK.Input.MouseButton.Middle] = false;
else if (e.ButtonEvent.button == 3) mouse[OpenTK.Input.MouseButton.Right] = false;
else if (e.ButtonEvent.button == 6) mouse[OpenTK.Input.MouseButton.Button1] = false;