public bool TryPick(int x, int y, out object picked, out int faceID, out Vector3 worldPos)
{
// Save old attributes
GL.PushAttrib(AttribMask.AllAttribBits);
// Disable some attributes to make the objects flat / solid color when they are drawn
GL.Disable(EnableCap.Fog);
GL.Disable(EnableCap.Texture2D);
GL.Disable(EnableCap.Dither);
GL.Disable(EnableCap.Lighting);
GL.Disable(EnableCap.LineStipple);
GL.Disable(EnableCap.PolygonStipple);
GL.Disable(EnableCap.CullFace);
GL.Disable(EnableCap.Blend);
GL.Disable(EnableCap.AlphaTest);
Render(true);
byte[] color = new byte[4];
GL.ReadPixels(x, glControl.Height - y, 1, 1, OpenTK.Graphics.OpenGL.PixelFormat.Rgba, PixelType.UnsignedByte, color);
float depth = 0f;
GL.ReadPixels(x, glControl.Height - y, 1, 1, OpenTK.Graphics.OpenGL.PixelFormat.DepthComponent, PixelType.Float, ref depth);
OpenTK.Vector3 worldPosTK = OpenTK.Vector3.Zero;
Math3D.GluUnProject(x, glControl.Height - y, depth, ModelMatrix, ProjectionMatrix, Viewport, out worldPosTK);
worldPos = RHelp.OMVVector3(worldPosTK);
GL.PopAttrib();
int primID = Utils.BytesToUInt16(color, 0);
faceID = color[2];
picked = null;
if (color[3] == 253) // Terrain
{
int vertexIndex = Utils.BytesToInt(new byte[] { color[0], color[1], color[2], 0 });
ColorVertex cv;
if (terrain.TryGetVertex(vertexIndex, out cv))
{
picked = cv.Vertex.Position;
return true;
}
}
else if (color[3] == 254) // Avatar
{
lock (VisibleAvatars)
{
foreach (var avatar in VisibleAvatars)
{
for (int i = 0; i < avatar.data.Length; i++)
{
var face = avatar.data[i];
if (face != null && face.PickingID == primID)
{
picked = avatar;
break;
}
}
}
}
if (picked != null)
{
return true;
}
}
else if (color[3] == 255) // Prim
{
lock (SortedObjects)
{
foreach (SceneObject obj in SortedObjects)
{
if (!(obj is RenderPrimitive)) continue;
RenderPrimitive prim = (RenderPrimitive)obj;
if (obj.BasePrim.LocalID == 0)
continue;
foreach (var face in prim.Faces)
{
if (face.UserData == null) continue;
if (((FaceData)face.UserData).PickingID == primID)
{
picked = prim;
break;
}
}
if (picked != null) break;
}
}
}
return picked != null;
}