Skip to content

Instantly share code, notes, and snippets.

@sixman9
Created March 15, 2011 17:35
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sixman9/871099 to your computer and use it in GitHub Desktop.
Save sixman9/871099 to your computer and use it in GitHub Desktop.
An implementation of OpenGL's glu.project and glu.unProject, suitable for OpenTK (when modded)
//Found at www.opentk.com/node/1892
Projects a 3D vector from object space into screen space. Reference page contains links to related code samples.
Parameters
source
The vector to project.
projection
The projection matrix.
view
The view matrix.
world
The world matrix.
public Vector3 Project(Vector3 source, Matrix projection, Matrix view, Matrix world)
{
Matrix matrix = Matrix.Multiply(Matrix.Multiply(world, view), projection);
Vector3 vector = Vector3.Transform(source, matrix);
float a = (((source.X * matrix.M14) + (source.Y * matrix.M24)) + (source.Z * matrix.M34)) + matrix.M44;
if (!WithinEpsilon(a, 1f))
{
vector = (Vector3) (vector / a);
}
vector.X = (((vector.X + 1f) * 0.5f) * this.Width) + this.X;
vector.Y = (((-vector.Y + 1f) * 0.5f) * this.Height) + this.Y;
vector.Z = (vector.Z * (this.MaxDepth - this.MinDepth)) + this.MinDepth;
return vector;
}
Converts a screen space point into a corresponding point in world space.
Parameters
source
The vector to project.
projection
The projection matrix.
view
The view matrix.
world
The world matrix.
public Vector3 Unproject(Vector3 source, Matrix projection, Matrix view, Matrix world)
{
Matrix matrix = Matrix.Invert(Matrix.Multiply(Matrix.Multiply(world, view), projection));
source.X = (((source.X - this.X) / ((float) this.Width)) * 2f) - 1f;
source.Y = -((((source.Y - this.Y) / ((float) this.Height)) * 2f) - 1f);
source.Z = (source.Z - this.MinDepth) / (this.MaxDepth - this.MinDepth);
Vector3 vector = Vector3.Transform(source, matrix);
float a = (((source.X * matrix.M14) + (source.Y * matrix.M24)) + (source.Z * matrix.M34)) + matrix.M44;
if (!WithinEpsilon(a, 1f))
{
vector = (Vector3) (vector / a);
}
return vector;
}
private static bool WithinEpsilon(float a, float b)
{
float num = a - b;
return ((-1.401298E-45f <= num) && (num <= float.Epsilon));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment