public void Apply(bool forceNewCheck) { //TODO //This function assumes that connections from the n1,n2 nodes never need to be removed in the future (e.g because the nodes move or something) NNConstraint nn = NNConstraint.None; nn.distanceXZ = true; int graph = (int)startNode.GraphIndex; //Search all graphs but the one which start and end nodes are on nn.graphMask = ~(1 << graph); bool same = true; { //Good Game //var info = AstarPath.active.GetNearest(StartTransform.position, nn); var info = AstarPath.active.GetNearest((VInt3)StartTransform.position, nn); same &= info.node == connectedNode1 && info.node != null; connectedNode1 = info.node as MeshNode; clamped1 = info.position; if (connectedNode1 != null) { Debug.DrawRay((Vector3)connectedNode1.position, Vector3.up * 5, Color.red); } } { //Good Game //var info = AstarPath.active.GetNearest(EndTransform.position, nn); var info = AstarPath.active.GetNearest((VInt3)EndTransform.position, nn); same &= info.node == connectedNode2 && info.node != null; connectedNode2 = info.node as MeshNode; clamped2 = info.position; if (connectedNode2 != null) { Debug.DrawRay((Vector3)connectedNode2.position, Vector3.up * 5, Color.cyan); } } if (connectedNode2 == null || connectedNode1 == null) { return; } startNode.SetPosition((VInt3)StartTransform.position); endNode.SetPosition((VInt3)EndTransform.position); if (same && !forceNewCheck) { return; } RemoveConnections(startNode); RemoveConnections(endNode); uint cost = (uint)Mathf.RoundToInt(((VInt3)(StartTransform.position - EndTransform.position)).costMagnitude * costFactor); startNode.AddConnection(endNode, cost); endNode.AddConnection(startNode, cost); VInt3 dir = connectedNode2.position - connectedNode1.position; for (int a = 0; a < connectedNode1.GetVertexCount(); a++) { VInt3 va1 = connectedNode1.GetVertex(a); VInt3 va2 = connectedNode1.GetVertex((a + 1) % connectedNode1.GetVertexCount()); if (VInt3.DotLong((va2 - va1).Normal2D(), dir) > 0) { continue; } for (int b = 0; b < connectedNode2.GetVertexCount(); b++) { VInt3 vb1 = connectedNode2.GetVertex(b); VInt3 vb2 = connectedNode2.GetVertex((b + 1) % connectedNode2.GetVertexCount()); if (VInt3.DotLong((vb2 - vb1).Normal2D(), dir) < 0) { continue; } if (VInt3.Angle((vb2 - vb1), (va2 - va1)) > (170.0 / 360.0f) * Mathf.PI * 2) { float t1 = 0; float t2 = 1; t2 = System.Math.Min(t2, VectorMath.ClosestPointOnLineFactor(va1, va2, vb1)); t1 = System.Math.Max(t1, VectorMath.ClosestPointOnLineFactor(va1, va2, vb2)); if (t2 < t1) { Debug.LogError("Something went wrong! " + t1 + " " + t2 + " " + va1 + " " + va2 + " " + vb1 + " " + vb2 + "\nTODO, how can this happen?"); } else { //Good Game /*Vector3 pa = (Vector3)(va2-va1)*t1 + (Vector3)va1; * Vector3 pb = (Vector3)(va2-va1)*t2 + (Vector3)va1;*/ VInt3 pa = (va2 - va1) * t1 + va1; VInt3 pb = (va2 - va1) * t2 + va1; startNode.portalA = pa; startNode.portalB = pb; endNode.portalA = pb; endNode.portalB = pa; //Add connections between nodes, or replace old connections if existing //Good Game /*connectedNode1.AddConnection(startNode, (uint)Mathf.RoundToInt(((VInt3)(clamped1 - StartTransform.position)).costMagnitude*costFactor)); * connectedNode2.AddConnection(endNode, (uint)Mathf.RoundToInt(((VInt3)(clamped2 - EndTransform.position)).costMagnitude*costFactor)); * * startNode.AddConnection(connectedNode1, (uint)Mathf.RoundToInt(((VInt3)(clamped1 - StartTransform.position)).costMagnitude*costFactor)); * endNode.AddConnection(connectedNode2, (uint)Mathf.RoundToInt(((VInt3)(clamped2 - EndTransform.position)).costMagnitude*costFactor));*/ connectedNode1.AddConnection(startNode, (uint)Mathf.RoundToInt(((clamped1 - (VInt3)StartTransform.position)).costMagnitude * costFactor)); connectedNode2.AddConnection(endNode, (uint)Mathf.RoundToInt(((clamped2 - (VInt3)EndTransform.position)).costMagnitude * costFactor)); startNode.AddConnection(connectedNode1, (uint)Mathf.RoundToInt(((clamped1 - (VInt3)StartTransform.position)).costMagnitude * costFactor)); endNode.AddConnection(connectedNode2, (uint)Mathf.RoundToInt(((clamped2 - (VInt3)EndTransform.position)).costMagnitude * costFactor)); return; } } } } }
private void DelaunayRefinement(VInt3[] verts, int[] tris, ref int vCount, ref int tCount, bool delaunay, bool colinear, VInt3 worldOffset) { if (tCount % 3 != 0) { throw new Exception("Triangle array length must be a multiple of 3"); } Dictionary <VInt2, int> dictionary = this.cached_Int2_int_dict; dictionary.Clear(); for (int i = 0; i < tCount; i += 3) { if (!Polygon.IsClockwise(verts[tris[i]], verts[tris[i + 1]], verts[tris[i + 2]])) { int num = tris[i]; tris[i] = tris[i + 2]; tris[i + 2] = num; } dictionary.set_Item(new VInt2(tris[i], tris[i + 1]), i + 2); dictionary.set_Item(new VInt2(tris[i + 1], tris[i + 2]), i); dictionary.set_Item(new VInt2(tris[i + 2], tris[i]), i + 1); } int num2 = 9; for (int j = 0; j < tCount; j += 3) { for (int k = 0; k < 3; k++) { int num3; if (dictionary.TryGetValue(new VInt2(tris[j + (k + 1) % 3], tris[j + k % 3]), ref num3)) { VInt3 vInt = verts[tris[j + (k + 2) % 3]]; VInt3 vInt2 = verts[tris[j + (k + 1) % 3]]; VInt3 vInt3 = verts[tris[j + (k + 3) % 3]]; VInt3 vInt4 = verts[tris[num3]]; vInt.y = 0; vInt2.y = 0; vInt3.y = 0; vInt4.y = 0; bool flag = false; if (!Polygon.Left(vInt, vInt3, vInt4) || Polygon.LeftNotColinear(vInt, vInt2, vInt4)) { if (!colinear) { goto IL_439; } flag = true; } if (colinear && AstarMath.DistancePointSegment(vInt, vInt4, vInt2) < (float)num2 && !dictionary.ContainsKey(new VInt2(tris[j + (k + 2) % 3], tris[j + (k + 1) % 3])) && !dictionary.ContainsKey(new VInt2(tris[j + (k + 1) % 3], tris[num3]))) { tCount -= 3; int num4 = num3 / 3 * 3; tris[j + (k + 1) % 3] = tris[num3]; if (num4 != tCount) { tris[num4] = tris[tCount]; tris[num4 + 1] = tris[tCount + 1]; tris[num4 + 2] = tris[tCount + 2]; dictionary.set_Item(new VInt2(tris[num4], tris[num4 + 1]), num4 + 2); dictionary.set_Item(new VInt2(tris[num4 + 1], tris[num4 + 2]), num4); dictionary.set_Item(new VInt2(tris[num4 + 2], tris[num4]), num4 + 1); tris[tCount] = 0; tris[tCount + 1] = 0; tris[tCount + 2] = 0; } else { tCount += 3; } dictionary.set_Item(new VInt2(tris[j], tris[j + 1]), j + 2); dictionary.set_Item(new VInt2(tris[j + 1], tris[j + 2]), j); dictionary.set_Item(new VInt2(tris[j + 2], tris[j]), j + 1); } else if (delaunay && !flag) { float num5 = VInt3.Angle(vInt2 - vInt, vInt3 - vInt); float num6 = VInt3.Angle(vInt2 - vInt4, vInt3 - vInt4); if (num6 > 6.28318548f - 2f * num5) { tris[j + (k + 1) % 3] = tris[num3]; int num7 = num3 / 3 * 3; int num8 = num3 - num7; tris[num7 + (num8 - 1 + 3) % 3] = tris[j + (k + 2) % 3]; dictionary.set_Item(new VInt2(tris[j], tris[j + 1]), j + 2); dictionary.set_Item(new VInt2(tris[j + 1], tris[j + 2]), j); dictionary.set_Item(new VInt2(tris[j + 2], tris[j]), j + 1); dictionary.set_Item(new VInt2(tris[num7], tris[num7 + 1]), num7 + 2); dictionary.set_Item(new VInt2(tris[num7 + 1], tris[num7 + 2]), num7); dictionary.set_Item(new VInt2(tris[num7 + 2], tris[num7]), num7 + 1); } } } IL_439 :; } } }