private static ClipTriangle[] initClipBuffer(int size) { ClipTriangle[] triangleArray = new ClipTriangle[size]; for (int i = 0; i < size; i++) { triangleArray[i].corner = new Vector3[3]; triangleArray[i].uv = new Vector2[3]; triangleArray[i].color = new Color32[3]; } return(triangleArray); }
private static ClipTriangle[] initClipBuffer(int size) { var buffer = new ClipTriangle[size]; for (int i = 0; i < size; i++) { buffer[i].corner = new Vector3[3]; buffer[i].uv = new Vector2[3]; buffer[i].color = new Color[3]; } return(buffer); }
/// <summary> /// Hull making. /// </summary> /// <remarks>Based/Completely from http://www.xbdev.net/physics/MinkowskiDifference/index.php /// I don't (100%) see why this should always work. /// </remarks> /// <param name="triangleList"></param> /// <param name="generationThreshold"></param> public virtual void MakeHull(ref List <TSVector> triangleList, int generationThreshold) { FP distanceThreshold = FP.Zero; if (generationThreshold < 0) { generationThreshold = 4; } Stack <ClipTriangle> activeTriList = new Stack <ClipTriangle>(); TSVector[] v = new TSVector[] // 6 Array { new TSVector(-1, 0, 0), new TSVector(1, 0, 0), new TSVector(0, -1, 0), new TSVector(0, 1, 0), new TSVector(0, 0, -1), new TSVector(0, 0, 1), }; int[,] kTriangleVerts = new int[8, 3] // 8 x 3 Array { { 5, 1, 3 }, { 4, 3, 1 }, { 3, 4, 0 }, { 0, 5, 3 }, { 5, 2, 1 }, { 4, 1, 2 }, { 2, 0, 4 }, { 0, 2, 5 } }; for (int i = 0; i < 8; i++) { ClipTriangle tri = new ClipTriangle(); tri.n1 = v[kTriangleVerts[i, 0]]; tri.n2 = v[kTriangleVerts[i, 1]]; tri.n3 = v[kTriangleVerts[i, 2]]; tri.generation = 0; activeTriList.Push(tri); } // surfaceTriList while (activeTriList.Count > 0) { ClipTriangle tri = activeTriList.Pop(); TSVector p1; SupportMapping(ref tri.n1, out p1); TSVector p2; SupportMapping(ref tri.n2, out p2); TSVector p3; SupportMapping(ref tri.n3, out p3); FP d1 = (p2 - p1).sqrMagnitude; FP d2 = (p3 - p2).sqrMagnitude; FP d3 = (p1 - p3).sqrMagnitude; if (TSMath.Max(TSMath.Max(d1, d2), d3) > distanceThreshold && tri.generation < generationThreshold) { ClipTriangle tri1 = new ClipTriangle(); ClipTriangle tri2 = new ClipTriangle(); ClipTriangle tri3 = new ClipTriangle(); ClipTriangle tri4 = new ClipTriangle(); tri1.generation = tri.generation + 1; tri2.generation = tri.generation + 1; tri3.generation = tri.generation + 1; tri4.generation = tri.generation + 1; tri1.n1 = tri.n1; tri2.n2 = tri.n2; tri3.n3 = tri.n3; TSVector n = FP.Half * (tri.n1 + tri.n2); n.Normalize(); tri1.n2 = n; tri2.n1 = n; tri4.n3 = n; n = FP.Half * (tri.n2 + tri.n3); n.Normalize(); tri2.n3 = n; tri3.n2 = n; tri4.n1 = n; n = FP.Half * (tri.n3 + tri.n1); n.Normalize(); tri1.n3 = n; tri3.n1 = n; tri4.n2 = n; activeTriList.Push(tri1); activeTriList.Push(tri2); activeTriList.Push(tri3); activeTriList.Push(tri4); } else { if (((p3 - p1) % (p2 - p1)).sqrMagnitude > TSMath.Epsilon) { triangleList.Add(p1); triangleList.Add(p2); triangleList.Add(p3); } } } }
private static int clipToPlane(Plane plane, ref ClipTriangle triangle, ClipTriangle[] dest, int destIndex) { var verts = triangle.corner; var numInside = 0; var outside = 0; var planeNormal = plane.normal; var planeDist = plane.distance; for (int i = 0; i < 3; i++) { if (Vector3.Dot(planeNormal, verts[i]) + planeDist > 0) { inside[numInside++] = i; } else { outside = i; } } // Entire triangle is in front of the plane if (numInside == 3) { triangle.CopyTo(ref dest[destIndex]); return(1); } // Entire triangle is behind the plane if (numInside == 0) { return(0); } // We've got vertices on either side of the plane, need to slice... // TODO: Currently always splits in the same direction. Modify so split retains largest triangle area? if (numInside == 1) { var i0 = inside[0]; var i1 = (i0 + 1) % 3; var i2 = (i0 + 2) % 3; var va = verts[i0]; var vb = verts[i1]; var vc = verts[i2]; var uva = triangle.uv[i0]; var uvb = triangle.uv[i1]; var uvc = triangle.uv[i2]; var ca = triangle.color[i0]; var cb = triangle.color[i1]; var cc = triangle.color[i2]; var distance = 0f; var dir = vb - va; var ray = new Ray(va, dir.normalized); plane.Raycast(ray, out distance); var lerpDist = distance / dir.magnitude; var v1 = ray.GetPoint(distance); var uv1 = Vector2.Lerp(uva, uvb, lerpDist); var c1 = Color.Lerp(ca, cb, lerpDist); dir = vc - va; ray = new Ray(va, dir.normalized); plane.Raycast(ray, out distance); lerpDist = distance / dir.magnitude; var v2 = ray.GetPoint(distance); var uv2 = Vector2.Lerp(uva, uvc, lerpDist); var c2 = Color.Lerp(ca, cc, lerpDist); dest[destIndex].corner[0] = va; dest[destIndex].corner[1] = v1; dest[destIndex].corner[2] = v2; dest[destIndex].uv[0] = uva; dest[destIndex].uv[1] = uv1; dest[destIndex].uv[2] = uv2; dest[destIndex].color[0] = ca; dest[destIndex].color[1] = c1; dest[destIndex].color[2] = c2; return(1); } else { var i0 = outside; var i1 = (i0 + 1) % 3; var i2 = (i0 + 2) % 3; var va = verts[i0]; var vb = verts[i1]; var vc = verts[i2]; var uva = triangle.uv[i0]; var uvb = triangle.uv[i1]; var uvc = triangle.uv[i2]; var ca = triangle.color[i0]; var cb = triangle.color[i1]; var cc = triangle.color[i2]; var dir = vb - va; var ray = new Ray(va, dir.normalized); var distance = 0f; plane.Raycast(ray, out distance); var lerpDist = distance / dir.magnitude; var v1 = ray.GetPoint(distance); var uv1 = Vector2.Lerp(uva, uvb, lerpDist); var c1 = Color.Lerp(ca, cb, lerpDist); dir = vc - va; ray = new Ray(va, dir.normalized); plane.Raycast(ray, out distance); lerpDist = distance / dir.magnitude; var v2 = ray.GetPoint(distance); var uv2 = Vector2.Lerp(uva, uvc, lerpDist); var c2 = Color.Lerp(ca, cc, lerpDist); dest[destIndex].corner[0] = v1; dest[destIndex].corner[1] = vb; dest[destIndex].corner[2] = v2; dest[destIndex].uv[0] = uv1; dest[destIndex].uv[1] = uvb; dest[destIndex].uv[2] = uv2; dest[destIndex].color[0] = c1; dest[destIndex].color[1] = cb; dest[destIndex].color[2] = c2; destIndex++; dest[destIndex].corner[0] = v2; dest[destIndex].corner[1] = vb; dest[destIndex].corner[2] = vc; dest[destIndex].uv[0] = uv2; dest[destIndex].uv[1] = uvb; dest[destIndex].uv[2] = uvc; dest[destIndex].color[0] = c2; dest[destIndex].color[1] = cb; dest[destIndex].color[2] = cc; return(2); } }
public void CopyTo(ref ClipTriangle target) { Array.Copy(this.corner, target.corner, 3); Array.Copy(this.uv, target.uv, 3); Array.Copy(this.color, target.color, 3); }
/// <summary> /// Hull making. /// </summary> /// <remarks>Based/Completely from http://www.xbdev.net/physics/MinkowskiDifference/index.php /// I don't (100%) see why this should always work. /// </remarks> /// <param name="triangleList"></param> /// <param name="generationThreshold"></param> public virtual void MakeHull(ref List <Vector3> triangleList, int generationThreshold) { float distanceThreshold = 0.0f; if (generationThreshold < 0) { generationThreshold = 4; } Stack <ClipTriangle> activeTriList = new Stack <ClipTriangle>(); Vector3[] v = new Vector3[] // 6 Array { new Vector3(-1, 0, 0), new Vector3(1, 0, 0), new Vector3(0, -1, 0), new Vector3(0, 1, 0), new Vector3(0, 0, -1), new Vector3(0, 0, 1), }; int[,] kTriangleVerts = new int[8, 3] // 8 x 3 Array { { 5, 1, 3 }, { 4, 3, 1 }, { 3, 4, 0 }, { 0, 5, 3 }, { 5, 2, 1 }, { 4, 1, 2 }, { 2, 0, 4 }, { 0, 2, 5 } }; for (int i = 0; i < 8; i++) { ClipTriangle tri = new ClipTriangle(); tri.n1 = v[kTriangleVerts[i, 0]]; tri.n2 = v[kTriangleVerts[i, 1]]; tri.n3 = v[kTriangleVerts[i, 2]]; tri.generation = 0; activeTriList.Push(tri); } List <Vector3> pointSet = new List <Vector3>(); // surfaceTriList while (activeTriList.Count > 0) { ClipTriangle tri = activeTriList.Pop(); Vector3 p1; SupportMapping(ref tri.n1, out p1); Vector3 p2; SupportMapping(ref tri.n2, out p2); Vector3 p3; SupportMapping(ref tri.n3, out p3); float d1 = (p2 - p1).LengthSquared(); float d2 = (p3 - p2).LengthSquared(); float d3 = (p1 - p3).LengthSquared(); if (Math.Max(Math.Max(d1, d2), d3) > distanceThreshold && tri.generation < generationThreshold) { ClipTriangle tri1 = new ClipTriangle(); ClipTriangle tri2 = new ClipTriangle(); ClipTriangle tri3 = new ClipTriangle(); ClipTriangle tri4 = new ClipTriangle(); tri1.generation = tri.generation + 1; tri2.generation = tri.generation + 1; tri3.generation = tri.generation + 1; tri4.generation = tri.generation + 1; tri1.n1 = tri.n1; tri2.n2 = tri.n2; tri3.n3 = tri.n3; Vector3 n = 0.5f * (tri.n1 + tri.n2); n.Normalize(); tri1.n2 = n; tri2.n1 = n; tri4.n3 = n; n = 0.5f * (tri.n2 + tri.n3); n.Normalize(); tri2.n3 = n; tri3.n2 = n; tri4.n1 = n; n = 0.5f * (tri.n3 + tri.n1); n.Normalize(); tri1.n3 = n; tri3.n1 = n; tri4.n2 = n; activeTriList.Push(tri1); activeTriList.Push(tri2); activeTriList.Push(tri3); activeTriList.Push(tri4); } else { if (((p3 - p1) % (p2 - p1)).LengthSquared() > Mathf.Epsilon) { triangleList.Add(p1); triangleList.Add(p2); triangleList.Add(p3); } } } }
/// <summary> /// Hull making. /// </summary> /// <remarks>Based/Completely from http://www.xbdev.net/physics/MinkowskiDifference/index.php /// I don't (100%) see why this should always work. /// </remarks> /// <param name="triangleList"></param> /// <param name="generationThreshold"></param> public virtual void MakeHull(ref List<JVector> triangleList, int generationThreshold) { double distanceThreshold = 0.0f; if (generationThreshold < 0) generationThreshold = 4; Stack<ClipTriangle> activeTriList = new Stack<ClipTriangle>(); JVector[] v = new JVector[] // 6 Array { new JVector( -1, 0, 0 ), new JVector( 1, 0, 0 ), new JVector( 0, -1, 0 ), new JVector( 0, 1, 0 ), new JVector( 0, 0, -1 ), new JVector( 0, 0, 1 ), }; int[,] kTriangleVerts = new int[8, 3] // 8 x 3 Array { { 5, 1, 3 }, { 4, 3, 1 }, { 3, 4, 0 }, { 0, 5, 3 }, { 5, 2, 1 }, { 4, 1, 2 }, { 2, 0, 4 }, { 0, 2, 5 } }; for (int i = 0; i < 8; i++) { ClipTriangle tri = new ClipTriangle(); tri.n1 = v[kTriangleVerts[i, 0]]; tri.n2 = v[kTriangleVerts[i, 1]]; tri.n3 = v[kTriangleVerts[i, 2]]; tri.generation = 0; activeTriList.Push(tri); } List<JVector> pointSet = new List<JVector>(); // surfaceTriList while (activeTriList.Count > 0) { ClipTriangle tri = activeTriList.Pop(); JVector p1; SupportMapping(ref tri.n1, out p1); JVector p2; SupportMapping(ref tri.n2, out p2); JVector p3; SupportMapping(ref tri.n3, out p3); double d1 = (p2 - p1).LengthSquared(); double d2 = (p3 - p2).LengthSquared(); double d3 = (p1 - p3).LengthSquared(); if (Math.Max(Math.Max(d1, d2), d3) > distanceThreshold && tri.generation < generationThreshold) { ClipTriangle tri1 = new ClipTriangle(); ClipTriangle tri2 = new ClipTriangle(); ClipTriangle tri3 = new ClipTriangle(); ClipTriangle tri4 = new ClipTriangle(); tri1.generation = tri.generation + 1; tri2.generation = tri.generation + 1; tri3.generation = tri.generation + 1; tri4.generation = tri.generation + 1; tri1.n1 = tri.n1; tri2.n2 = tri.n2; tri3.n3 = tri.n3; JVector n = 0.5f * (tri.n1 + tri.n2); n.Normalize(); tri1.n2 = n; tri2.n1 = n; tri4.n3 = n; n = 0.5f * (tri.n2 + tri.n3); n.Normalize(); tri2.n3 = n; tri3.n2 = n; tri4.n1 = n; n = 0.5f * (tri.n3 + tri.n1); n.Normalize(); tri1.n3 = n; tri3.n1 = n; tri4.n2 = n; activeTriList.Push(tri1); activeTriList.Push(tri2); activeTriList.Push(tri3); activeTriList.Push(tri4); } else { if (((p3 - p1) % (p2 - p1)).LengthSquared() > JMath.Epsilon) { triangleList.Add(p1); triangleList.Add(p2); triangleList.Add(p3); } } } }
private static int clipToPlane(Plane plane, ClipTriangle triangle, ClipTriangle[] dest, int destIndex) { Vector3[] corner = triangle.corner; int num = 0; int num2 = 0; Vector3 normal = plane.normal; float distance = plane.distance; for (int i = 0; i < 3; i++) { if ((Vector3.Dot(normal, corner[i]) + distance) > 0f) { inside[num++] = i; } else { num2 = i; } } switch (num) { case 3: triangle.CopyTo(dest[destIndex]); return(1); case 0: return(0); case 1: { int num5 = inside[0]; int num6 = (num5 + 1) % 3; int num7 = (num5 + 2) % 3; Vector3 vector2 = corner[num5]; Vector3 vector3 = corner[num6]; Vector3 vector4 = corner[num7]; Vector2 vector5 = triangle.uv[num5]; Vector2 vector6 = triangle.uv[num6]; Vector2 vector7 = triangle.uv[num7]; Color32 color = triangle.color[num5]; Color32 color2 = triangle.color[num6]; Color32 color3 = triangle.color[num7]; float num8 = 0f; Vector3 vector8 = vector3 - vector2; Ray ray = new Ray(vector2, vector8.normalized); plane.Raycast(ray, out num8); float num9 = num8 / vector8.magnitude; Vector3 vector9 = ray.origin + ((Vector3)(ray.direction * num8)); Vector2 vector10 = Vector2.Lerp(vector5, vector6, num9); Color color4 = Color.Lerp((Color)color, (Color)color2, num9); vector8 = vector4 - vector2; ray = new Ray(vector2, vector8.normalized); plane.Raycast(ray, out num8); num9 = num8 / vector8.magnitude; Vector3 vector11 = ray.origin + ((Vector3)(ray.direction * num8)); Vector2 vector12 = Vector2.Lerp(vector5, vector7, num9); Color color5 = Color.Lerp((Color)color, (Color)color3, num9); dest[destIndex].corner[0] = vector2; dest[destIndex].corner[1] = vector9; dest[destIndex].corner[2] = vector11; dest[destIndex].uv[0] = vector5; dest[destIndex].uv[1] = vector10; dest[destIndex].uv[2] = vector12; dest[destIndex].color[0] = color; dest[destIndex].color[1] = color4; dest[destIndex].color[2] = color5; return(1); } } int index = num2; int num11 = (index + 1) % 3; int num12 = (index + 2) % 3; Vector3 origin = corner[index]; Vector3 vector14 = corner[num11]; Vector3 vector15 = corner[num12]; Vector2 from = triangle.uv[index]; Vector2 to = triangle.uv[num11]; Vector2 vector18 = triangle.uv[num12]; Color32 color6 = triangle.color[index]; Color32 color7 = triangle.color[num11]; Color32 color8 = triangle.color[num12]; Vector3 vector19 = vector14 - origin; Ray ray2 = new Ray(origin, vector19.normalized); float enter = 0f; plane.Raycast(ray2, out enter); float t = enter / vector19.magnitude; Vector3 vector20 = ray2.origin + ((Vector3)(ray2.direction * enter)); Vector2 vector21 = Vector2.Lerp(from, to, t); Color color9 = Color.Lerp((Color)color6, (Color)color7, t); vector19 = vector15 - origin; ray2 = new Ray(origin, vector19.normalized); plane.Raycast(ray2, out enter); t = enter / vector19.magnitude; Vector3 vector22 = ray2.origin + ((Vector3)(ray2.direction * enter)); Vector2 vector23 = Vector2.Lerp(from, vector18, t); Color color10 = Color.Lerp((Color)color6, (Color)color8, t); dest[destIndex].corner[0] = vector20; dest[destIndex].corner[1] = vector14; dest[destIndex].corner[2] = vector22; dest[destIndex].uv[0] = vector21; dest[destIndex].uv[1] = to; dest[destIndex].uv[2] = vector23; dest[destIndex].color[0] = color9; dest[destIndex].color[1] = color7; dest[destIndex].color[2] = color10; destIndex++; dest[destIndex].corner[0] = vector22; dest[destIndex].corner[1] = vector14; dest[destIndex].corner[2] = vector15; dest[destIndex].uv[0] = vector23; dest[destIndex].uv[1] = to; dest[destIndex].uv[2] = vector18; dest[destIndex].color[0] = color10; dest[destIndex].color[1] = color7; dest[destIndex].color[2] = color8; return(2); }
private static int clipToPlane( Plane plane, ClipTriangle triangle, ClipTriangle[] dest, int destIndex ) { var verts = triangle.corner; var numInside = 0; var outside = 0; var planeNormal = plane.normal; var planeDist = plane.distance; for( int i = 0; i < 3; i++ ) { if( Vector3.Dot( planeNormal, verts[ i ] ) + planeDist > 0 ) inside[ numInside++ ] = i; else outside = i; } // Entire triangle is in front of the plane if( numInside == 3 ) { triangle.CopyTo( dest[ destIndex ] ); return 1; } // Entire triangle is behind the plane if( numInside == 0 ) { return 0; } // We've got vertices on either side of the plane, need to slice... // TODO: Currently always splits in the same direction. Modify so split retains largest triangle area? if( numInside == 1 ) { var i0 = inside[ 0 ]; var i1 = ( i0 + 1 ) % 3; var i2 = ( i0 + 2 ) % 3; var va = verts[ i0 ]; var vb = verts[ i1 ]; var vc = verts[ i2 ]; var uva = triangle.uv[ i0 ]; var uvb = triangle.uv[ i1 ]; var uvc = triangle.uv[ i2 ]; var ca = triangle.color[ i0 ]; var cb = triangle.color[ i1 ]; var cc = triangle.color[ i2 ]; var distance = 0f; var dir = vb - va; var ray = new Ray( va, dir.normalized ); plane.Raycast( ray, out distance ); var lerpDist = distance / dir.magnitude; var v1 = ray.origin + ray.direction * distance; var uv1 = Vector2.Lerp( uva, uvb, lerpDist ); var c1 = Color.Lerp( ca, cb, lerpDist ); dir = vc - va; ray = new Ray( va, dir.normalized ); plane.Raycast( ray, out distance ); lerpDist = distance / dir.magnitude; var v2 = ray.origin + ray.direction * distance; var uv2 = Vector2.Lerp( uva, uvc, lerpDist ); var c2 = Color.Lerp( ca, cc, lerpDist ); dest[ destIndex ].corner[ 0 ] = va; dest[ destIndex ].corner[ 1 ] = v1; dest[ destIndex ].corner[ 2 ] = v2; dest[ destIndex ].uv[ 0 ] = uva; dest[ destIndex ].uv[ 1 ] = uv1; dest[ destIndex ].uv[ 2 ] = uv2; dest[ destIndex ].color[ 0 ] = ca; dest[ destIndex ].color[ 1 ] = c1; dest[ destIndex ].color[ 2 ] = c2; return 1; } else { var i0 = outside; var i1 = ( i0 + 1 ) % 3; var i2 = ( i0 + 2 ) % 3; var va = verts[ i0 ]; var vb = verts[ i1 ]; var vc = verts[ i2 ]; var uva = triangle.uv[ i0 ]; var uvb = triangle.uv[ i1 ]; var uvc = triangle.uv[ i2 ]; var ca = triangle.color[ i0 ]; var cb = triangle.color[ i1 ]; var cc = triangle.color[ i2 ]; var dir = vb - va; var ray = new Ray( va, dir.normalized ); var distance = 0f; plane.Raycast( ray, out distance ); var lerpDist = distance / dir.magnitude; var v1 = ray.origin + ray.direction * distance; var uv1 = Vector2.Lerp( uva, uvb, lerpDist ); var c1 = Color.Lerp( ca, cb, lerpDist ); dir = vc - va; ray = new Ray( va, dir.normalized ); plane.Raycast( ray, out distance ); lerpDist = distance / dir.magnitude; var v2 = ray.origin + ray.direction * distance; var uv2 = Vector2.Lerp( uva, uvc, lerpDist ); var c2 = Color.Lerp( ca, cc, lerpDist ); dest[ destIndex ].corner[ 0 ] = v1; dest[ destIndex ].corner[ 1 ] = vb; dest[ destIndex ].corner[ 2 ] = v2; dest[ destIndex ].uv[ 0 ] = uv1; dest[ destIndex ].uv[ 1 ] = uvb; dest[ destIndex ].uv[ 2 ] = uv2; dest[ destIndex ].color[ 0 ] = c1; dest[ destIndex ].color[ 1 ] = cb; dest[ destIndex ].color[ 2 ] = c2; destIndex++; dest[ destIndex ].corner[ 0 ] = v2; dest[ destIndex ].corner[ 1 ] = vb; dest[ destIndex ].corner[ 2 ] = vc; dest[ destIndex ].uv[ 0 ] = uv2; dest[ destIndex ].uv[ 1 ] = uvb; dest[ destIndex ].uv[ 2 ] = uvc; dest[ destIndex ].color[ 0 ] = c2; dest[ destIndex ].color[ 1 ] = cb; dest[ destIndex ].color[ 2 ] = cc; return 2; } }
private static int clipToPlane( Plane plane, ClipTriangle[] source, ClipTriangle[] dest, int count ) { var newCount = 0; for( int i = 0; i < count; i++ ) { newCount += clipToPlane( plane, source[ i ], dest, newCount ); } return newCount; }
public void CopyTo( ClipTriangle target ) { Array.Copy( this.corner, target.corner, 3 ); Array.Copy( this.uv, target.uv, 3 ); Array.Copy( this.color, target.color, 3 ); }
private static ClipTriangle[] initClipBuffer( int size ) { var buffer = new ClipTriangle[ size ]; for( int i = 0; i < size; i++ ) { buffer[ i ].corner = new Vector3[ 3 ]; buffer[ i ].uv = new Vector2[ 3 ]; buffer[ i ].color = new Color32[ 3 ]; } return buffer; }