예제 #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static DrawMode ToDrawMode(this PickingGeometryType type)
        {
            DrawMode mode = DrawMode.Points;

            switch (type)
            {
            case PickingGeometryType.Point:
                mode = DrawMode.Points;
                break;

            case PickingGeometryType.Line:
                mode = DrawMode.Lines;
                break;

            case PickingGeometryType.Triangle:
                mode = DrawMode.Triangles;
                break;

            case PickingGeometryType.Quad:
                mode = DrawMode.Quads;
                break;

            case PickingGeometryType.Polygon:
                mode = DrawMode.Polygon;
                break;

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

            return(mode);
        }
예제 #2
0
        /// <summary>
        /// Get vertex count of specified geometry's type.
        /// <para>returns -1 if type is <see cref="PickingGeometryType.Polygon"/>.</para>
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static int GetVertexCount(this PickingGeometryType type)
        {
            int result = -1;

            switch (type)
            {
            case PickingGeometryType.Point:
                result = 1;
                break;

            case PickingGeometryType.Line:
                result = 2;
                break;

            case PickingGeometryType.Triangle:
                result = 3;
                break;

            case PickingGeometryType.Quad:
                result = 4;
                break;

            case PickingGeometryType.Polygon:
                result = -1;
                break;

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

            return(result);
        }
        private void UpdatePolygonMode(PickingGeometryType geometryType)
        {
            switch (geometryType)
            {
            case PickingGeometryType.None:
                // whatever it is.
                polygonModeState.Mode = PolygonMode.Point;
                break;

            case PickingGeometryType.Point:
                polygonModeState.Mode = PolygonMode.Point;
                break;

            case PickingGeometryType.Line:
                polygonModeState.Mode = PolygonMode.Line;
                break;

            case PickingGeometryType.Triangle:
                polygonModeState.Mode = PolygonMode.Fill;
                break;

            case PickingGeometryType.Quad:
                polygonModeState.Mode = PolygonMode.Fill;
                break;

            case PickingGeometryType.Polygon:
                polygonModeState.Mode = PolygonMode.Fill;
                break;

            default:
                throw new NotImplementedException();
            }
        }
예제 #4
0
        /// <summary>
        /// Get geometry at specified <paramref name="mousePosition"/> with specified <paramref name="pickingGeometryType"/>.
        /// <para>Returns null when <paramref name="mousePosition"/> is out of this scene's area or there's no active(visible and enabled) viewport.</para>
        /// </summary>
        /// <param name="mousePosition">mouse position in Windows coordinate system.(Left Up is (0, 0))</param>
        /// <param name="pickingGeometryType">target's geometry type.</param>
        /// <returns></returns>
        public List <Tuple <Point, PickedGeometry> > Pick(Point mousePosition, PickingGeometryType pickingGeometryType)
        {
            Rectangle clientRectangle = this.Canvas.ClientRectangle;

            // if mouse is out of window's area, nothing picked.
            if (mousePosition.X < 0 || clientRectangle.Width <= mousePosition.X || mousePosition.Y < 0 || clientRectangle.Height <= mousePosition.Y)
            {
                return(null);
            }

            int x = mousePosition.X;
            int y = clientRectangle.Height - mousePosition.Y - 1;
            // now (x, y) is in OpenGL's window cooridnate system.
            Point position    = new Point(x, y);
            var   pickingRect = new Rectangle(x, y, 1, 1);
            List <Tuple <Point, PickedGeometry> > allPickedGeometrys = null;

            foreach (ViewPort viewPort in this.rootViewPort.Traverse(TraverseOrder.Post))
            {
                if (viewPort.Visiable && viewPort.Enabled && viewPort.Contains(position))
                {
                    allPickedGeometrys = ColorCodedPicking(viewPort, pickingRect, clientRectangle, pickingGeometryType);

                    break;
                }
            }

            return(allPickedGeometrys);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="geometryType"></param>
        /// <returns></returns>
        public static PolygonMode GetPolygonMode(this PickingGeometryType geometryType)
        {
            PolygonMode mode;

            switch (geometryType)
            {
            case PickingGeometryType.Point:
                mode = PolygonMode.Point;
                break;

            case PickingGeometryType.Line:
                mode = PolygonMode.Line;
                break;

            case PickingGeometryType.Triangle:
                mode = PolygonMode.Fill;
                break;

            case PickingGeometryType.Quad:
                mode = PolygonMode.Fill;
                break;

            case PickingGeometryType.Polygon:
                mode = PolygonMode.Fill;
                break;

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

            return(mode);
        }
예제 #6
0
 //public PickedGeometry() { }
 /// <summary>
 /// The color-coded picking result.
 /// <para>Representing a primitive(point, line, triangle, quad, polygon).</para>
 /// </summary>
 /// <param name="geometryType"></param>
 /// <param name="positions"></param>
 /// <param name="vertexIds"></param>
 /// <param name="stageVertexId"></param>
 /// <param name="fromRenderer"></param>
 public PickedGeometry(PickingGeometryType geometryType, vec3[] positions, uint[] vertexIds, uint stageVertexId, IPickable fromRenderer)
 {
     this.GeometryType  = geometryType;
     this.Positions     = positions;
     this.VertexIds     = vertexIds;
     this.StageVertexId = stageVertexId;
     this.FromRenderer  = fromRenderer;
 }
예제 #7
0
 //public PickedGeometry() { }
 /// <summary>
 /// The color-coded picking result.
 /// <para>Representing a primitive(point, line, triangle, quad, polygon).</para>
 /// </summary>
 /// <param name="fromViewPort"></param>
 /// <param name="geometryType"></param>
 /// <param name="positions"></param>
 /// <param name="vertexIds"></param>
 /// <param name="stageVertexId"></param>
 /// <param name="fromRenderer"></param>
 public PickedGeometry(ViewPort fromViewPort, PickingGeometryType geometryType, vec3[] positions, uint[] vertexIds, uint stageVertexId, IPickable fromRenderer)
 {
     this.FromViewPort = fromViewPort;
     this.GeometryType = geometryType;
     this.Positions = positions;
     this.VertexIds = vertexIds;
     this.StageVertexId = stageVertexId;
     this.FromRenderer = fromRenderer;
 }
예제 #8
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>
        public PickEventArgs(Scene scene, int x, int y, PickingGeometryType geometryType)
        {
            this.Scene        = scene;
            this.X            = x;
            this.Y            = y;
            this.GeometryType = geometryType;

            this.ModelMatrixStack = new Stack <mat4>();
            this.ModelMatrixStack.Push(mat4.identity());
        }
예제 #9
0
 /// <summary>
 /// Render this scene.
 /// </summary>
 /// <param name="pickingGeometryType">Specify type of primitive you want to pick or nothing to pick.</param>
 public void Render(
     PickingGeometryType pickingGeometryType = PickingGeometryType.None)
 {
     lock (this.synObj)
     {
         // update view port's location and size.
         // render scene in every view port.
         this.RenderViewPort(this.Canvas.ClientRectangle, pickingGeometryType);
     }
 }
예제 #10
0
 /// <summary>
 /// render scene in every view port.
 /// </summary>
 /// <param name="clientRectangle"></param>
 /// <param name="pickingGeometryType"></param>
 private void RenderViewPort(Rectangle clientRectangle, PickingGeometryType pickingGeometryType)
 {
     if (pickingGeometryType == PickingGeometryType.None)
     {
         RenderNormally(this, clientRectangle);
     }
     else
     {
         RenderColorCoded(this, clientRectangle, pickingGeometryType);
     }
 }
예제 #11
0
        /// <summary>
        /// render scene in this view port.
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="clientRectangle"></param>
        /// <param name="pickingGeometryType"></param>
        public override void Render(Scene scene, System.Drawing.Rectangle clientRectangle, PickingGeometryType pickingGeometryType)
        {
            this.On();// limit rendering area.

            vec4 color = this.ClearColor.ToVec4();
            OpenGL.glClearColor(color.x, color.y, color.z, color.w);

            OpenGL.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT | OpenGL.GL_STENCIL_BUFFER_BIT);

            this.Off();// cancel limitation.
        }
예제 #12
0
 /// <summary>
 /// Render this scene.
 /// </summary>
 /// <param name="pickingGeometryType">Specify type of primitive you want to pick or nothing to pick.</param>
 public void Render(
     PickingGeometryType pickingGeometryType = PickingGeometryType.None)
 {
     lock (this.synObj)
     {
         // update view port's location and size.
         this.rootViewPort.Layout();
         // render scene in every view port.
         this.RenderViewPort(this.rootViewPort, this.Canvas.ClientRectangle, pickingGeometryType);
     }
 }
예제 #13
0
        /// <summary>
        /// render scene in this view port.
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="clientRectangle"></param>
        /// <param name="pickingGeometryType"></param>
        public virtual void Render(Scene scene, Rectangle clientRectangle, PickingGeometryType pickingGeometryType)
        {
            this.On();// limit rendering area.

            if (pickingGeometryType == PickingGeometryType.None)
            {
                RenderNormally(scene, clientRectangle);
            }
            else
            {
                RenderColorCoded(scene, clientRectangle, pickingGeometryType);
            }

            this.Off();// cancel limitation.
        }
예제 #14
0
        /// <summary>
        /// render scene in every view port.
        /// </summary>
        /// <param name="viewPort"></param>
        /// <param name="clientRectangle"></param>
        /// <param name="pickingGeometryType"></param>
        private void RenderViewPort(ViewPort viewPort, Rectangle clientRectangle, PickingGeometryType pickingGeometryType)
        {
            if (viewPort.Enabled)
            {
                // render in this view port.
                if (viewPort.Visiable)
                {
                    // render scene in this view port.
                    viewPort.Render(this, clientRectangle, pickingGeometryType);
                }

                // render children viewport.
                foreach (ViewPort item in viewPort.Children)
                {
                    this.RenderViewPort(item, clientRectangle, pickingGeometryType);
                }
            }
        }
예제 #15
0
        /// <summary>
        /// render scene in every view port.
        /// </summary>
        /// <param name="viewPort"></param>
        /// <param name="clientRectangle"></param>
        /// <param name="pickingGeometryType"></param>
        private void RenderViewPort(ViewPort viewPort, Rectangle clientRectangle, PickingGeometryType pickingGeometryType)
        {
            if (viewPort.Enabled)
            {
                // render in this view port.
                if (viewPort.Visiable)
                {
                    // render scene in this view port.
                    viewPort.Render(this, clientRectangle, pickingGeometryType);
                }

                // render children viewport.
                foreach (ViewPort item in viewPort.Children)
                {
                    this.RenderViewPort(item, clientRectangle, pickingGeometryType);
                }
            }
        }
예제 #16
0
        /// <summary>
        /// Get geometry at specified <paramref name="mousePosition"/> with specified <paramref name="pickingGeometryType"/>.
        /// <para>Returns null when <paramref name="mousePosition"/> is out of this scene's area or there's no active(visible and enabled) viewport.</para>
        /// </summary>
        /// <param name="mousePosition">mouse position in Windows coordinate system.(Left Up is (0, 0))</param>
        /// <param name="pickingGeometryType">target's geometry type.</param>
        /// <returns></returns>
        public List <Tuple <Point, PickedGeometry> > Pick(Point mousePosition, PickingGeometryType pickingGeometryType)
        {
            Rectangle clientRectangle = this.Canvas.ClientRectangle;

            // if mouse is out of window's area, nothing picked.
            if (mousePosition.X < 0 || clientRectangle.Width <= mousePosition.X || mousePosition.Y < 0 || clientRectangle.Height <= mousePosition.Y)
            {
                return(null);
            }

            int x = mousePosition.X;
            int y = clientRectangle.Height - mousePosition.Y - 1;
            // now (x, y) is in OpenGL's window cooridnate system.
            Point position    = new Point(x, y);
            var   pickingRect = new Rectangle(x, y, 1, 1);
            List <Tuple <Point, PickedGeometry> > allPickedGeometrys = null;

            allPickedGeometrys = ColorCodedPicking(pickingRect, clientRectangle, pickingGeometryType);

            return(allPickedGeometrys);
        }
예제 #17
0
        /// <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);
        }
예제 #18
0
        private void RenderColorCoded(Scene scene, Rectangle clientRectangle, PickingGeometryType pickingGeometryType)
        {
            var color = new vec4(1, 1, 1, 1);

            OpenGL.glClearColor(color.x, color.y, color.z, color.w);

            OpenGL.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT | OpenGL.GL_STENCIL_BUFFER_BIT);

            var arg = new RenderEventArgs(clientRectangle, this, pickingGeometryType);
            // render objects.
            // Render all PickableRenderers for color-coded picking.
            List <IPickable> pickableRendererList = scene.Render4Picking(arg);

            //// render regular UI.
            //this.RootUI.Render(arg);

            //// render cursor.
            //UICursor cursor = this.Cursor;
            //if (cursor != null && cursor.Enabled)
            //{
            //    cursor.UpdatePosition(mousePosition);
            //    this.rootCursor.Render(arg);
            //}
        }
예제 #19
0
        /// <summary>
        /// Get geometry at specified <paramref name="mousePosition"/> with specified <paramref name="pickingGeometryType"/>.
        /// <para>Returns null when <paramref name="mousePosition"/> is out of this scene's area or there's no active(visible and enabled) viewport.</para>
        /// </summary>
        /// <param name="mousePosition">mouse position in Windows coordinate system.(Left Up is (0, 0))</param>
        /// <param name="pickingGeometryType">target's geometry type.</param>
        /// <returns></returns>
        public List<Tuple<Point, PickedGeometry>> Pick(Point mousePosition, PickingGeometryType pickingGeometryType)
        {
            Rectangle clientRectangle = this.Canvas.ClientRectangle;
            // if mouse is out of window's area, nothing picked.
            if (mousePosition.X < 0 || clientRectangle.Width <= mousePosition.X || mousePosition.Y < 0 || clientRectangle.Height <= mousePosition.Y) { return null; }

            int x = mousePosition.X;
            int y = clientRectangle.Height - mousePosition.Y - 1;
            // now (x, y) is in OpenGL's window cooridnate system.
            Point position = new Point(x, y);
            var pickingRect = new Rectangle(x, y, 1, 1);
            List<Tuple<Point, PickedGeometry>> allPickedGeometrys = null;
            foreach (ViewPort viewPort in this.rootViewPort.Traverse(TraverseOrder.Post))
            {
                if (viewPort.Visiable && viewPort.Enabled && viewPort.Contains(position))
                {
                    allPickedGeometrys = ColorCodedPicking(viewPort, pickingRect, clientRectangle, pickingGeometryType);

                    break;
                }
            }

            return allPickedGeometrys;
        }
        /// <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>
        /// <returns></returns>
        public override PickedGeometry GetPickedGeometry(RenderEventArgs arg, uint stageVertexId,
                                                         int x, int y)
        {
            uint lastVertexId;

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

            PickingGeometryType geometryType = arg.PickingGeometryType;

            if (geometryType == PickingGeometryType.Point)
            {
                DrawMode            mode       = this.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, x, y, lastVertexId, searcher));
                    }
                    else
                    {
                        throw new Exception(string.Format("Lack of searcher for [{0}]", mode));
                    }
                }
            }
            else if (geometryType == PickingGeometryType.Line)
            {
                DrawMode            mode       = this.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, x, y, 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.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)); }
            }
        }
        private PickedGeometry PickWhateverItIs(RenderEventArgs 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.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 NotImplementedException();
                }
            }

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

            return(pickedGeometry);
        }
예제 #22
0
 // TODO: big bug: when mouse is picking something and move outside of viewport to anothher one, camera will go wrong.
 /// <summary>
 /// Initializes a new instance of the <see cref="RenderEventArgs"/> class.
 /// </summary>
 /// <param name="camera"></param>
 /// <param name="canvasRect"></param>
 /// <param name="pickingGeometryType">Target geometry type(point, line, triangle, quad or polygon) for color-coded-picking; otherwise useless.</param>
 public RenderEventArgs(ICamera camera, Rectangle canvasRect, PickingGeometryType pickingGeometryType)
 {
     this.Camera              = camera;
     this.CanvasRect          = canvasRect;
     this.PickingGeometryType = pickingGeometryType;
 }
예제 #23
0
 // TODO: big bug: when mouse is picking something and move outside of viewport to anothher one, camera will go wrong.
 /// <summary>
 /// Initializes a new instance of the <see cref="RenderEventArgs"/> class.
 /// </summary>
 /// <param name="canvasRect"></param>
 /// <param name="viewPort">camera used during rendering.</param>
 /// <param name="pickingGeometryType">Target geometry type(point, line, triangle, quad or polygon) for color-coded-picking; otherwise useless.</param>
 public RenderEventArgs(Rectangle canvasRect, ViewPort viewPort, PickingGeometryType pickingGeometryType)
 {
     this.CanvasRect          = canvasRect;
     this.UsingViewPort       = viewPort;
     this.PickingGeometryType = pickingGeometryType;
 }
예제 #24
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(RenderEventArgs arg, uint stageVertexId, RecognizedPrimitiveInfo primitiveInfo, PickingGeometryType typeOfMode)
        {
            uint[] vertexIds      = primitiveInfo.VertexIds;
            vec3[] positions      = FillPickedGeometrysPosition(vertexIds);
            var    pickedGeometry = new PickedGeometry(typeOfMode, positions, vertexIds, stageVertexId, this);

            return(pickedGeometry);
        }
        private PickedGeometry PickWhateverItIs(RenderEventArgs 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.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 NotImplementedException();
                }
            }

            PickedGeometry pickedGeometry = new PickedGeometry(arg.UsingViewPort, typeOfMode, positions, vertexIds, stageVertexId, this);
            return pickedGeometry;
        }
        private void UpdatePolygonMode(PickingGeometryType geometryType)
        {
            switch (geometryType)
            {
                case PickingGeometryType.None:
                    // whatever it is.
                    polygonModeState.Mode = PolygonMode.Point;
                    break;

                case PickingGeometryType.Point:
                    polygonModeState.Mode = PolygonMode.Point;
                    break;

                case PickingGeometryType.Line:
                    polygonModeState.Mode = PolygonMode.Line;
                    break;

                case PickingGeometryType.Triangle:
                    polygonModeState.Mode = PolygonMode.Fill;
                    break;

                case PickingGeometryType.Quad:
                    polygonModeState.Mode = PolygonMode.Fill;
                    break;

                case PickingGeometryType.Polygon:
                    polygonModeState.Mode = PolygonMode.Fill;
                    break;

                default:
                    throw new NotImplementedException();
            }
        }
예제 #27
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>
        /// <returns></returns>
        public override PickedGeometry GetPickedGeometry(RenderEventArgs arg, uint stageVertexId,
                                                         int x, int y)
        {
            uint lastVertexId;

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

            // 找到 lastIndexId
            RecognizedPrimitiveInfo lastIndexId = this.GetLastIndexIdOfPickedGeometry(
                arg, lastVertexId, x, y);

            if (lastIndexId == null)
            {
                Debug.WriteLine(string.Format(
                                    "Got lastVertexId[{0}] but no lastIndexId! Params are [{1}] [{2}] [{3}] [{4}]",
                                    lastVertexId, arg, stageVertexId, x, y));
                { return(null); }
            }

            PickingGeometryType geometryType = arg.PickingGeometryType;
            DrawMode            mode         = this.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, x, y, 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, x, y, lastVertexId, 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)); }
            }
        }
예제 #28
0
 // TODO: big bug: when mouse is picking something and move outside of viewport to anothher one, camera will go wrong.
 /// <summary>
 /// Initializes a new instance of the <see cref="RenderEventArgs"/> class.
 /// </summary>
 /// <param name="canvasRect"></param>
 /// <param name="viewPort">camera used during rendering.</param>
 /// <param name="pickingGeometryType">Target geometry type(point, line, triangle, quad or polygon) for color-coded-picking; otherwise useless.</param>
 public RenderEventArgs(Rectangle canvasRect, ViewPort viewPort, PickingGeometryType pickingGeometryType)
 {
     this.CanvasRect = canvasRect;
     this.UsingViewPort = viewPort;
     this.PickingGeometryType = pickingGeometryType;
 }
        /// <summary>
        /// Convert <see cref="DrawMode"/> to <see cref="PickingGeometryType"/>.
        /// </summary>
        /// <param name="mode"></param>
        /// <returns></returns>
        public static PickingGeometryType ToGeometryType(this DrawMode mode)
        {
            PickingGeometryType result = PickingGeometryType.Point;

            switch (mode)
            {
            case DrawMode.Points:
                result = PickingGeometryType.Point;
                break;

            case DrawMode.LineStrip:
                result = PickingGeometryType.Line;
                break;

            case DrawMode.LineLoop:
                result = PickingGeometryType.Line;
                break;

            case DrawMode.Lines:
                result = PickingGeometryType.Line;
                break;

            case DrawMode.LineStripAdjacency:
                result = PickingGeometryType.Line;
                break;

            case DrawMode.LinesAdjacency:
                result = PickingGeometryType.Line;
                break;

            case DrawMode.TriangleStrip:
                result = PickingGeometryType.Triangle;
                break;

            case DrawMode.TriangleFan:
                result = PickingGeometryType.Triangle;
                break;

            case DrawMode.Triangles:
                result = PickingGeometryType.Triangle;
                break;

            case DrawMode.TriangleStripAdjacency:
                result = PickingGeometryType.Triangle;
                break;

            case DrawMode.TrianglesAdjacency:
                result = PickingGeometryType.Triangle;
                break;

            case DrawMode.Patches:    // this is about tessellation shader. I've no idea about it now.
                throw new NotImplementedException();

            case DrawMode.QuadStrip:
                result = PickingGeometryType.Quad;
                break;

            case DrawMode.Quads:
                result = PickingGeometryType.Quad;
                break;

            case DrawMode.Polygon:
                result = PickingGeometryType.Polygon;
                break;

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

            return(result);
        }
예제 #30
0
        /// <summary>
        /// Pick primitives in specified <paramref name="viewPort"/>.
        /// </summary>
        /// <param name="viewPort"></param>
        /// <param name="pickingRect">rect in OpenGL's window coordinate system.(Left Down is (0, 0)), size).</param>
        /// <param name="clientRectangle">whole canvas' rectangle.</param>
        /// <param name="pickingGeometryType"></param>
        /// <returns></returns>
        private List<Tuple<Point, PickedGeometry>> ColorCodedPicking(ViewPort viewPort, Rectangle pickingRect, Rectangle clientRectangle, PickingGeometryType pickingGeometryType)
        {
            var result = new List<Tuple<Point, PickedGeometry>>();

            // if depth buffer is valid in specified rect, then maybe something is picked.
            //if (DepthBufferValid(pickingRect))
            {
                lock (this.synObj)
                {
                    var arg = new RenderEventArgs(clientRectangle, viewPort, pickingGeometryType);
                    // Render all PickableRenderers for color-coded picking.
                    List<IPickable> pickableRendererList = Render4Picking(arg);
                    // Read pixels in specified rect and get the VertexIds they represent.
                    List<Tuple<Point, uint>> stageVertexIdList = ReadPixels(pickingRect);
                    // Get all picked geometrys.
                    foreach (Tuple<Point, uint> tuple in stageVertexIdList)
                    {
                        int x = tuple.Item1.X;
                        int y = tuple.Item1.Y;
                        //if (x < 0 || clientRectangle.Width <= x || y < 0 || clientRectangle.Height <= y) { continue; }

                        uint stageVertexId = tuple.Item2;
                        PickedGeometry pickedGeometry = GetPickGeometry(arg,
                           x, y, stageVertexId, pickableRendererList);
                        if (pickedGeometry != null)
                        {
                            result.Add(new Tuple<Point, PickedGeometry>(new Point(x, y), pickedGeometry));
                        }
                    }
                }
            }

            return result;
        }
예제 #31
0
        /// <summary>
        /// render scene in this view port.
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="clientRectangle"></param>
        /// <param name="pickingGeometryType"></param>
        public override void Render(Scene scene, System.Drawing.Rectangle clientRectangle, PickingGeometryType pickingGeometryType)
        {
            this.On();// limit rendering area.

            vec4 color = this.ClearColor.ToVec4();

            OpenGL.glClearColor(color.x, color.y, color.z, color.w);

            OpenGL.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT | OpenGL.GL_STENCIL_BUFFER_BIT);

            this.Off();// cancel limitation.
        }
예제 #32
0
        /// <summary>
        /// Pick primitives.
        /// </summary>
        /// <param name="pickingRect">rect in OpenGL's window coordinate system.(Left Down is (0, 0)), size).</param>
        /// <param name="clientRectangle">whole canvas' rectangle.</param>
        /// <param name="pickingGeometryType"></param>
        /// <returns></returns>
        private List <Tuple <Point, PickedGeometry> > ColorCodedPicking(Rectangle pickingRect, Rectangle clientRectangle, PickingGeometryType pickingGeometryType)
        {
            var result = new List <Tuple <Point, PickedGeometry> >();

            // if depth buffer is valid in specified rect, then maybe something is picked.
            //if (DepthBufferValid(pickingRect))
            {
                lock (this.synObj)
                {
                    var arg = new RenderEventArgs(this.FirstCamera, clientRectangle, pickingGeometryType);
                    // Render all PickableRenderers for color-coded picking.
                    List <IPickable> pickableRendererList = Render4Picking(arg);
                    // Read pixels in specified rect and get the VertexIds they represent.
                    List <Tuple <Point, uint> > stageVertexIdList = ReadPixels(pickingRect);
                    // Get all picked geometrys.
                    foreach (Tuple <Point, uint> tuple in stageVertexIdList)
                    {
                        int x = tuple.Item1.X;
                        int y = tuple.Item1.Y;
                        //if (x < 0 || clientRectangle.Width <= x || y < 0 || clientRectangle.Height <= y) { continue; }

                        uint           stageVertexId  = tuple.Item2;
                        PickedGeometry pickedGeometry = GetPickGeometry(arg,
                                                                        x, y, stageVertexId, pickableRendererList);
                        if (pickedGeometry != null)
                        {
                            result.Add(new Tuple <Point, PickedGeometry>(new Point(x, y), pickedGeometry));
                        }
                    }
                }
            }

            return(result);
        }
예제 #33
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(RenderEventArgs arg, uint stageVertexId, RecognizedPrimitiveInfo primitiveInfo, PickingGeometryType typeOfMode)
        {
            uint[] vertexIds = primitiveInfo.VertexIds;
            vec3[] positions = FillPickedGeometrysPosition(vertexIds);
            var pickedGeometry = new PickedGeometry(arg.UsingViewPort, typeOfMode, positions, vertexIds, stageVertexId, this);

            return pickedGeometry;
        }