public static PickingGeometryTypes ToFlags(this GeometryType type) { PickingGeometryTypes result = 0; switch (type) { case GeometryType.Point: result = PickingGeometryTypes.Point; break; case GeometryType.Line: result = PickingGeometryTypes.Line; break; case GeometryType.Triangle: result = PickingGeometryTypes.Triangle; break; case GeometryType.Quad: result = PickingGeometryTypes.Quad; break; case GeometryType.Polygon: result = PickingGeometryTypes.Polygon; break; default: throw new NotDealWithNewEnumItemException(typeof(GeometryType)); } return(result); }
/// <summary> /// /// </summary> /// <param name="pickingType"></param> /// <param name="typeOfMode"></param> /// <returns></returns> public static bool Contains(this PickingGeometryTypes pickingType, GeometryType typeOfMode) { bool result = false; switch (typeOfMode) { case GeometryType.Point: result = (pickingType & PickingGeometryTypes.Point) == PickingGeometryTypes.Point; break; case GeometryType.Line: result = (pickingType & PickingGeometryTypes.Line) == PickingGeometryTypes.Line; break; case GeometryType.Triangle: result = (pickingType & faceTypes) != noType; break; case GeometryType.Quad: result = (pickingType & faceTypes) != noType; break; case GeometryType.Polygon: result = (pickingType & faceTypes) != noType; break; default: throw new NotDealWithNewEnumItemException(typeof(GeometryType)); } return(result); }
public static PickingGeometryTypes ToFlags(this GeometryType type) { PickingGeometryTypes result = 0; switch (type) { case GeometryType.Point: result = PickingGeometryTypes.Point; break; case GeometryType.Line: result = PickingGeometryTypes.Line; break; case GeometryType.Triangle: result = PickingGeometryTypes.Triangle; break; case GeometryType.Quad: result = PickingGeometryTypes.Quad; break; case GeometryType.Polygon: result = PickingGeometryTypes.Polygon; break; default: throw new Exception("not expected PickingGeometryType!"); } return(result); }
/// <summary> /// Pick geometry at specified positon. /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="geometryTypes"></param> /// <param name="width"></param> /// <param name="height"></param> /// <returns></returns> public PickedGeometry Pick(int x, int y, PickingGeometryTypes geometryTypes, int width, int height) { if (x < 0 || width <= x) { return(null); } if (y < 0 || height <= y) { return(null); } if (geometryTypes == 0) { return(null); } PickedGeometry pickedGeometry = null; Framebuffer framebuffer = GetPickingFramebuffer(width, height); framebuffer.Bind(); { const float one = 1.0f; GL.Instance.ClearColor(one, one, one, one); GL.Instance.Clear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT); var arg = new PickingEventArgs(this.Scene, x, y, geometryTypes); this.RenderForPicking(this.Scene.RootNode, arg); bool dump = false; if (dump) { var final = new Bitmap(width, height); var data = final.LockBits(new Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb); //glGetTexImage((uint)texture.Target, 0, GL_BGRA, GL_UNSIGNED_BYTE, data.Scan0); GL.Instance.ReadPixels(0, 0, width, height, GL.GL_BGRA, GL.GL_UNSIGNED_BYTE, data.Scan0); final.UnlockBits(data); final.RotateFlip(RotateFlipType.Rotate180FlipX); final.Save(string.Format("picking.dump.png")); } uint stageVertexId = ColorCodedPicking.ReadStageVertexId(x, y); pickedGeometry = SearchGeometry(stageVertexId, arg, this.Scene.RootNode); if (pickedGeometry != null) { var depth = new float[1]; GCHandle pinned = GCHandle.Alloc(depth, GCHandleType.Pinned); IntPtr header = pinned.AddrOfPinnedObject(); // same with: IntPtr header = Marshal.UnsafeAddrOfPinnedArrayElement(array, 0); GL.Instance.ReadPixels(x, y, 1, 1, GL.GL_DEPTH_COMPONENT, GL.GL_FLOAT, header); pinned.Free(); pickedGeometry.PickedPosition = new vec3(x, y, depth[0]); } } framebuffer.Unbind(); return(pickedGeometry); }
/// <summary> /// /// </summary> /// <param name="scene"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="geometryType">Target geometry type(point, line, triangle, quad or polygon) for color-coded-picking or none(nothing to pick).</param> internal PickingEventArgs(Scene scene, int x, int y, PickingGeometryTypes geometryType) { this.Scene = scene; this.X = x; this.Y = y; this.GeometryType = geometryType; this.ModelMatrixStack = new Stack <mat4>(); this.ModelMatrixStack.Push(mat4.identity()); }
/// <summary> /// Pick geometry at specified positon. /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="pickTriangle"></param> /// <param name="pickQuad"></param> /// <param name="pickPolygon"></param> /// <returns></returns> public PickedGeometry Pick(int x, int y, bool pickTriangle, bool pickQuad, bool pickPolygon) { PickingGeometryTypes geometryTypes = 0; if (pickTriangle) { geometryTypes |= PickingGeometryTypes.Triangle; } if (pickQuad) { geometryTypes |= PickingGeometryTypes.Quad; } if (pickPolygon) { geometryTypes |= PickingGeometryTypes.Polygon; } if (geometryTypes == 0) { return(null); } PickedGeometry pickedGeometry = null; Framebuffer framebuffer = GetPickingFramebuffer(); framebuffer.Bind(); { const float one = 1.0f; GL.Instance.ClearColor(one, one, one, one); GL.Instance.Clear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT); var arg = new PickingEventArgs(this.Scene, x, y, geometryTypes); this.RenderForPicking(this.Scene.RootElement, arg); uint stageVertexId = ColorCodedPicking.ReadStageVertexId(x, y); pickedGeometry = Pick(stageVertexId, arg, this.Scene.RootElement); if (pickedGeometry != null) { var depth = new float[1]; GCHandle pinned = GCHandle.Alloc(depth, GCHandleType.Pinned); IntPtr header = pinned.AddrOfPinnedObject(); // same with: IntPtr header = Marshal.UnsafeAddrOfPinnedArrayElement(array, 0); GL.Instance.ReadPixels(x, y, 1, 1, GL.GL_DEPTH_COMPONENT, GL.GL_FLOAT, header); pinned.Free(); pickedGeometry.PickedPosition = new vec3(x, y, depth[0]); } } framebuffer.Unbind(); return(pickedGeometry); }
/// <summary> /// /// </summary> /// <param name="geometryTypes"></param> /// <returns></returns> public static PolygonMode GetPolygonMode(this PickingGeometryTypes geometryTypes) { PolygonMode mode; if ((geometryTypes & PickingGeometryTypes.Point) == PickingGeometryTypes.Point) { mode = PolygonMode.Point; } else if ((geometryTypes & PickingGeometryTypes.Line) == PickingGeometryTypes.Line) { mode = PolygonMode.Line; } else { mode = PolygonMode.Fill; } return(mode); }
/// <summary> /// Pick geometry at specified positon. /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="pickTriangle"></param> /// <param name="pickQuad"></param> /// <param name="pickPolygon"></param> /// <returns></returns> public PickedGeometry Pick(int x, int y, bool pickTriangle, bool pickQuad, bool pickPolygon) { PickingGeometryTypes geometryTypes = 0; if (pickTriangle) { geometryTypes |= PickingGeometryTypes.Triangle; } if (pickQuad) { geometryTypes |= PickingGeometryTypes.Quad; } if (pickPolygon) { geometryTypes |= PickingGeometryTypes.Polygon; } if (geometryTypes == 0) { return(null); } PickedGeometry pickedGeometry = null; Framebuffer framebuffer = GetPickingFramebuffer(); framebuffer.Bind(); { const float one = 1.0f; GL.Instance.ClearColor(one, one, one, one); GL.Instance.Clear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT); var arg = new PickingEventArgs(this.Scene, x, y, geometryTypes); this.RenderForPicking(this.Scene.RootElement, arg); uint stageVertexId = ColorCodedPicking.ReadStageVertexId(x, y); pickedGeometry = Pick(stageVertexId, arg, this.Scene.RootElement); } framebuffer.Unbind(); return(pickedGeometry); }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="stageVertexId">The last vertex's id that constructs the picked primitive. /// <para>This id is in scene's all <see cref="IPickable"/>s' order.</para></param> /// <param name="baseId">Index of first vertex of the buffer that The geometry belongs to. /// <para>This id is in scene's all <see cref="IPickable"/>s' order.</para></param> /// <returns></returns> public override PickedGeometry GetPickedGeometry(PickingEventArgs arg, uint stageVertexId, uint baseId) { if (stageVertexId < baseId) { return(null); } uint singleNodeVertexId = stageVertexId - baseId; if (this.PositionBuffer.Length <= singleNodeVertexId) { return(null); } PickableNode node = this.Node; // Find primitiveInfo RecognizedPrimitiveInfo primitiveInfo = this.GetPrimitiveInfoOfPickedGeometry(arg, singleNodeVertexId, baseId); if (primitiveInfo == null) { Debug.WriteLine(string.Format( "Got singleNodeVertexId[{0}] but no primitiveInfo! Params are [{1}] [{2}]", singleNodeVertexId, arg, stageVertexId)); { return(null); } } PickingGeometryTypes geometryType = arg.GeometryType; DrawMode drawMode = this.DrawCommand.CurrentMode; GeometryType typeOfMode = drawMode.ToGeometryType(); if ((geometryType & PickingGeometryTypes.Point) == PickingGeometryTypes.Point) { // 获取pickedGeometry if (typeOfMode == GeometryType.Point) { return(PickWhateverItIs(arg, stageVertexId, primitiveInfo, typeOfMode)); } else { DrawElementsPointSearcher searcher = GetPointSearcher(drawMode); if (searcher != null)// line is from triangle, quad or polygon { return(SearchPoint(arg, singleNodeVertexId, stageVertexId, primitiveInfo, searcher)); } else { throw new Exception(string.Format("Lack of searcher for [{0}]", drawMode)); } } } else if ((geometryType & PickingGeometryTypes.Line) == PickingGeometryTypes.Line) { // 获取pickedGeometry if (typeOfMode == GeometryType.Point) // want a line when rendering GL_POINTS { return(null); } if (typeOfMode == GeometryType.Line) { return(PickWhateverItIs(arg, stageVertexId, primitiveInfo, typeOfMode)); } else { DrawElementsLineSearcher searcher = GetLineSearcher(drawMode); if (searcher != null)// line is from triangle, quad or polygon { return(SearchLine(arg, singleNodeVertexId, stageVertexId, primitiveInfo, searcher)); } else { throw new Exception(string.Format("Lack of searcher for [{0}]", drawMode)); } } } else { if (geometryType.Contains(typeOfMode)) // I want what it is { return(PickWhateverItIs(arg, stageVertexId, primitiveInfo, typeOfMode)); } else { return(null); } //{ throw new Exception(string.Format("Lack of searcher for [{0}]", mode)); } } }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="stageVertexId">The last vertex's id that constructs the picked primitive. /// <para>This id is in scene's all <see cref="IPickable"/>s' order.</para></param> /// <param name="baseId">Index of first vertex of the buffer that The geometry belongs to. /// <para>This id is in scene's all <see cref="IPickable"/>s' order.</para></param> /// <returns></returns> public override PickedGeometry GetPickedGeometry(PickingEventArgs arg, uint stageVertexId, uint baseId) { if (stageVertexId < baseId) { return(null); } uint singleNodeVertexId = stageVertexId - baseId; if (this.PositionBuffer.Length <= singleNodeVertexId) { return(null); } PickingGeometryTypes pickingType = arg.GeometryType; if ((pickingType & PickingGeometryTypes.Point) == PickingGeometryTypes.Point) { DrawMode mode = this.DrawCommand.CurrentMode; GeometryType typeOfMode = mode.ToGeometryType(); if (typeOfMode == GeometryType.Point) { return(PickWhateverItIs(arg, stageVertexId, singleNodeVertexId, mode, typeOfMode)); } else if (typeOfMode == GeometryType.Line) { if (this.OnPrimitiveTest(singleNodeVertexId, mode)) { return(PickPoint(arg, stageVertexId, singleNodeVertexId)); } else { return(null); } } else { DrawArraysPointSearcher searcher = GetPointSearcher(mode); if (searcher != null)// point is from triangle, quad or polygon { return(SearchPoint(arg, stageVertexId, singleNodeVertexId, searcher)); } else { throw new Exception(string.Format("Lack of searcher for [{0}]", mode)); } } } else if ((pickingType & PickingGeometryTypes.Line) == PickingGeometryTypes.Line) { DrawMode mode = this.DrawCommand.CurrentMode; GeometryType typeOfMode = mode.ToGeometryType(); if (pickingType.Contains(typeOfMode)) { return(PickWhateverItIs(arg, stageVertexId, singleNodeVertexId, mode, typeOfMode)); } else { DrawArraysLineSearcher searcher = GetLineSearcher(mode); if (searcher != null)// line is from triangle, quad or polygon { return(SearchLine(arg, stageVertexId, singleNodeVertexId, searcher)); } else if (mode == DrawMode.Points)// want a line when rendering GL_POINTS { return(null); } else { throw new Exception(string.Format("Lack of searcher for [{0}]", mode)); } } } else { DrawMode mode = this.DrawCommand.CurrentMode; GeometryType typeOfMode = mode.ToGeometryType(); if (pickingType.Contains(typeOfMode)) // I want what it is { return(PickWhateverItIs(arg, stageVertexId, singleNodeVertexId, mode, typeOfMode)); } else { return(null); } //{ throw new Exception(string.Format("Lack of searcher for [{0}]", mode)); } } }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="stageVertexId"></param> /// <returns></returns> public override PickedGeometry GetPickedGeometry(PickingEventArgs arg, uint stageVertexId) { uint lastVertexId; if (!this.Renderer.GetLastVertexIdOfPickedGeometry(stageVertexId, out lastVertexId)) { return(null); } PickingGeometryTypes pickingType = arg.GeometryType; if ((pickingType & PickingGeometryTypes.Point) == PickingGeometryTypes.Point) { DrawMode mode = this.Renderer.PickingRenderUnit.VertexArrayObject.IndexBuffer.Mode; GeometryType typeOfMode = mode.ToGeometryType(); if (typeOfMode == GeometryType.Point) { return(PickWhateverItIs(arg, stageVertexId, lastVertexId, mode, typeOfMode)); } else if (typeOfMode == GeometryType.Line) { if (this.OnPrimitiveTest(lastVertexId, mode)) { return(PickPoint(arg, stageVertexId, lastVertexId)); } else { return(null); } } else { ZeroIndexPointSearcher searcher = GetPointSearcher(mode); if (searcher != null)// point is from triangle, quad or polygon { return(SearchPoint(arg, stageVertexId, lastVertexId, searcher)); } else { throw new Exception(string.Format("Lack of searcher for [{0}]", mode)); } } } else if ((pickingType & PickingGeometryTypes.Line) == PickingGeometryTypes.Line) { DrawMode mode = this.Renderer.PickingRenderUnit.VertexArrayObject.IndexBuffer.Mode; GeometryType typeOfMode = mode.ToGeometryType(); if (pickingType.Contains(typeOfMode)) { return(PickWhateverItIs(arg, stageVertexId, lastVertexId, mode, typeOfMode)); } else { ZeroIndexLineSearcher searcher = GetLineSearcher(mode); if (searcher != null)// line is from triangle, quad or polygon { return(SearchLine(arg, stageVertexId, lastVertexId, searcher)); } else if (mode == DrawMode.Points)// want a line when rendering GL_POINTS { return(null); } else { throw new Exception(string.Format("Lack of searcher for [{0}]", mode)); } } } else { DrawMode mode = this.Renderer.PickingRenderUnit.VertexArrayObject.IndexBuffer.Mode; GeometryType typeOfMode = mode.ToGeometryType(); if (pickingType.Contains(typeOfMode)) // I want what it is { return(PickWhateverItIs(arg, stageVertexId, lastVertexId, mode, typeOfMode)); } else { return(null); } //{ throw new Exception(string.Format("Lack of searcher for [{0}]", mode)); } } }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="stageVertexId"></param> /// <returns></returns> public override PickedGeometry GetPickedGeometry(PickingEventArgs arg, uint stageVertexId) { PickableNode node = this.Renderer; uint lastVertexId; if (!node.GetLastVertexIdOfPickedGeometry(stageVertexId, out lastVertexId)) { return(null); } // 找到 lastIndexId RecognizedPrimitiveInfo lastIndexId = this.GetLastIndexIdOfPickedGeometry( arg, lastVertexId); if (lastIndexId == null) { Debug.WriteLine(string.Format( "Got lastVertexId[{0}] but no lastIndexId! Params are [{1}] [{2}]", lastVertexId, arg, stageVertexId)); { return(null); } } PickingGeometryTypes geometryType = arg.GeometryType; DrawMode drawMode = node.PickingRenderUnit.VertexArrayObject.IndexBuffer.Mode; GeometryType typeOfMode = drawMode.ToGeometryType(); if ((geometryType & PickingGeometryTypes.Point) == PickingGeometryTypes.Point) { // 获取pickedGeometry if (typeOfMode == GeometryType.Point) { return(PickWhateverItIs(arg, stageVertexId, lastIndexId, typeOfMode)); } else if (typeOfMode == GeometryType.Line) { if (this.OnPrimitiveTest(lastVertexId, drawMode)) { return(PickPoint(arg, stageVertexId, lastVertexId)); } else { return(null); } } else { OneIndexPointSearcher searcher = GetPointSearcher(drawMode); if (searcher != null)// line is from triangle, quad or polygon { return(SearchPoint(arg, stageVertexId, lastVertexId, lastIndexId, searcher)); } else { throw new Exception(string.Format("Lack of searcher for [{0}]", drawMode)); } } } else if ((geometryType & PickingGeometryTypes.Line) == PickingGeometryTypes.Line) { // 获取pickedGeometry if (typeOfMode == GeometryType.Point) // want a line when rendering GL_POINTS { return(null); } if (typeOfMode == GeometryType.Line) { return(PickWhateverItIs(arg, stageVertexId, lastIndexId, typeOfMode)); } else { OneIndexLineSearcher searcher = GetLineSearcher(drawMode); if (searcher != null)// line is from triangle, quad or polygon { return(SearchLine(arg, stageVertexId, lastIndexId, searcher)); } else { throw new Exception(string.Format("Lack of searcher for [{0}]", drawMode)); } } } else { if (geometryType.Contains(typeOfMode)) // I want what it is { return(PickWhateverItIs(arg, stageVertexId, lastIndexId, typeOfMode)); } else { return(null); } //{ throw new Exception(string.Format("Lack of searcher for [{0}]", mode)); } } }