/// <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); }
/// <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(); } }
/// <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); }
//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; }
//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; }
/// <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()); }
/// <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); } }
/// <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); } }
/// <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. }
/// <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); } }
/// <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. }
/// <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); } } }
/// <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); }
/// <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); }
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); //} }
/// <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); }
// 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; }
// 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> /// 是三角形,就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; }
/// <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)); } } }
/// <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); }
/// <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; }
/// <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); }
/// <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; }