private void RenderForPicking(RendererBase sceneElement, PickEventArgs arg)
        {
            if (sceneElement != null)
            {
                mat4 parentCascadeModelMatrix = arg.ModelMatrixStack.Peek();
                sceneElement.cascadeModelMatrix = sceneElement.GetModelMatrix(parentCascadeModelMatrix);

                var      pickable = sceneElement as IPickable;
                TwoFlags flags    = (pickable != null) ? pickable.EnablePicking : TwoFlags.None;
                bool     before   = (pickable != null) && ((flags & TwoFlags.BeforeChildren) == TwoFlags.BeforeChildren);
                bool     children = (pickable == null) || ((flags & TwoFlags.Children) == TwoFlags.Children);

                if (before)
                {
                    pickable.PickingBaseId += arg.RenderedVertexCount;
                    pickable.RenderForPicking(arg);
                    arg.RenderedVertexCount += pickable.GetVertexCount();
                }

                if (children)
                {
                    arg.ModelMatrixStack.Push(sceneElement.cascadeModelMatrix);
                    foreach (var item in sceneElement.Children)
                    {
                        this.RenderForPicking(item, arg);
                    }
                    arg.ModelMatrixStack.Pop();
                }
            }
        }
示例#2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="x">mouse position(Left Down is (0, 0)).</param>
        /// <param name="y">mouse position(Left Down is (0, 0)).</param>
        /// <param name="lastVertexId"></param>
        /// <param name="modernRenderer"></param>
        /// <returns></returns>
        internal override uint[] Search(PickEventArgs arg,
                                        uint lastVertexId, ZeroIndexPicker picker)
        {
            OneIndexBuffer buffer = GLBuffer.Create(IndexBufferElementType.UInt, 6, DrawMode.Lines, BufferUsage.StaticDraw);

            unsafe
            {
                var array = (uint *)buffer.MapBuffer(MapBufferAccess.WriteOnly);
                array[0] = 0; array[1] = lastVertexId - 1;
                array[2] = lastVertexId - 1; array[3] = lastVertexId - 0;
                array[4] = lastVertexId - 0; array[5] = 0;
                buffer.UnmapBuffer();
            }
            picker.Renderer.Render4InnerPicking(arg, buffer);
            uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y);

            buffer.Dispose();

            if (id + 1 == lastVertexId)
            {
                return(new uint[] { 0, lastVertexId - 1, });
            }
            else if (id == lastVertexId)
            {
                return(new uint[] { lastVertexId - 1, lastVertexId - 0, });
            }
            else if (id == 0)
            {
                return(new uint[] { lastVertexId - 0, 0, });
            }
            else
            {
                throw new Exception("This should not happen!");
            }
        }
示例#3
0
 public override void RenderForPicking(PickEventArgs arg)
 {
     if (this.RenderWireframe || this.RenderBody)
     {
         base.RenderForPicking(arg);
     }
 }
示例#4
0
        /// <summary>
        /// 遍历以<paramref name="lastVertexId"/>为最后一个顶点的图元,
        /// 瞄准每个图元的索引(例如1个三角形有3个索引)中的最后一个索引,
        /// 将此索引在<see cref="IndexBuffer"/>中的索引(位置)收集起来。
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="lastVertexId"></param>
        /// <returns></returns>
        private List <RecognizedPrimitiveInfo> GetLastIndexIdList(PickEventArgs arg, uint lastVertexId)
        {
            var indexBuffer = this.Renderer.IndexBuffer;
            PrimitiveRecognizer recognizer = PrimitiveRecognizerFactory.Create(
                (arg.GeometryType == PickingGeometryType.Point &&
                 indexBuffer.Mode.ToGeometryType() == PickingGeometryType.Line) ?
                DrawMode.Points : indexBuffer.Mode);

            PrimitiveRestartState glState = GetPrimitiveRestartState();

            var    buffer  = indexBuffer as OneIndexBuffer;
            IntPtr pointer = buffer.MapBuffer(MapBufferAccess.ReadOnly);
            List <RecognizedPrimitiveInfo> primitiveInfoList = null;

            if (glState == null)
            {
                primitiveInfoList = recognizer.Recognize(lastVertexId, pointer, indexBuffer as OneIndexBuffer);
            }
            else
            {
                primitiveInfoList = recognizer.Recognize(lastVertexId, pointer, indexBuffer as OneIndexBuffer, glState.RestartIndex);
            }
            buffer.UnmapBuffer();

            return(primitiveInfoList);
        }
        private PickedGeometry Pick(uint stageVertexId, PickEventArgs arg, RendererBase renderer)
        {
            PickedGeometry pickedGeometry = null;

            if (renderer != null)
            {
                var pickable = renderer as IPickable;
                if (pickable != null)
                {
                    pickedGeometry = pickable.GetPickedGeometry(arg, stageVertexId);
                }

                if (pickedGeometry == null)
                {
                    foreach (var item in renderer.Children)
                    {
                        pickedGeometry = Pick(stageVertexId, arg, item);
                        if (pickedGeometry != null)
                        {
                            break;
                        }
                    }
                }
            }

            return(pickedGeometry);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="x">mouse position(Left Down is (0, 0)).</param>
        /// <param name="y">mouse position(Left Down is (0, 0)).</param>
        /// <param name="lastVertexId"></param>
        /// <param name="modernRenderer"></param>
        /// <returns></returns>
        internal override uint Search(PickEventArgs arg,
                                      uint lastVertexId, ZeroIndexPicker picker)
        {
            OneIndexBuffer buffer = GLBuffer.Create(IndexBufferElementType.UInt, 4, DrawMode.Points, 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();
            }
            picker.Renderer.Render4InnerPicking(arg, buffer);
            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>
        ///
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="x">mouse position(Left Down is (0, 0)).</param>
        /// <param name="y">mouse position(Left Down is (0, 0)).</param>
        /// <param name="primitiveInfo"></param>
        /// <param name="modernRenderer"></param>
        /// <returns></returns>
        internal override uint Search(PickEventArgs arg,
                                      RecognizedPrimitiveInfo primitiveInfo,
                                      OneIndexPicker picker)
        {
            uint[] indexList = primitiveInfo.VertexIds;
            if (indexList.Length != 3)
            {
                throw new ArgumentException();
            }

            OneIndexBuffer buffer = indexList.GenIndexBuffer(DrawMode.Points, BufferUsage.StaticDraw);

            picker.Renderer.Render4InnerPicking(arg, buffer);
            uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y);

            buffer.Dispose();

            if (id == indexList[0] || id == indexList[1] || id == indexList[2])
            {
                return(id);
            }
            else
            {
                throw new Exception("This should not happen!");
            }
        }
示例#8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="twoPrimitivesIndexBuffer"></param>
        /// <param name="x">mouse position(Left Down is (0, 0)).</param>
        /// <param name="y">mouse position(Left Down is (0, 0)).</param>
        /// <returns></returns>
        private uint Pick(PickEventArgs arg, OneIndexBuffer twoPrimitivesIndexBuffer)
        {
            this.Renderer.Render4InnerPicking(arg, twoPrimitivesIndexBuffer);

            uint pickedIndex = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y);

            return(pickedIndex);
        }
示例#9
0
        /// <summary>
        /// 是三角形,就pick一个三角形;是四边形,就pick一个四边形,是多边形,就pick一个多边形。
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="stageVertexId"></param>
        /// <param name="primitiveInfo"></param>
        /// <param name="typeOfMode"></param>
        /// <returns></returns>
        private PickedGeometry PickWhateverItIs(PickEventArgs arg, uint stageVertexId, RecognizedPrimitiveInfo primitiveInfo, PickingGeometryType typeOfMode)
        {
            uint[] vertexIds      = primitiveInfo.VertexIds;
            vec3[] positions      = FillPickedGeometrysPosition(vertexIds);
            var    pickedGeometry = new PickedGeometry(typeOfMode, positions, vertexIds, stageVertexId, this.Renderer);

            return(pickedGeometry);
        }
示例#10
0
        private PickedGeometry PickPoint(PickEventArgs arg, uint stageVertexId, uint lastVertexId)
        {
            var vertexIds      = new uint[] { lastVertexId, };
            var positions      = FillPickedGeometrysPosition(vertexIds);
            var pickedGeometry = new PickedGeometry(PickingGeometryType.Point, positions, vertexIds, stageVertexId, this.Renderer);

            return(pickedGeometry);
        }
示例#11
0
        /// <summary>
        /// Search line in triangles/triangle_strip/triangle_fan/
        /// triangles_adjacency/triangle_strip_adjacency/
        /// quads/quad_strip/polygon
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="stageVertexId"></param>
        /// <param name="x">mouse position(Left Down is (0, 0)).</param>
        /// <param name="y">mouse position(Left Down is (0, 0)).</param>
        /// <param name="lastVertexId"></param>
        /// <param name="searcher"></param>
        /// <returns></returns>
        private PickedGeometry SearchLine(PickEventArgs arg, uint stageVertexId,
                                          uint lastVertexId, ZeroIndexLineSearcher searcher)
        {
            var vertexIds      = searcher.Search(arg, lastVertexId, this);
            var positions      = FillPickedGeometrysPosition(vertexIds);
            var pickedGeometry = new PickedGeometry(PickingGeometryType.Line, positions, vertexIds, stageVertexId, this.Renderer);

            return(pickedGeometry);
        }
示例#12
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="stageVertexId"></param>
        /// <param name="x">mouse position(Left Down is (0, 0)).</param>
        /// <param name="y">mouse position(Left Down is (0, 0)).</param>
        /// <param name="lastVertexId"></param>
        /// <param name="primitiveInfo"></param>
        /// <param name="searcher"></param>
        /// <returns></returns>
        private PickedGeometry SearchLine(PickEventArgs arg, uint stageVertexId, RecognizedPrimitiveInfo primitiveInfo, OneIndexLineSearcher searcher)
        {
            var vertexIds = searcher.Search(arg, primitiveInfo, this);

            vec3[] positions      = FillPickedGeometrysPosition(vertexIds);
            var    pickedGeometry = new PickedGeometry(PickingGeometryType.Line, positions, vertexIds, stageVertexId, this.Renderer);

            return(pickedGeometry);
        }
        public virtual PickedGeometry GetPickedGeometry(PickEventArgs arg, uint stageVertexId)
        {
            PickedGeometry result = null;

            PickerBase picker = this.picker;

            if (picker != null)
            {
                result = picker.GetPickedGeometry(arg, stageVertexId);
            }

            return(result);
        }
示例#14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="lastVertexId"></param>
        /// <param name="x">mouse position(Left Down is (0, 0)).</param>
        /// <param name="y">mouse position(Left Down is (0, 0)).</param>
        /// <returns></returns>
        private RecognizedPrimitiveInfo GetLastIndexIdOfPickedGeometry(
            PickEventArgs arg,
            uint lastVertexId)
        {
            List <RecognizedPrimitiveInfo> primitiveInfoList = GetLastIndexIdList(arg, lastVertexId);

            if (primitiveInfoList.Count == 0)
            {
                return(null);
            }

            RecognizedPrimitiveInfo lastIndexId = GetLastIndexId(arg, primitiveInfoList);

            return(lastIndexId);
        }
        private void RenderForPicking(PickEventArgs arg, IndexBuffer tempIndexBuffer)
        {
            if (!this.IsInitialized)
            {
                this.Initialize();
            }

            this.polygonModeState.Mode = arg.GeometryType.GetPolygonMode();

            ShaderProgram program = this.PickProgram;

            // 绑定shader
            program.Bind();
            program.glUniform("pickingBaseId", (int)(((IPickable)this).PickingBaseId));
            {
                mat4 projection = arg.Scene.Camera.GetProjectionMatrix();
                mat4 view       = arg.Scene.Camera.GetViewMatrix();
                mat4 model      = this.GetModelMatrix();
                program.glUniform("MVP", projection * view * model);
            }

            this.polygonModeState.On();
            this.lineWidthState.On();
            this.pointSizeState.On();

            var oneIndexBuffer = tempIndexBuffer as OneIndexBuffer;

            if (oneIndexBuffer != null)
            {
                PrimitiveRestartState glState = this.GetPrimitiveRestartState(oneIndexBuffer);
                glState.On();
                this.pickVertexArrayObject.Render(program, tempIndexBuffer);
                glState.Off();
            }
            else
            {
                this.pickVertexArrayObject.Render(program, tempIndexBuffer);
            }

            this.pointSizeState.Off();
            this.lineWidthState.Off();
            this.polygonModeState.Off();

            // 解绑shader
            program.Unbind();
        }
        /// <summary>
        /// 在所有可能的图元(lastVertexId匹配)中,
        /// 逐个测试,找到最接近摄像机的那个图元,
        /// 返回此图元的最后一个索引在<see cref="IndexBuffer"/>中的索引(位置)。
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="primitiveInfoList"></param>
        /// <param name="x">mouse position(Left Down is (0, 0)).</param>
        /// <param name="y">mouse position(Left Down is (0, 0)).</param>
        /// <returns></returns>
        private RecognizedPrimitiveInfo GetLastIndexId(
            PickEventArgs arg,
            List <RecognizedPrimitiveInfo> primitiveInfoList)
        {
            if (primitiveInfoList == null || primitiveInfoList.Count == 0)
            {
                return(null);
            }
#if DEBUG
            SameLengths(primitiveInfoList);
#endif
            if (primitiveInfoList[0].VertexIds.Length == 1)// picking a point.
            {
                return(primitiveInfoList[0]);
            }

            int current = 0;
#if DEBUG
            NoPrimitiveRestartIndex(primitiveInfoList);
#endif
            for (int i = 1; i < primitiveInfoList.Count; i++)
            {
                OneIndexBuffer twoPrimitivesIndexBuffer;
                uint           lastIndex0, lastIndex1;
                AssembleIndexBuffer(
                    primitiveInfoList[current], primitiveInfoList[i], this.Renderer.IndexBuffer.Mode,
                    out twoPrimitivesIndexBuffer, out lastIndex0, out lastIndex1);
                uint pickedIndex = Pick(arg, twoPrimitivesIndexBuffer);
                if (pickedIndex == lastIndex1)
                {
                    current = i;
                }
                else if (pickedIndex == lastIndex0)
                {                                      /* nothing to do */
                }
                else if (pickedIndex == uint.MaxValue) // 两个候选图元都没有被拾取到
                {                                      /* nothing to do */
                }
                else
                {
                    throw new Exception("This should not happen!");
                }
            }

            return(primitiveInfoList[current]);
        }
示例#17
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="x">mouse position(Left Down is (0, 0)).</param>
        /// <param name="y">mouse position(Left Down is (0, 0)).</param>
        /// <param name="primitiveInfo"></param>
        /// <param name="modernRenderer"></param>
        /// <returns></returns>
        internal override uint[] Search(PickEventArgs arg,
                                        RecognizedPrimitiveInfo primitiveInfo,
                                        OneIndexPicker picker)
        {
            uint[] indexList = primitiveInfo.VertexIds;
            if (indexList.Length < 3)
            {
                throw new ArgumentException();
            }

            OneIndexBuffer buffer = indexList.GenIndexBuffer(DrawMode.LineLoop, BufferUsage.StaticDraw);

            picker.Renderer.Render4InnerPicking(arg, buffer);
            uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y);

            buffer.Dispose();

            if (id == indexList[0])
            {
                return(new uint[] { indexList[indexList.Length - 1], id, });
            }
            else
            {
                uint[] result = null;
                for (int i = 1; i < indexList.Length; i++)
                {
                    if (id == indexList[i])
                    {
                        result = new uint[] { indexList[i - 1], indexList[i], };
                        break;
                    }
                }

                if (result != null)
                {
                    return(result);
                }
                else
                {
                    throw new Exception("This should not happen!");
                }
            }
        }
        /// <summary>
        /// 在此Buffer中的图元进行N选1
        /// select a primitive geometry(point, line, triangle, quad, polygon) from points/lines/triangles/quads/polygons in this renderer.
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="indexBuffer">indicates the primitive to pick a line from.</param>
        internal void Render4InnerPicking(PickEventArgs arg, IndexBuffer indexBuffer)
        {
            // record clear color
            var originalClearColor = new float[4];

            GL.Instance.GetFloatv((uint)GetTarget.ColorClearValue, originalClearColor);

            // 白色意味着没有拾取到任何对象
            // white color: nothing picked.
            GL.Instance.ClearColor(1.0f, 1.0f, 1.0f, 1.0f);
            GL.Instance.Clear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT);

            // restore clear color
            GL.Instance.ClearColor(originalClearColor[0], originalClearColor[1], originalClearColor[2], originalClearColor[3]);

            this.RenderForPicking(arg, indexBuffer);

            GL.Instance.Flush();

            //var filename = string.Format("Render4InnerPicking{0:yyyy-MM-dd_HH-mm-ss.ff}.png", DateTime.Now);
            //Save2PictureHelper.Save2Picture(0, 0,
            //    e.CanvasRect.Width, e.CanvasRect.Height, filename);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="arg"></param>
        /// <param name="x">mouse position(Left Down is (0, 0)).</param>
        /// <param name="y">mouse position(Left Down is (0, 0)).</param>
        /// <param name="lastVertexId"></param>
        /// <param name="modernRenderer"></param>
        /// <returns></returns>
        internal override uint Search(PickEventArgs arg,
                                      uint lastVertexId, ZeroIndexPicker picker)
        {
            var zeroIndexBuffer = picker.Renderer.IndexBuffer as ZeroIndexBuffer;
            // when the temp index buffer could be long, it's no longer needed.
            // what a great OpenGL API design!
            ZeroIndexBuffer indexBuffer = ZeroIndexBuffer.Create(DrawMode.Points, zeroIndexBuffer.FirstVertex, zeroIndexBuffer.RenderingVertexCount, zeroIndexBuffer.PrimCount);

            picker.Renderer.Render4InnerPicking(arg, indexBuffer);
            uint id = ColorCodedPicking.ReadStageVertexId(arg.X, arg.Y);

            indexBuffer.Dispose();

            if (zeroIndexBuffer.FirstVertex <= id &&
                id < zeroIndexBuffer.FirstVertex + zeroIndexBuffer.RenderingVertexCount)
            {
                return(id);
            }
            else
            {
                throw new Exception("This should not happen!");
            }
        }
        /// <summary>
        /// Pick geometry at specified positon.
        /// </summary>
        /// <param name="x">Left Down is (0, 0)</param>
        /// <param name="y">Left Down is (0, 0)</param>
        /// <param name="geometryType"></param>
        /// <returns></returns>
        public PickedGeometry Pick(int x, int y, PickingGeometryType geometryType)
        {
            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 PickEventArgs(this, x, y, geometryType);
                this.RenderForPicking(this.RootElement, arg);

                uint stageVertexId = ColorCodedPicking.ReadStageVertexId(x, y);

                pickedGeometry = Pick(stageVertexId, arg, this.RootElement);
            }
            framebuffer.Unbind();

            return(pickedGeometry);
        }
示例#21
0
 public virtual void RenderForPicking(PickEventArgs arg)
 {
     this.RenderForPicking(arg, null);
 }
示例#22
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="renderer"></param>
        /// <param name="arg"></param>
        /// <param name="stageVertexId"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public override PickedGeometry GetPickedGeometry(PickEventArgs arg, uint stageVertexId)
        {
            PickableRenderer renderer = this.Renderer;

            uint lastVertexId;

            if (!renderer.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}] [{3}] [{4}]",
                                    lastVertexId, arg, stageVertexId));
                { return(null); }
            }

            PickingGeometryType geometryType = arg.GeometryType;
            DrawMode            mode         = renderer.IndexBuffer.Mode;
            PickingGeometryType typeOfMode   = mode.ToGeometryType();

            if (geometryType == PickingGeometryType.Point)
            {
                // 获取pickedGeometry
                if (typeOfMode == PickingGeometryType.Point)
                {
                    return(PickWhateverItIs(arg, stageVertexId, lastIndexId, typeOfMode));
                }
                else if (typeOfMode == PickingGeometryType.Line)
                {
                    if (this.OnPrimitiveTest(lastVertexId, mode))
                    {
                        return(PickPoint(arg, stageVertexId, lastVertexId));
                    }
                    else
                    {
                        return(null);
                    }
                }
                else
                {
                    OneIndexPointSearcher searcher = GetPointSearcher(mode);
                    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}]", mode));
                    }
                }
            }
            else if (geometryType == PickingGeometryType.Line)
            {
                // 获取pickedGeometry
                if (geometryType == typeOfMode)
                {
                    return(PickWhateverItIs(arg, stageVertexId, lastIndexId, typeOfMode));
                }
                else
                {
                    OneIndexLineSearcher searcher = GetLineSearcher(mode);
                    if (searcher != null)// line is from triangle, quad or polygon
                    {
                        return(SearchLine(arg, stageVertexId, lastIndexId, 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
            {
                if (typeOfMode == geometryType)// 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)); }
            }
        }
示例#23
0
        private PickedGeometry PickWhateverItIs(PickEventArgs arg, uint stageVertexId, uint lastVertexId, DrawMode mode, PickingGeometryType typeOfMode)
        {
            //PickedGeometry pickedGeometry = new PickedGeometry();
            //pickedGeometry.GeometryType = typeOfMode;
            //pickedGeometry.StageVertexId = stageVertexId;
            //pickedGeometry.FromRenderer = this;

            // Fill primitive's position information.
            int vertexCount = typeOfMode.GetVertexCount();

            if (vertexCount == -1)
            {
                vertexCount = this.Renderer.PositionBuffer.Length;
            }

            uint[] vertexIds; vec3[] positions;

            if (lastVertexId == 0 && vertexCount == 2)
            {
                // This is when mode is GL_LINE_LOOP and picked last line(the loop back one)
                PickingLastLineInLineLoop(out vertexIds, out positions);
            }
            else
            {
                // Other conditions
                switch (typeOfMode)
                {
                case PickingGeometryType.Point:
                    vertexIds = new uint[] { lastVertexId, };
                    positions = FillPickedGeometrysPosition(lastVertexId, 1);
                    break;

                case PickingGeometryType.Line:
                    vertexIds = new uint[] { lastVertexId - 1, lastVertexId, };
                    positions = FillPickedGeometrysPosition(lastVertexId - 1, 2);
                    break;

                case PickingGeometryType.Triangle:
                    if (mode == DrawMode.TriangleFan)
                    {
                        vertexIds = new uint[] { 0, lastVertexId - 1, lastVertexId, };
                        positions = FillPickedGeometrysPosition(vertexIds);
                    }
                    else if (mode == DrawMode.TrianglesAdjacency || mode == DrawMode.TriangleStripAdjacency)
                    {
                        vertexIds = new uint[] { lastVertexId - 4, lastVertexId - 2, lastVertexId, };
                        positions = FillPickedGeometrysPosition(vertexIds);
                    }
                    else
                    {
                        vertexIds = new uint[] { lastVertexId - 2, lastVertexId - 1, lastVertexId, };
                        positions = FillPickedGeometrysPosition(lastVertexId - 2, 3);
                    }
                    break;

                case PickingGeometryType.Quad:
                    vertexIds = new uint[] { lastVertexId - 3, lastVertexId - 2, lastVertexId - 1, lastVertexId, };
                    positions = FillPickedGeometrysPosition(lastVertexId - 3, 4);
                    break;

                case PickingGeometryType.Polygon:
                    vertexIds = new uint[vertexCount];
                    for (uint i = 0; i < vertexCount; i++)
                    {
                        vertexIds[i] = lastVertexId + i;
                    }
                    positions = FillPickedGeometrysPosition(0, vertexCount);
                    break;

                default:
                    throw new Exception("Unexpected PickingGeometryType!");
                }
            }

            PickedGeometry pickedGeometry = new PickedGeometry(typeOfMode, positions, vertexIds, stageVertexId, this.Renderer);

            return(pickedGeometry);
        }
示例#24
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="renderer"></param>
 /// <param name="arg"></param>
 /// <param name="stageVertexId"></param>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <returns></returns>
 public abstract PickedGeometry GetPickedGeometry(PickEventArgs arg, uint stageVertexId);
示例#25
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="renderer"></param>
        /// <param name="arg"></param>
        /// <param name="stageVertexId"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public override PickedGeometry GetPickedGeometry(PickEventArgs arg, uint stageVertexId)
        {
            uint lastVertexId;

            if (!this.Renderer.GetLastVertexIdOfPickedGeometry(stageVertexId, out lastVertexId))
            {
                return(null);
            }

            PickingGeometryType geometryType = arg.GeometryType;

            if (geometryType == PickingGeometryType.Point)
            {
                DrawMode            mode       = this.Renderer.IndexBuffer.Mode;
                PickingGeometryType typeOfMode = mode.ToGeometryType();
                if (typeOfMode == PickingGeometryType.Point)
                {
                    return(PickWhateverItIs(arg, stageVertexId, lastVertexId, mode, typeOfMode));
                }
                else if (typeOfMode == PickingGeometryType.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 (geometryType == PickingGeometryType.Line)
            {
                DrawMode            mode       = this.Renderer.IndexBuffer.Mode;
                PickingGeometryType typeOfMode = mode.ToGeometryType();
                if (geometryType == 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.IndexBuffer.Mode;
                PickingGeometryType typeOfMode = mode.ToGeometryType();
                if (typeOfMode == geometryType)// 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)); }
            }
        }