private Vector3 GetMiddleNormal(PolygonSide pair, Vector3 point) { float t = Vector3.Distance(vertices[pair.left], point) / Vector3.Distance(vertices[pair.left], vertices[pair.right]); Vector3 middleNormal = Vector3.Lerp(normals[pair.left], normals[pair.right], t); return(middleNormal); }
public int Cut(PolygonSide a, PolygonSide b, out List <MPolygon> newPolys, int vertexCount) { if (!a.SameAs(b)) { var newV1 = vertexCount; var newV2 = vertexCount + 1; var part1 = new List <int> (); var part2 = new List <int> (); var part3 = new List <int> (); if (contains(a.Reversed())) { a.Reverse(); } if (contains(b.Reversed())) { b.Reverse(); } List <int> side1 = GetSideWalk(a.right, b.left); side1.Add(newV1); side1.Add(newV2); List <int> side2 = GetSideWalk(b.right, a.left); side2.Add(newV2); side2.Add(newV1); newPolys = new List <MPolygon> (); newPolys.Add(new MPolygon(side1)); newPolys.Add(new MPolygon(side2)); return(2); } newPolys = null; return(-1); }
private int FindCutPoint(Vector3 start, Vector3 end, PolygonSide neighbor) { Vector3 p0 = vertices[neighbor.left]; Vector3 p1 = vertices[neighbor.right]; float d; var cutPoint = LinearAlgebra.getClosest(start, end, p0, p1, out d); int index = AddCutPoint(cutPoint, sside); cutEdges[index] = neighbor; return(index); }
private bool isOnPolygonSide(Vector3 intersection, MPolygon polygon, out PolygonSide intersectSide) { foreach (var side in polygon.GetSides()) { if (LinearAlgebra.isInSegment(intersection, vertices[side.left], vertices[side.right])) { intersectSide = side; return(true); } } intersectSide = null; return(false); }
public bool ContainsEdge(PolygonSide pairEntry, Dictionary <PolygonSide, int> replacedNeighbors) { if (!replacedNeighbors.ContainsKey(pairEntry)) { return(contains(pairEntry) || contains(pairEntry.Reversed())); } else { var neighbor = replacedNeighbors[pairEntry]; var pair1 = new PolygonSide(pairEntry.left, neighbor); var pair2 = new PolygonSide(pairEntry.right, neighbor); return(contains(pair1) || contains(pair1.Reversed()) || contains(pair2) || contains(pair2.Reversed())); } }
private bool haveCommonSide(int hit1, int hit2, out PolygonSide neighbor) { var t1 = GetTriangle(hit1); var t2 = GetTriangle(hit2); if (t1.isNeighbor(t2, out neighbor)) { return(true); } else { return(false); } }
private List <int> CutUpPolygons(int triangle, PolygonSide side, Vector3 pointSide, int corner, Vector3 pointCorner, out List <MPolygon> newPolys, out MPolygon remove) { var polys = polyAtTriangle[triangle]; var cutPointIndices = new List <int> (); newPolys = null; remove = null; if (!LinearAlgebra.isInSegment(pointCorner, vertices[side.left], vertices[side.right])) { for (int j = 0; j < polys.Count; j++) { var polygon = polys[j]; var numNewVerts = -1; bool entryInPolygon = isPolygonCorner(pointCorner, polygon, out corner); bool exitInPolygon = isOnPolygonSide(pointSide, polygon, out side); if (entryInPolygon && exitInPolygon) { remove = polygon; numNewVerts = CutPolygon(polygon, out newPolys, side, corner); } if (numNewVerts > 0) { var newV1 = vertices.Count; if (!vertices.Contains(pointSide)) { vertices.Add(pointSide); normals.Add(GetMiddleNormal(side, pointSide)); cutPointIndices.Add(newV1); } else { var newIndex = vertices.IndexOf(pointSide); foreach (var pol in newPolys) { int index = pol.IndexOf(newV1); pol.RemoveAt(index); pol.Insert(index, newIndex); } cutPointIndices.Add(newIndex); } break; } } } return(cutPointIndices); }
bool contains(PolygonSide pairEntry) { for (int i = 1; i < Count; i++) { if (pairEntry.left.Equals(this [i - 1]) && pairEntry.right.Equals(this [i])) { return(true); } } if (pairEntry.left.Equals(this [Count - 1]) && pairEntry.right.Equals(this [0])) { return(true); } return(false); }
private static bool IsSeparatingEdge(Dictionary <int, int> cutPointsToVertices, PolygonSide side) { int cp1, cp2; cp1 = -2; if (cutPointsToVertices.ContainsKey(side.left)) { cp1 = cutPointsToVertices[side.left]; } cp2 = -2; if (cutPointsToVertices.ContainsKey(side.right)) { cp2 = cutPointsToVertices[side.right]; } return(Mathf.Abs(cp1 - cp2) == 1); }
private bool isLHS(MTriangle mTriangle, PolygonSide pairEntry, int vertexExit) { foreach (var side in mTriangle.GetSides()) { if (pairEntry.SameAs(side)) { if (vertexExit == side.left) { return(false); } else if (vertexExit == side.right) { return(true); } } } return(false); }
private int GetOtherTriangle(int hit1, PolygonSide closestSide) { var two = g.getTriangles(closestSide.left, closestSide.right); // Debug.Log("Triangles for " + hit1 + ": " g); // Misc.DebugList<int> ("Triangles for " + hit1 + ": ", two); two.Remove(hit1); if (two.Count > 1) { Debug.LogWarning("In GetOtherTriangle: two has more than one element"); } if (two.Count < 1) { // DebugAtTriangle (hit1, Color.red); Debug.LogWarning("In GetOtherTriangle: two has less than one element"); } return(two[0]); }
internal bool isNeighbor(MTriangle t2, out PolygonSide neighbor) { var sides = GetSides(); foreach (var side in sides) { if (t2.innerList.Contains(side.left) && t2.innerList.Contains(side.right)) { neighbor = side; return(true); } } // var intersect = this.innerList.Intersect (t2.innerList).ToList (); // if (intersect.Count == 2) { // neighbor = new Pair<int> (intersect[0], intersect[1]); // return true; // } else { neighbor = null; return(false); // } }
public int Cut(PolygonSide a, int corner, out List <MPolygon> newPolys, int vertexCount) { // Debug.Log ("Check if not contain corner"); if (!a.Contains(corner)) { // Debug.Log ("Does not contain corner"); var newV1 = vertexCount; if (contains(a.Reversed())) { a.Reverse(); } List <int> side1 = GetSideWalk(corner, a.left); side1.Add(newV1); List <int> side2 = GetSideWalk(a.right, corner); side2.Add(newV1); newPolys = new List <MPolygon> (); newPolys.Add(new MPolygon(side1)); newPolys.Add(new MPolygon(side2)); return(2); } newPolys = null; return(-1); }
private Vector3 FindPointOnTriangle(int t1, Vector3 start, Vector3 end, ref PolygonSide closestSide) { var triangle = GetTriangle(t1); var sides = triangle.GetSides(); var minDist = float.MaxValue; Vector3 closestCutPoint = default(Vector3); foreach (var side in sides) { if (!side.SameAs(closestSide)) { float distance; var minCutPoint = LinearAlgebra.getClosest(start, end, vertices[side.left], vertices[side.right], out distance); // Misc.DebugSphere (closestIntersection, Color.magenta, "Intersection point on Side for " + hit1); if (distance < minDist) { closestCutPoint = minCutPoint; closestSide = side; minDist = distance; } } } return(closestCutPoint); }
private List <int> CutUpPolygons(int triangle, PolygonSide pairEntry, PolygonSide pairExit, Vector3 pointEntry, Vector3 pointExit, out List <MPolygon> newPolys, out MPolygon remove) { var polys = polyAtTriangle[triangle]; newPolys = null; remove = null; var cutPointIndices = new List <int> (); for (int j = 0; j < polys.Count; j++) { var polygon = polys[j]; var numNewVerts = -1; bool entryInPolygon = isOnPolygonSide(pointEntry, polygon, out pairEntry); bool exitInPolygon = isOnPolygonSide(pointExit, polygon, out pairExit); if (entryInPolygon != exitInPolygon) { Debug.LogWarning("Entry but not Exit in Polygon (or exit but not entry. This probably means the polygon was cross-cutted."); } if (entryInPolygon && exitInPolygon) { remove = polygon; numNewVerts = CutPolygon(polygon, out newPolys, pairEntry, pairExit); } if (numNewVerts > 0) { var newV1 = vertices.Count; var newV2 = vertices.Count + 1; if (!vertices.Contains(pointExit)) { vertices.Add(pointExit); normals.Add(GetMiddleNormal(pairExit, pointExit)); cutPointIndices.Add(newV1); } else { var newIndex = vertices.IndexOf(pointExit); foreach (var pol in newPolys) { int index = pol.IndexOf(newV1); pol.RemoveAt(index); pol.Insert(index, newIndex); } cutPointIndices.Add(newIndex); } if (!vertices.Contains(pointEntry)) { vertices.Add(pointEntry); normals.Add(GetMiddleNormal(pairEntry, pointEntry)); cutPointIndices.Add(newV2); } else { var newIndex = vertices.IndexOf(pointEntry); foreach (var pol in newPolys) { int index = pol.IndexOf(newV2); pol.RemoveAt(index); pol.Insert(index, newIndex); } cutPointIndices.Add(newIndex); } break; } } return(cutPointIndices); }
/// <summary> /// Processes the edges of the given triangle. It does so by updating /// the adjacency information based on the direction the polygon is facing. /// If there is a silhouette edge found, then this edge is added to the list /// of edges if it is within the texture coordinate bounds passed to the function. /// </summary> /// <param name="p">The triangle's vertices</param> /// <param name="uv">The texture coordinates for those vertices</param> /// <param name="visualTexCoordBounds">The texture coordinate edges being searched for</param> /// <param name="polygonSide">Which side the polygon is facing (greateer than 0 front, less than 0 back)</param> /// <param name="edgeList">The list of edges comprosing the visual outline</param> /// <param name="adjInformation">The adjacency information structure</param> private void ProcessTriangleEdges(Point3D[] p, Point[] uv, Point[] visualTexCoordBounds, PolygonSide polygonSide, List<HitTestEdge> edgeList, Dictionary<Edge, EdgeInfo> adjInformation) { // loop over all the edges and add them to the adjacency list for (int i = 0; i < p.Length; i++) { Point uv1, uv2; Point3D p3D1 = p[i]; Point3D p3D2 = p[(i + 1) % p.Length]; Edge edge; // order the edge points so insertion in to adjInformation is consistent if (p3D1.X < p3D2.X || (p3D1.X == p3D2.X && p3D1.Y < p3D2.Y) || (p3D1.X == p3D2.X && p3D1.Y == p3D2.Y && p3D1.Z < p3D1.Z)) { edge = new Edge(p3D1, p3D2); uv1 = uv[i]; uv2 = uv[(i + 1) % p.Length]; } else { edge = new Edge(p3D2, p3D1); uv2 = uv[i]; uv1 = uv[(i + 1) % p.Length]; } // look up the edge information EdgeInfo edgeInfo; if (adjInformation.ContainsKey(edge)) { edgeInfo = adjInformation[edge]; } else { edgeInfo = new EdgeInfo(); adjInformation[edge] = edgeInfo; } edgeInfo._numSharing++; // whether or not the edge has already been added to the edge list bool alreadyAdded = edgeInfo._hasBackFace && edgeInfo._hasFrontFace; // add the edge to the info list if (polygonSide == PolygonSide.FRONT) { edgeInfo._hasFrontFace = true; edgeInfo._uv1 = uv1; edgeInfo._uv2 = uv2; } else { edgeInfo._hasBackFace = true; } // if the sides are different we may need to add an edge if (!alreadyAdded && edgeInfo._hasBackFace && edgeInfo._hasFrontFace) { HandleSilhouetteEdge(edgeInfo._uv1, edgeInfo._uv2, edge._start, edge._end, visualTexCoordBounds, edgeList); } } }
internal Pair <List <MPolygon> > Cut(List <Vector3> cutPoints, Dictionary <int, PolygonSide> cutEdges, Dictionary <int, int> cutNodes, Dictionary <int, int> cutTriangles) { var lhs = new List <MPolygon> (); var rhs = new List <MPolygon> (); for (int i = 1; i < cutPoints.Count + 1; i++) { PolygonSide pairEntry = null; PolygonSide pairExit = null; int vertexEntry = -1; int vertexExit = -1; int bIndex = i - 1; var pointEntry = cutPoints[bIndex]; if (cutEdges.ContainsKey(bIndex)) { pairEntry = cutEdges[bIndex]; } else if (cutNodes.ContainsKey(bIndex)) { vertexEntry = cutNodes[bIndex]; // Debug.Log ("Vertex entry not null at " + vertexEntry); } int tIndex = i == cutPoints.Count ? 0 : i; var pointExit = cutPoints[tIndex]; if (cutEdges.ContainsKey(tIndex)) { pairExit = cutEdges[tIndex]; } else if (cutNodes.ContainsKey(tIndex)) { vertexExit = cutNodes[tIndex]; // Debug.Log ("Vertex exit not null at " + vertexExit); } List <MPolygon> newPolys = null; var triangle = -1; MPolygon remove = null; if (pairEntry != null && vertexExit != -1) { // Debug.Log ("Cut from " + pairEntry + " to " + vertexExit + " at triangle " + tIndex); triangle = cutTriangles[tIndex]; var cutPointIndices = CutUpPolygons(triangle, pairEntry, pointEntry, vertexExit, pointExit, out newPolys, out remove); if (cutPointIndices.Count == 1) { cutPointVertices[cutPointIndices[0]] = tIndex; lhs.Add(newPolys[1]); rhs.Add(newPolys[0]); if (newPolys[0].Contains(1370)) { Debug.Log("p-v Adding " + newPolys[0] + " to rhs and " + newPolys[1] + " to lhs"); } } else { // Debug.Log ("Same entry and exit at p-v " + pairEntry + " to " + vertexExit + " with " + cutTriangles[bIndex] + " and " + cutTriangles[tIndex] + " " + isLHS (GetTriangle (triangle), pairEntry, vertexExit)); // if (isLHS (GetTriangle (triangle), pairEntry, vertexExit)) { // lhs.AddRange (polyAtTriangle[cutTriangles[tIndex]]); // foreach (var item in polyAtTriangle[cutTriangles[tIndex]]) { // if (item.Contains (1299)) { // Debug.Log ("p-v Adding " + item); // } // } // } else { // rhs.AddRange (polyAtTriangle[cutTriangles[tIndex]]); // } } } else if (vertexEntry != -1 && pairExit != null) { // Debug.Log ("Cut from " + vertexEntry + " to " + pairExit); triangle = cutTriangles[tIndex]; var cutPointIndices = CutUpPolygons(triangle, pairExit, pointExit, vertexEntry, pointEntry, out newPolys, out remove); if (cutPointIndices.Count == 1) { cutPointVertices[cutPointIndices[0]] = tIndex; lhs.Add(newPolys[0]); rhs.Add(newPolys[1]); if (newPolys[1].Contains(1370)) { Debug.Log("v-p Adding " + newPolys[1] + " to rhs and " + newPolys[0] + " to lhs"); } } else { // Debug.Log ("Same entry and exit at v-p " + pairExit + " to " + vertexEntry + " with " + cutTriangles[bIndex] + " and " + cutTriangles[tIndex] + " " + isLHS (GetTriangle (triangle), pairExit, vertexEntry)); // if (isLHS (GetTriangle (triangle), pairExit, vertexEntry)) { // lhs.AddRange (polyAtTriangle[cutTriangles[tIndex]]); // foreach (var item in polyAtTriangle[cutTriangles[tIndex]]) { // if (item.Contains (1299)) { // Debug.Log ("v-p Adding " + item); // } // } // } else { // rhs.AddRange (polyAtTriangle[cutTriangles[tIndex]]); // } } } else if (vertexEntry != -1 && vertexExit != -1) { //Nothing } else if (pairEntry != null && pairExit != null) { if (!pairEntry.SameAs(pairExit)) { triangle = cutTriangles[tIndex]; var cutPointIndices = CutUpPolygons(triangle, pairEntry, pairExit, pointEntry, pointExit, out newPolys, out remove); if (cutPointIndices.Count == 2) { cutPointVertices[cutPointIndices[0]] = tIndex; cutPointVertices[cutPointIndices[1]] = bIndex; lhs.Add(newPolys[0]); rhs.Add(newPolys[1]); if (newPolys[1].Contains(1335)) { Debug.Log("p-p Adding " + newPolys[1] + " to rhs and " + newPolys[0] + " to lhs"); } } } else { // Debug.Log ("Same entry and exit at " + pairEntry + " to " + pairExit + " with " + cutTriangles[bIndex] + " and " + cutTriangles[tIndex]); // Misc.DebugSphere (vertices[pairEntry.left], Color.white, "Entry " + pairEntry + " left"); // Misc.DebugSphere (vertices[pairEntry.right], Color.white, "Entry " + pairEntry + " right"); // rhs.AddRange (polyAtTriangle[cutTriangles[bIndex]]); // foreach (var item in polyAtTriangle[cutTriangles[bIndex]]) { // if (item.Contains (1297)) { // Debug.Log ("e-e Adding " + item + " to rhs"); // } // } // lhs.AddRange (polyAtTriangle[cutTriangles[tIndex]]); } } if (newPolys != null) { polyAtTriangle[triangle].Remove(remove); lhs.Remove(remove); rhs.Remove(remove); polyAtTriangle[triangle].AddRange(newPolys); } } return(new Pair <List <MPolygon> > (lhs, rhs)); }
private List <MPolygon> getNeighbors(Dictionary <int, List <MPolygon> > polyAtTriangle, PolygonSide neighborSide) { List <MPolygon> retList = new List <MPolygon> (); foreach (var key in polyAtTriangle.Keys) { foreach (var polygon in polyAtTriangle[key]) { // if (polygon.Contains (neighborSide.left)) { // Misc.DebugList ("Candidate for " + neighborSide, polygon); // } if (polygon.ContainsEdge(neighborSide)) { retList.Add(polygon); } } } return(retList); }
public bool ContainsEdge(PolygonSide pairEntry) { return(contains(pairEntry) || contains(pairEntry.Reversed())); }
private int CutPolygon(MPolygon polygon, out List <MPolygon> newPolys, PolygonSide sideEntry, PolygonSide sideExit) { return(polygon.Cut(sideEntry, sideExit, out newPolys, vertices.Count)); }
private int CutPolygon(MPolygon polygon, out List <MPolygon> newPolys, PolygonSide side, int corner) { return(polygon.Cut(side, corner, out newPolys, vertices.Count)); }
private bool GetIntersection(int i) { var start = onMeshPositions[i - 1]; var end = onMeshPositions[i]; if (onVertex.ContainsKey(i - 1) && onVertex.ContainsKey(i)) { // AddOnVertexCut (i - 1); // AddOnVertexCut (i); //Shouldn't happen Debug.LogError("Both on Cut at " + i); } else if (!onVertex.ContainsKey(i - 1) && onVertex.ContainsKey(i)) { int t = cutTriangles.Count > 0 ? cutTriangles[cutPoints.Count - 1] : -1; var index = AddOnVertexCut(i); Debug.Log("Cut to v " + (i - 1) + " to " + i + ", adding " + triangleIndices[i - 1] + " to cuttriangles at " + index); var v = triangleIndices[i - 1]; if (t >= 0) { v = getNeighboringTriangle(onVertex[i], GetTriangle(t)); } cutTriangles[index] = v; // Misc.DebugSphere (cutPoints[index], Color.red, "Cut Point e-v " + i); } else if (onVertex.ContainsKey(i - 1) && !onVertex.ContainsKey(i)) { // var index = AddOnVertexCut (i - 1); // Debug.Log ("Cut from v " + (i - 1) + " to " + i + ", adding " + v + " to cuttriangles at " + index); // cutTriangles[index] = v; // Misc.DebugSphere (cutPoints[index], Color.red, "Cut Point v-e " + i); } else { int t1 = triangleIndices[i - 1]; int t2 = triangleIndices[i]; if (t1 != t2) { PolygonSide neighbor; var counter = 0; PolygonSide closestSide = null; while (!haveCommonSide(t1, t2, out neighbor) && ++counter < 12) { var closestCutPoint = FindPointOnTriangle(t1, start, end, ref closestSide); int index = AddCutPoint(closestCutPoint, sside); // Misc.DebugSphere (cutPoints[index], Color.red, "Cut Point e-e " + t1 + " " + t2); cutTriangles[index] = t1; cutEdges[index] = closestSide; t1 = GetOtherTriangle(t1, closestSide); start = closestCutPoint; } if (counter > 9) { Debug.LogError("Still no common side between " + triangleIndices[i - 1] + " and " + triangleIndices[i]); DebugAtTriangle(triangleIndices[i - 1], Color.white); DebugAtTriangle(triangleIndices[i], Color.black); } var cutIndex = FindCutPoint(start, end, neighbor); cutTriangles[cutIndex] = t1; } } return(true); }
private void GetIntersection(Vector3 start, Vector3 end, int t1, int t2, PolygonSide neighbor) { }