/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="x">mouse position(Left Down is (0, 0)).</param> /// <param name="y">mouse position(Left Down is (0, 0)).</param> /// <param name="primitiveInfo"></param> /// <param name="modernRenderer"></param> /// <returns></returns> internal override uint[] Search(RenderEventArgs arg, int x, int y, RecognizedPrimitiveInfo primitiveInfo, OneIndexRenderer modernRenderer) { uint[] indexList = primitiveInfo.VertexIds; if (indexList.Length < 3) { throw new ArgumentException(); } OneIndexBuffer buffer = indexList.GenIndexBuffer(DrawMode.LineLoop, BufferUsage.StaticDraw); modernRenderer.Render4InnerPicking(arg, buffer); uint id = ColorCodedPicking.ReadStageVertexId(x, y); buffer.Dispose(); if (id == indexList[0]) { return new uint[] { indexList[indexList.Length - 1], id, }; } else { uint[] result = null; for (int i = 1; i < indexList.Length; i++) { if (id == indexList[i]) { result = new uint[] { indexList[i - 1], indexList[i], }; break; } } if (result != null) { return result; } else { throw new Exception("This should not happen!"); } } }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="x">mouse position(Left Down is (0, 0)).</param> /// <param name="y">mouse position(Left Down is (0, 0)).</param> /// <param name="primitiveInfo"></param> /// <param name="modernRenderer"></param> /// <returns></returns> internal override uint[] Search(RenderEventArgs arg, int x, int y, RecognizedPrimitiveInfo primitiveInfo, OneIndexRenderer modernRenderer) { uint[] indexList = primitiveInfo.VertexIds; if (indexList.Length != 3) { throw new ArgumentException(); } //if (indexList[0] == indexList[1]) { return new uint[] { indexList[0], indexList[2], }; } //else if (indexList[0] == indexList[2]) { return new uint[] { indexList[0], indexList[1], }; } //else if (indexList[1] == indexList[2]) { return new uint[] { indexList[1], indexList[0], }; } var targetIndexList = new uint[6] { indexList[0], indexList[1], indexList[1], indexList[2], indexList[2], indexList[0], }; OneIndexBuffer buffer = targetIndexList.GenIndexBuffer(DrawMode.Lines, BufferUsage.StaticDraw); modernRenderer.Render4InnerPicking(arg, buffer); uint id = ColorCodedPicking.ReadStageVertexId(x, y); buffer.Dispose(); if (id == indexList[1]) { return new uint[] { indexList[0], indexList[1], }; } else if (id == indexList[2]) { return new uint[] { indexList[1], indexList[2], }; } else if (id == indexList[0]) { return new uint[] { indexList[2], indexList[0], }; } else { throw new Exception("This should not happen!"); } }
protected override void RecognizeByte(uint lastVertexId, IntPtr pointer, OneIndexBuffer oneIndexBuffer, List<RecognizedPrimitiveInfo> primitiveInfoList, uint primitiveRestartIndex) { int length = oneIndexBuffer.Length; unsafe { var array = (byte*)pointer.ToPointer(); long nearestRestartIndex = -1; uint i = 0; while (i < length && array[i] == primitiveRestartIndex) { nearestRestartIndex = i; i++; } for (i = i + 1; i < length; i++) { var value = array[i]; if (value == primitiveRestartIndex) { nearestRestartIndex = i; } else if (value == lastVertexId && array[i - 1] != primitiveRestartIndex && (i - nearestRestartIndex) % 2 == 0) { var item = new RecognizedPrimitiveInfo(i, array[i - 1], lastVertexId); primitiveInfoList.Add(item); } } } }
/// <summary> /// 将共享点前移,构成2个图元组成的新的小小的索引。 /// </summary> /// <param name="recognizedPrimitiveIndex0"></param> /// <param name="recognizedPrimitiveIndex1"></param> /// <param name="drawMode"></param> /// <param name="lastIndex0"></param> /// <param name="lastIndex1"></param> /// <returns></returns> private List<uint> ArrangeIndexes( RecognizedPrimitiveInfo recognizedPrimitiveIndex0, RecognizedPrimitiveInfo recognizedPrimitiveIndex1, DrawMode drawMode, out uint lastIndex0, out uint lastIndex1) { var sameIndexList = new List<uint>(); var array0 = new List<uint>(recognizedPrimitiveIndex0.VertexIds); var array1 = new List<uint>(recognizedPrimitiveIndex1.VertexIds); array0.Sort(); array1.Sort(); int p0 = 0, p1 = 0; while (p0 < array0.Count && p1 < array1.Count) { if (array0[p0] < array1[p1]) { p0++; } else if (array0[p0] > array1[p1]) { p1++; } else { sameIndexList.Add(array0[p0]); array0.RemoveAt(p0); array1.RemoveAt(p1); } } if (array0.Count == 0 && array1.Count == 0) { throw new Exception("Two primitives are totally the same!"); } if (array0.Count > 0) { lastIndex0 = array0.Last(); } else { if (sameIndexList.Count == 0) { throw new Exception("array0 is totally empty!"); } lastIndex0 = sameIndexList.Last(); } if (array1.Count > 0) { lastIndex1 = array1.Last(); } else { if (sameIndexList.Count == 0) { throw new Exception("array1 is totally empty!"); } lastIndex1 = sameIndexList.Last(); } if (lastIndex0 == lastIndex1) { throw new Exception(); } var result = new List<uint>(); result.AddRange(sameIndexList); result.AddRange(array0); result.Add(uint.MaxValue);// primitive restart index result.AddRange(sameIndexList); result.AddRange(array1); return result; }
protected override void RecognizeUInt(uint lastVertexId, IntPtr pointer, OneIndexBuffer oneIndexBuffer, List<RecognizedPrimitiveInfo> primitiveInfoList) { int length = oneIndexBuffer.Length; unsafe { var array = (uint*)pointer.ToPointer(); for (uint i = 0; i < length; i++) { var value = array[i]; if (value == lastVertexId) { var item = new RecognizedPrimitiveInfo(i, value); primitiveInfoList.Add(item); } } } }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="x">mouse position(Left Down is (0, 0)).</param> /// <param name="y">mouse position(Left Down is (0, 0)).</param> /// <param name="primitiveInfo"></param> /// <param name="modernRenderer"></param> /// <returns></returns> internal override uint Search(RenderEventArgs arg, int x, int y, RecognizedPrimitiveInfo primitiveInfo, OneIndexRenderer modernRenderer) { uint[] indexList = primitiveInfo.VertexIds; if (indexList.Length < 3) { throw new ArgumentException(); } OneIndexBuffer buffer = indexList.GenIndexBuffer(DrawMode.Points, BufferUsage.StaticDraw); modernRenderer.Render4InnerPicking(arg, buffer); uint id = ColorCodedPicking.ReadStageVertexId(x, y); buffer.Dispose(); if (id != uint.MaxValue) { return id; } else { throw new Exception("This should not happen!"); } }
protected override void RecognizeByte(uint lastVertexId, IntPtr pointer, OneIndexBuffer oneIndexBuffer, List<RecognizedPrimitiveInfo> primitiveInfoList) { int length = oneIndexBuffer.Length; unsafe { var array = (byte*)pointer.ToPointer(); uint i = 0; for (i = i + 1; i < length; i++) { var value = array[i]; if (value == lastVertexId && (i + 1) % 2 == 0) { var item = new RecognizedPrimitiveInfo(i, array[i - 1], lastVertexId); primitiveInfoList.Add(item); } } } }
protected override void RecognizeUInt(uint lastVertexId, IntPtr pointer, OneIndexBuffer oneIndexBuffer, List<RecognizedPrimitiveInfo> primitiveInfoList) { int length = oneIndexBuffer.Length; unsafe { var array = (uint*)pointer.ToPointer(); long nearestRestartIndex = -1; uint i = 0; for (i = i + 3; i < length; i++) { var value = array[i]; if (value == lastVertexId && (i - nearestRestartIndex) % 4 == 0) { var item = new RecognizedPrimitiveInfo(i, array[i - 3], array[i - 2], array[i - 1], lastVertexId); primitiveInfoList.Add(item); } } } }
protected override void RecognizeUShort(uint lastVertexId, DrawElementsCmd cmd, List <RecognizedPrimitiveInfo> primitiveInfoList, uint primitiveRestartIndex) { IndexBuffer indexBuffer = cmd.IndexBufferObject; int length = indexBuffer.Length; IntPtr pointer = indexBuffer.MapBuffer(MapBufferAccess.ReadOnly); unsafe { var array = (ushort *)pointer.ToPointer(); long nearestRestartIndex = -1; uint i = 0; while (i < length && array[i] == primitiveRestartIndex) { nearestRestartIndex = i; i++; } for (i = i + 4; i < length; i++) { var value = array[i]; if (value == primitiveRestartIndex) { nearestRestartIndex = i; } else if (array[i + 1] != primitiveRestartIndex && value == lastVertexId && array[i - 1] != primitiveRestartIndex && array[i - 2] != primitiveRestartIndex && array[i - 3] != primitiveRestartIndex && array[i - 4] != primitiveRestartIndex && (i - 4 - nearestRestartIndex) % 6 == 0) { var item = new RecognizedPrimitiveInfo(i, array[i - 4], array[i - 2], lastVertexId); primitiveInfoList.Add(item); } } } indexBuffer.UnmapBuffer(); }
protected override void RecognizeUShort(uint lastVertexId, IntPtr pointer, DrawElementsCmd cmd, List <RecognizedPrimitiveInfo> primitiveInfoList) { int length = cmd.IndexBufferObject.Length; unsafe { var array = (ushort *)pointer.ToPointer(); for (uint i = 1; i < length; i++) { var value = array[i]; if (value == lastVertexId) { var item = new RecognizedPrimitiveInfo(i, array[i - 1], lastVertexId); primitiveInfoList.Add(item); } } if (array[0] == lastVertexId && length > 1) { var item = new RecognizedPrimitiveInfo(0, array[length - 1], lastVertexId); primitiveInfoList.Add(item); } } }
protected override void RecognizeUInt(uint flatColorVertexId, DrawElementsCmd cmd, List <RecognizedPrimitiveInfo> primitiveInfoList, uint primitiveRestartIndex) { IndexBuffer indexBuffer = cmd.IndexBufferObject; int length = indexBuffer.Length; IntPtr pointer = indexBuffer.MapBuffer(MapBufferAccess.ReadOnly); unsafe { var array = (uint *)pointer.ToPointer(); long nearestRestartIndex = -1; uint i = 0; while (i < length && array[i] == primitiveRestartIndex) { nearestRestartIndex = i; i++; } for (i = i + 3; i < length; i++) { var value = array[i]; if (value == primitiveRestartIndex) { // try the loop back line. nearestRestartIndex = i; } else if (value == flatColorVertexId && array[i - 1] != primitiveRestartIndex && array[i - 3] != primitiveRestartIndex && array[i - 2] != primitiveRestartIndex ) { var item = new RecognizedPrimitiveInfo(i, array[i - 2], array[i - 3], array[i - 1], flatColorVertexId); primitiveInfoList.Add(item); } } } indexBuffer.UnmapBuffer(); }
protected override void RecognizeByte(uint lastVertexId, IntPtr pointer, OneIndexBuffer oneIndexBuffer, List <RecognizedPrimitiveInfo> primitiveInfoList) { int length = oneIndexBuffer.VertexCount; unsafe { var array = (byte *)pointer.ToPointer(); for (uint i = 1; i < length; i++) { var value = array[i]; if (value == lastVertexId) { var item = new RecognizedPrimitiveInfo(i, array[i - 1], lastVertexId); primitiveInfoList.Add(item); } } if (array[0] == lastVertexId && length > 1) { var item = new RecognizedPrimitiveInfo(0, array[length - 1], lastVertexId); primitiveInfoList.Add(item); } } }
protected override void RecognizeUInt(uint lastVertexId, DrawElementsCmd cmd, List <RecognizedPrimitiveInfo> primitiveInfoList) { IndexBuffer indexBuffer = cmd.IndexBufferObject; int length = indexBuffer.Length; IntPtr pointer = indexBuffer.MapBuffer(MapBufferAccess.ReadOnly); unsafe { var array = (uint *)pointer.ToPointer(); long nearestRestartIndex = -1; uint i = 0; for (i = i + 3; i < length; i++) { var value = array[i]; if (value == lastVertexId && (i - nearestRestartIndex) % 4 == 0) { var item = new RecognizedPrimitiveInfo(i, array[i - 3], array[i - 2], array[i - 1], lastVertexId); primitiveInfoList.Add(item); } } } indexBuffer.UnmapBuffer(); }
/// <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)); } } }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="stageVertexId"></param> /// <param name="primitiveInfo"></param> /// <param name="searcher"></param> /// <returns></returns> private PickedGeometry SearchLine(PickingEventArgs arg, uint singleNodeVertexId, uint stageVertexId, RecognizedPrimitiveInfo primitiveInfo, DrawElementsLineSearcher searcher) { var vertexIds = searcher.Search(arg, primitiveInfo, singleNodeVertexId, stageVertexId, this); vec3[] positions = FillPickedGeometrysPosition(vertexIds); var pickedGeometry = new PickedGeometry(GeometryType.Line, positions, vertexIds, stageVertexId, this.Node); return(pickedGeometry); }
/// <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(PickingEventArgs arg, uint stageVertexId, RecognizedPrimitiveInfo primitiveInfo, GeometryType typeOfMode) { uint[] vertexIds = primitiveInfo.VertexIds; vec3[] positions = FillPickedGeometrysPosition(vertexIds); var pickedGeometry = new PickedGeometry(typeOfMode, positions, vertexIds, stageVertexId, this.Node); return(pickedGeometry); }
/// <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)); } } }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="stageVertexId"></param> /// <param name="singleNodeVertexId"></param> /// <param name="primitiveInfo"></param> /// <param name="searcher"></param> /// <returns></returns> private PickedGeometry SearchPoint(PickingEventArgs arg, uint singleNodeVertexId, uint stageVertexId, RecognizedPrimitiveInfo primitiveInfo, DrawElementsPointSearcher searcher) { uint id = searcher.Search(arg, primitiveInfo, singleNodeVertexId, stageVertexId, this); if (id == uint.MaxValue) { return(null); } // Scene's changed before second rendering for picking> uint baseId = stageVertexId - singleNodeVertexId; var vertexIds = new uint[] { (id - baseId) }; vec3[] positions = FillPickedGeometrysPosition(vertexIds); var pickedGeometry = new PickedGeometry(GeometryType.Point, positions, vertexIds, stageVertexId, this.Node); return(pickedGeometry); }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="stageVertexId"></param> /// <param name="lastVertexId"></param> /// <param name="primitiveInfo"></param> /// <param name="searcher"></param> /// <returns></returns> private PickedGeometry SearchPoint(PickingEventArgs arg, uint stageVertexId, uint lastVertexId, RecognizedPrimitiveInfo primitiveInfo, OneIndexPointSearcher searcher) { var vertexIds = new uint[] { searcher.Search(arg, primitiveInfo, this), }; vec3[] positions = FillPickedGeometrysPosition(vertexIds); var pickedGeometry = new PickedGeometry(GeometryType.Point, positions, vertexIds, stageVertexId, this.Renderer); return(pickedGeometry); }
/// <summary> /// 将共享点前移,然后重新渲染、拾取 /// </summary> /// <param name="recognizedPrimitiveIndex0"></param> /// <param name="recognizedPrimitiveIndex1"></param> /// <param name="drawMode"></param> /// <param name="oneIndexBuffer"></param> /// <param name="lastIndex0"></param> /// <param name="lastIndex1"></param> private void AssembleIndexBuffer( RecognizedPrimitiveInfo recognizedPrimitiveIndex0, RecognizedPrimitiveInfo recognizedPrimitiveIndex1, DrawMode drawMode, out OneIndexBuffer oneIndexBuffer, out uint lastIndex0, out uint lastIndex1) { List<uint> indexArray = ArrangeIndexes( recognizedPrimitiveIndex0, recognizedPrimitiveIndex1, drawMode, out lastIndex0, out lastIndex1); if (indexArray.Count != recognizedPrimitiveIndex0.VertexIds.Length + 1 + recognizedPrimitiveIndex1.VertexIds.Length) { throw new Exception(string.Format("index array[{0}] not same length with [recognized primitive1 index length{1}] + [1] + recognized primitive2 index length[{2}]", recognizedPrimitiveIndex0.VertexIds.Length, recognizedPrimitiveIndex1.VertexIds.Length)); } oneIndexBuffer = indexArray.ToArray().GenIndexBuffer(drawMode, BufferUsage.StaticDraw); //oneIndexBuffer = Buffer.Create(IndexElementType.UInt, // recognizedPrimitiveIndex0.VertexIds.Length // + 1 // + recognizedPrimitiveIndex1.VertexIds.Length, // drawMode, BufferUsage.StaticDraw); //unsafe //{ // var array = (uint*)oneIndexBuffer.MapBuffer(MapBufferAccess.WriteOnly); // for (int i = 0; i < indexArray.Count; i++) // { // array[i] = indexArray[i]; // } // oneIndexBuffer.UnmapBuffer(); //} }
private PickedGeometry SearchLine(RenderEventArgs arg, uint stageVertexId, int x, int y, uint lastVertexId, RecognizedPrimitiveInfo primitiveInfo, OneIndexLineSearcher searcher) { PickedGeometry pickedGeometry = new PickedGeometry(); pickedGeometry.From = this; pickedGeometry.GeometryType = GeometryType.Line; pickedGeometry.StageVertexId = stageVertexId; pickedGeometry.VertexIds = searcher.Search(arg, x, y, primitiveInfo, this); pickedGeometry.Positions = FillPickedGeometrysPosition(pickedGeometry.VertexIds); 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> /// <param name="lastVertexId"></param> /// <param name="primitiveInfo"></param> /// <param name="searcher"></param> /// <returns></returns> private PickedGeometry SearchPoint(RenderEventArgs arg, uint stageVertexId, int x, int y, uint lastVertexId, RecognizedPrimitiveInfo primitiveInfo, OneIndexPointSearcher searcher) { var vertexIds = new uint[] { searcher.Search(arg, x, y, primitiveInfo, this), }; vec3[] positions = FillPickedGeometrysPosition(vertexIds); var pickedGeometry = new PickedGeometry(arg.UsingViewPort, PickingGeometryType.Point, positions, vertexIds, stageVertexId, this); return pickedGeometry; }
/// <summary> /// 将共享点前移,构成2个图元组成的新的小小的索引。 /// </summary> /// <param name="recognizedPrimitiveIndex0"></param> /// <param name="recognizedPrimitiveIndex1"></param> /// <param name="drawMode"></param> /// <param name="lastIndex0"></param> /// <param name="lastIndex1"></param> /// <returns></returns> private List <uint> ArrangeIndexes( RecognizedPrimitiveInfo recognizedPrimitiveIndex0, RecognizedPrimitiveInfo recognizedPrimitiveIndex1, DrawMode drawMode, out uint lastIndex0, out uint lastIndex1) { var sameIndexList = new List <uint>(); var array0 = new List <uint>(recognizedPrimitiveIndex0.VertexIds); var array1 = new List <uint>(recognizedPrimitiveIndex1.VertexIds); array0.Sort(); array1.Sort(); int p0 = 0, p1 = 0; while (p0 < array0.Count && p1 < array1.Count) { if (array0[p0] < array1[p1]) { p0++; } else if (array0[p0] > array1[p1]) { p1++; } else { sameIndexList.Add(array0[p0]); array0.RemoveAt(p0); array1.RemoveAt(p1); } } if (array0.Count == 0 && array1.Count == 0) { throw new Exception("Two primitives are totally the same!"); } if (array0.Count > 0) { lastIndex0 = array0.Last(); } else { if (sameIndexList.Count == 0) { throw new Exception("array0 is totally empty!"); } lastIndex0 = sameIndexList.Last(); } if (array1.Count > 0) { lastIndex1 = array1.Last(); } else { if (sameIndexList.Count == 0) { throw new Exception("array1 is totally empty!"); } lastIndex1 = sameIndexList.Last(); } if (lastIndex0 == lastIndex1) { throw new Exception(); } var result = new List <uint>(); result.AddRange(sameIndexList); result.AddRange(array0); result.Add(uint.MaxValue);// primitive restart index result.AddRange(sameIndexList); result.AddRange(array1); return(result); }
protected override void RecognizeUShort(uint lastVertexId, IntPtr pointer, OneIndexBuffer oneIndexBuffer, List<RecognizedPrimitiveInfo> primitiveInfoList, uint primitiveRestartIndex) { int length = oneIndexBuffer.Length; unsafe { var array = (ushort*)pointer.ToPointer(); long nearestRestartIndex = -1; uint i = 0; while (i < length && array[i] == primitiveRestartIndex) { nearestRestartIndex = i; i++; } for (i = i + 3; i < length; i++) { var value = array[i]; if (value == primitiveRestartIndex) { // try the loop back line. nearestRestartIndex = i; } else if (value == lastVertexId && array[i - 1] != primitiveRestartIndex && array[i - 3] != primitiveRestartIndex && array[i - 2] != primitiveRestartIndex ) { var item = new RecognizedPrimitiveInfo(i, array[i - 2], array[i - 3], array[i - 1], lastVertexId); primitiveInfoList.Add(item); } } } }
/// <summary> /// /// </summary> /// <param name="arg"></param> /// <param name="stageVertexId"></param> /// <param name="x">mouse position(Left Down is (0, 0)).</param> /// <param name="y">mouse position(Left Down is (0, 0)).</param> /// <param name="lastVertexId"></param> /// <param name="primitiveInfo"></param> /// <param name="searcher"></param> /// <returns></returns> private PickedGeometry SearchLine(RenderEventArgs arg, uint stageVertexId, int x, int y, uint lastVertexId, RecognizedPrimitiveInfo primitiveInfo, OneIndexLineSearcher searcher) { var vertexIds = searcher.Search(arg, x, y, primitiveInfo, this); vec3[] positions = FillPickedGeometrysPosition(vertexIds); var pickedGeometry = new PickedGeometry(PickingGeometryType.Line, 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> /// 是三角形,就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; }