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);
        }
示例#3
0
        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);
        }
示例#4
0
        /// <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);
        }
示例#5
0
        /// <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());
        }
示例#6
0
        /// <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);
        }
示例#8
0
        /// <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);
        }
示例#9
0
        /// <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)); }
            }
        }
示例#10
0
        /// <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)); }
            }
        }
示例#11
0
        /// <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)); }
            }
        }
示例#12
0
        /// <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)); }
            }
        }