/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="singleNodeVertexId"></param> /// <param name="stageVertexId"></param> /// <param name="picker"></param> /// <returns></returns> internal override uint Search(PickingEventArgs arg, uint singleNodeVertexId, uint stageVertexId, DrawArraysPicker picker) { var array = new uint[] { singleNodeVertexId - 0, singleNodeVertexId - 1, singleNodeVertexId - 2 }; IndexBuffer buffer = array.GenIndexBuffer(BufferUsage.StaticDraw); var cmd = new DrawElementsCmd(buffer, DrawMode.Points); picker.Node.Render4InnerPicking(arg, cmd); uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y); buffer.Dispose(); if (stageVertexId - 2 <= id && id <= stageVertexId - 0) { return(id); } else { throw new Exception("This should not happen!"); } }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="lastVertexId"></param> /// <param name="picker"></param> /// <returns></returns> internal override uint Search(PickingEventArgs arg, uint lastVertexId, DrawArraysPicker picker) { IndexBuffer buffer = GLBuffer.Create(IndexBufferElementType.UInt, 4, BufferUsage.StaticDraw); unsafe { var array = (uint *)buffer.MapBuffer(MapBufferAccess.WriteOnly); array[0] = lastVertexId - 0; array[1] = lastVertexId - 1; array[2] = lastVertexId - 2; array[3] = lastVertexId - 3; buffer.UnmapBuffer(); } var cmd = new DrawElementsCmd(buffer, DrawMode.Points); picker.Node.Render4InnerPicking(arg, ControlMode.ByFrame, cmd); uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y); buffer.Dispose(); if (lastVertexId - 3 <= id && id <= lastVertexId - 0) { return(id); } else { throw new Exception("This should not happen!"); } }
/// <summary> /// 在三角形图元中拾取指定位置的Point /// </summary> /// <param name="arg">渲染参数</param> /// <param name="lastVertexId">三角形图元的最后一个顶点</param> /// <param name="picker">目标Renderer</param> /// <returns></returns> internal override uint Search(PickingEventArgs arg, uint lastVertexId, DrawArraysPicker picker) { // 创建临时索引 IndexBuffer buffer = GLBuffer.Create(IndexBufferElementType.UInt, 3, BufferUsage.StaticDraw); unsafe { var array = (uint *)buffer.MapBuffer(MapBufferAccess.WriteOnly); array[0] = lastVertexId - 0; array[1] = lastVertexId - 1; array[2] = lastVertexId - 2; buffer.UnmapBuffer(); } var cmd = new DrawElementsCmd(buffer, DrawMode.Points); // 用临时索引渲染此三角形图元(仅渲染此三角形图元) picker.Node.Render4InnerPicking(arg, IndexAccessMode.ByFrame, cmd); // id是拾取到的Line的Last Vertex Id uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y); buffer.Dispose(); // 对比临时索引,找到那个Line if (lastVertexId - 2 <= id && id <= lastVertexId - 0) { return(id); } else { throw new Exception("This should not happen!"); } }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="singleNodeVertexId"></param> /// <param name="stageVertexId"></param> /// <param name="picker"></param> /// <returns></returns> internal override uint[] Search(PickingEventArgs arg, uint singleNodeVertexId, uint stageVertexId, DrawArraysPicker picker) { var cmd = picker.DrawCommand as DrawArraysCmd; // when the temp index buffer could be long, it's no longer needed. // what a great OpenGL API design! DrawArraysCmd drawCmd = new DrawArraysCmd(DrawMode.LineLoop, cmd.MaxVertexCount, cmd.FirstVertex, cmd.VertexCount); picker.Node.Render4InnerPicking(arg, drawCmd); uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y); uint baseId = stageVertexId - singleNodeVertexId; if (id == baseId + cmd.FirstVertex) { return(new uint[] { (uint)(baseId + cmd.FirstVertex + cmd.VertexCount - 1), id, }); } else if (baseId + cmd.FirstVertex < id && id <= (uint)(baseId + cmd.FirstVertex + cmd.VertexCount - 1)) { return(new uint[] { id - 1, id, }); } else { throw new Exception("This should not happen!"); } }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="flatColorVertexId"></param> /// <param name="picker"></param> /// <returns></returns> internal override uint Search(PickingEventArgs arg, uint flatColorVertexId, DrawArraysPicker picker) { var cmd = picker.DrawCommand as DrawArraysCmd; // when the temp index buffer could be long, it's no longer needed. // what a great OpenGL API design! var drawCmd = new DrawArraysCmd(DrawMode.Points, cmd.MaxVertexCount, cmd.FirstVertex, cmd.VertexCount); picker.Node.Render4InnerPicking(arg, drawCmd); uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y); if (cmd.FirstVertex <= id && id < cmd.FirstVertex + cmd.VertexCount) { return(id); } else { throw new Exception("This should not happen!"); } }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="flatColorVertexId"></param> /// <param name="picker"></param> /// <returns></returns> internal override uint[] Search(PickingEventArgs arg, uint flatColorVertexId, DrawArraysPicker picker) { IndexBuffer buffer = GLBuffer.Create(IndexBufferElementType.UInt, 8, BufferUsage.StaticDraw); unsafe { var array = (uint *)buffer.MapBuffer(MapBufferAccess.WriteOnly); array[0] = flatColorVertexId - 0; array[1] = flatColorVertexId - 2; array[2] = flatColorVertexId - 2; array[3] = flatColorVertexId - 3; array[4] = flatColorVertexId - 3; array[5] = flatColorVertexId - 1; array[6] = flatColorVertexId - 1; array[7] = flatColorVertexId - 0; buffer.UnmapBuffer(); } var cmd = new DrawElementsCmd(buffer, DrawMode.Lines); picker.Node.Render4InnerPicking(arg, IndexAccessMode.ByFrame, cmd); uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y); buffer.Dispose(); if (id + 2 == flatColorVertexId) { return(new uint[] { flatColorVertexId - 0, flatColorVertexId - 2, }); } else if (id + 3 == flatColorVertexId) { return(new uint[] { flatColorVertexId - 2, flatColorVertexId - 3 }); } else if (id + 1 == flatColorVertexId) { return(new uint[] { flatColorVertexId - 3, flatColorVertexId - 1, }); } else if (id + 0 == flatColorVertexId) { return(new uint[] { flatColorVertexId - 1, flatColorVertexId - 0, }); } else { throw new Exception("This should not happen!"); } }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="lastVertexId"></param> /// <param name="picker"></param> /// <returns></returns> internal override uint Search(PickingEventArgs arg, uint lastVertexId, DrawArraysPicker picker) { var zeroIndexBuffer = picker.DrawCommand as DrawArraysCmd; // when the temp index buffer could be long, it's no longer needed. // what a great OpenGL API design! var drawCmd = new DrawArraysCmd(DrawMode.Points, zeroIndexBuffer.FirstVertex, zeroIndexBuffer.RenderingVertexCount, zeroIndexBuffer.InstanceCount); picker.Node.Render4InnerPicking(arg, IndexAccessMode.ByFrame, drawCmd); uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y); if (zeroIndexBuffer.FirstVertex <= id && id < zeroIndexBuffer.FirstVertex + zeroIndexBuffer.RenderingVertexCount) { return(id); } else { throw new Exception("This should not happen!"); } }
/// <summary> /// 在三角形图元中拾取指定位置的Line /// </summary> /// <param name="arg"></param> /// <param name="singleNodeVertexId">三角形图元的最后一个顶点</param> /// <param name="stageVertexId"></param> /// <param name="picker"></param> /// <returns></returns> internal override uint[] Search(PickingEventArgs arg, uint singleNodeVertexId, uint stageVertexId, DrawArraysPicker picker) { // 创建临时索引 var array = new uint[] { singleNodeVertexId - 1, singleNodeVertexId - 0, singleNodeVertexId - 2, singleNodeVertexId - 1, singleNodeVertexId - 0, singleNodeVertexId - 2 }; IndexBuffer buffer = array.GenIndexBuffer(BufferUsage.StaticDraw); var cmd = new DrawElementsCmd(buffer, DrawMode.Lines); // 用临时索引渲染此三角形图元(仅渲染此三角形图元) picker.Node.Render4InnerPicking(arg, cmd); // id是拾取到的Line的Last Vertex Id uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y); buffer.Dispose(); // 对比临时索引,找到那个Line if (id + 2 == stageVertexId) { return(new uint[] { id + 2, id, }); } else if (id + 1 == stageVertexId) { return(new uint[] { id - 1, id, }); } else if (id + 0 == stageVertexId) { return(new uint[] { id - 1, id, }); } else { throw new Exception("This should not happen!"); } }