// Token: 0x06000605 RID: 1541 RVA: 0x0003988C File Offset: 0x00037C8C public void AddSpan(uint bottom, uint top, int area, int voxelWalkableClimb) { VoxelSpan voxelSpan = new VoxelSpan(bottom, top, area); if (this.firstSpan == null) { this.firstSpan = voxelSpan; return; } VoxelSpan voxelSpan2 = null; VoxelSpan voxelSpan3 = this.firstSpan; while (voxelSpan3 != null) { if (voxelSpan3.bottom > voxelSpan.top) { break; } if (voxelSpan3.top < voxelSpan.bottom) { voxelSpan2 = voxelSpan3; voxelSpan3 = voxelSpan3.next; } else { if (voxelSpan3.bottom < bottom) { voxelSpan.bottom = voxelSpan3.bottom; } if (voxelSpan3.top > top) { voxelSpan.top = voxelSpan3.top; } if (AstarMath.Abs((int)(voxelSpan.top - voxelSpan3.top)) <= voxelWalkableClimb) { voxelSpan.area = AstarMath.Max(voxelSpan.area, voxelSpan3.area); } VoxelSpan next = voxelSpan3.next; if (voxelSpan2 != null) { voxelSpan2.next = next; } else { this.firstSpan = next; } voxelSpan3 = next; } } if (voxelSpan2 != null) { voxelSpan.next = voxelSpan2.next; voxelSpan2.next = voxelSpan; } else { voxelSpan.next = this.firstSpan; this.firstSpan = voxelSpan; } }
protected VInt3 CalculateTargetPoint(VInt3 p, VInt3 a, VInt3 b) { if (a.x == b.x && a.z == b.z) { return(a); } VFactor vFactor = AstarMath.NearestPointFactorXZ(ref a, ref b, ref p); long num = VInt3.Lerp(a, b, vFactor).XZSqrMagnitude(ref p); int num2 = IntMath.Sqrt(num); long num3 = a.XZSqrMagnitude(ref b); int num4 = IntMath.Sqrt(num3); if (num4 == 0) { return(b); } int num5 = Mathf.Clamp(this.forwardLook.i - num2, 0, this.forwardLook.i); VFactor vFactor2 = new VFactor((long)num5 * vFactor.den + vFactor.nom * (long)num4, (long)num4 * vFactor.den); if (vFactor2 > VFactor.one) { vFactor2 = VFactor.one; } else if (vFactor2 < VFactor.zero) { vFactor2 = VFactor.zero; } vFactor2.strip(); return(VInt3.Lerp(a, b, vFactor2)); }
protected VInt3 CalculateTargetPoint(VInt3 p, VInt3 a, VInt3 b) { if ((a.x == b.x) && (a.z == b.z)) { return(a); } VFactor f = AstarMath.NearestPointFactorXZ(ref a, ref b, ref p); int num3 = IntMath.Sqrt(VInt3.Lerp(a, b, f).XZSqrMagnitude(ref p)); int num5 = IntMath.Sqrt(a.XZSqrMagnitude(ref b)); if (num5 == 0) { return(b); } int num6 = Mathf.Clamp(this.forwardLook.i - num3, 0, this.forwardLook.i); VFactor one = new VFactor((num6 * f.den) + (f.nom * num5), num5 * f.den); if (one > VFactor.one) { one = VFactor.one; } else if (one < VFactor.zero) { one = VFactor.zero; } one.strip(); return(VInt3.Lerp(a, b, one)); }
protected VInt3 CalculateTargetPoint(VInt3 p, VInt3 a, VInt3 b) { if (a.x == b.x && a.z == b.z) { return(a); } VFactor f = AstarMath.NearestPointFactorXZ(ref a, ref b, ref p); long a2 = VInt3.Lerp(a, b, f).XZSqrMagnitude(ref p); int num = IntMath.Sqrt(a2); long a3 = a.XZSqrMagnitude(ref b); int num2 = IntMath.Sqrt(a3); if (num2 == 0) { return(b); } int num3 = Mathf.Clamp(this.forwardLook.i - num, 0, this.forwardLook.i); VFactor vFactor = new VFactor((long)num3 * f.den + f.nom * (long)num2, (long)num2 * f.den); if (vFactor > VFactor.one) { vFactor = VFactor.one; } else if (vFactor < VFactor.zero) { vFactor = VFactor.zero; } vFactor.strip(); return(VInt3.Lerp(a, b, vFactor)); }
public void OnPathComplete(Path p) { StartCoroutine(WaitToRepath()); //If the path didn't succeed, don't proceed if (p.error) { return; } //Get the calculated path as a Vector3 array path = p.vectorPath.ToArray(); //Find the segment in the path which is closest to the AI //If a closer segment hasn't been found in '6' iterations, break because it is unlikely to find any closer ones then float minDist = Mathf.Infinity; int notCloserHits = 0; for (int i = 0; i < path.Length - 1; i++) { float dist = AstarMath.DistancePointSegmentStrict(path[i], path[i + 1], tr.position); if (dist < minDist) { notCloserHits = 0; minDist = dist; pathIndex = i + 1; } else if (notCloserHits > 6) { break; } } }
/** Generates a terrain chunk mesh */ RasterizationMesh GenerateHeightmapChunk(float[, ] heights, Vector3 sampleSize, Vector3 offset, int x0, int z0, int width, int depth, int stride) { // Downsample to a smaller mesh (full resolution will take a long time to rasterize) // Round up the width to the nearest multiple of terrainSampleSize and then add 1 // (off by one because there are vertices at the edge of the mesh) int resultWidth = CeilDivision(width, terrainSampleSize) + 1; int resultDepth = CeilDivision(depth, terrainSampleSize) + 1; var heightmapWidth = heights.GetLength(0); var heightmapDepth = heights.GetLength(1); // Create a mesh from the heightmap var terrainVertices = new Vector3[resultWidth * resultDepth]; // Create lots of vertices for (int z = 0; z < resultDepth; z++) { for (int x = 0; x < resultWidth; x++) { int sampleX = Math.Min(x0 + x * stride, heightmapWidth - 1); int sampleZ = Math.Min(z0 + z * stride, heightmapDepth - 1); terrainVertices[z * resultWidth + x] = new Vector3(sampleZ * sampleSize.x, heights[sampleX, sampleZ] * sampleSize.y, sampleX * sampleSize.z) + offset; } } // Create the mesh by creating triangles in a grid like pattern var tris = new int[(resultWidth - 1) * (resultDepth - 1) * 2 * 3]; int triangleIndex = 0; for (int z = 0; z < resultDepth - 1; z++) { for (int x = 0; x < resultWidth - 1; x++) { tris[triangleIndex] = z * resultWidth + x; tris[triangleIndex + 1] = z * resultWidth + x + 1; tris[triangleIndex + 2] = (z + 1) * resultWidth + x + 1; triangleIndex += 3; tris[triangleIndex] = z * resultWidth + x; tris[triangleIndex + 1] = (z + 1) * resultWidth + x + 1; tris[triangleIndex + 2] = (z + 1) * resultWidth + x; triangleIndex += 3; } } #if ASTARDEBUG var color = AstarMath.IntToColor(x0 + 7 * z0, 0.7f); for (int i = 0; i < tris.Length; i += 3) { Debug.DrawLine(terrainVertices[tris[i]], terrainVertices[tris[i + 1]], color, 40); Debug.DrawLine(terrainVertices[tris[i + 1]], terrainVertices[tris[i + 2]], color, 40); Debug.DrawLine(terrainVertices[tris[i + 2]], terrainVertices[tris[i]], color, 40); } #endif var mesh = new RasterizationMesh(terrainVertices, tris, new Bounds()); // Could probably calculate these bounds in a faster way mesh.RecalculateBounds(); return(mesh); }
public void OnPathComplete(Path p) { base.StartCoroutine(this.WaitToRepath()); if (p.error) { return; } this.path = p.vectorPath.ToArray(); float num = float.PositiveInfinity; int num2 = 0; for (int i = 0; i < this.path.Length - 1; i++) { float num3 = AstarMath.DistancePointSegmentStrict(this.path[i], this.path[i + 1], this.tr.position); if (num3 < num) { num2 = 0; num = num3; this.pathIndex = i + 1; } else if (num2 > 6) { break; } } }
public void OnDrawGizmos() { if (this.points.Length >= 3) { for (int i = 0; i < this.points.Length; i++) { if (this.points[i] == null) { return; } } for (int j = 0; j < this.points.Length; j++) { int num = this.points.Length; Vector3 normalized = ((this.points[(j + 1) % num].position - this.points[j].position).normalized - (this.points[(j - 1 + num) % num].position - this.points[j].position).normalized).normalized; Vector3 normalized2 = ((this.points[(j + 2) % num].position - this.points[(j + 1) % num].position).normalized - (this.points[(j + num) % num].position - this.points[(j + 1) % num].position).normalized).normalized; Vector3 from = this.points[j].position; for (int k = 1; k <= 100; k++) { Vector3 vector = AstarMath.CubicBezier(this.points[j].position, this.points[j].position + normalized * this.tangentLengths, this.points[(j + 1) % num].position - normalized2 * this.tangentLengths, this.points[(j + 1) % num].position, (float)k / 100f); Gizmos.DrawLine(from, vector); from = vector; } } } }
/** Calculates target point from the current line segment. * \param p Current position * \param a Line segment start * \param b Line segment end * The returned point will lie somewhere on the line segment. * \see #forwardLook * \todo This function uses .magnitude quite a lot, can it be optimized? */ protected Vector3 CalculateTargetPoint(Vector3 p, Vector3 a, Vector3 b) { if (entity == null || entity.MoveState != Pathea.MovementState.Water) { a.y = p.y; b.y = p.y; } float magn = (a - b).magnitude; if (magn == 0) { return(a); } float closest = AstarMath.Clamp01(AstarMath.NearestPointFactor(a, b, p)); Vector3 point = (b - a) * closest + a; float distance = (point - p).magnitude; float lookAhead = Mathf.Clamp(forwardLook - distance, 0.0F, forwardLook); float offset = lookAhead / magn; offset = Mathf.Clamp(offset + closest, 0.0F, 1.0F); return((b - a) * offset + a); }
public void OnDrawGizmos() { if (points.Length >= 3) { for (int i = 0; i < points.Length; i++) { if (points[i] == null) { return; } } for (int pt = 0; pt < points.Length; pt++) { int c = points.Length; Vector3 inTang = ((points[(pt + 1) % c].position - points[pt + 0].position).normalized - (points[(pt - 1 + c) % c].position - points[pt + 0].position).normalized).normalized; Vector3 outTang = ((points[(pt + 2) % c].position - points[(pt + 1) % c].position).normalized - (points[(pt - 0 + c) % c].position - points[(pt + 1) % c].position).normalized).normalized; Vector3 pp = points[pt].position; for (int i = 1; i <= 100; i++) { Vector3 p = AstarMath.CubicBezier(points[pt].position, points[pt].position + inTang * tangentLengths, points[(pt + 1) % c].position - outTang * tangentLengths, points[(pt + 1) % c].position, i / 100.0f); Gizmos.DrawLine(pp, p); pp = p; } } } }
void OnDrawGizmos(int boxi, int depth) { BBTreeBox box = arr[boxi]; var min = (Vector3) new Int3(box.rect.xmin, 0, box.rect.ymin); var max = (Vector3) new Int3(box.rect.xmax, 0, box.rect.ymax); Vector3 center = (min + max) * 0.5F; Vector3 size = (max - center) * 2; size = new Vector3(size.x, 1, size.z); center.y += depth * 2; Gizmos.color = AstarMath.IntToColor(depth, 1f); //new Color (0,0,0,0.2F); Gizmos.DrawCube(center, size); if (box.node != null) { } else { OnDrawGizmos(box.left, depth + 1); OnDrawGizmos(box.right, depth + 1); } }
/** Finds the closest point on the current path. * Sets #currentWaypointIndex and #lerpTime to the appropriate values. */ protected virtual void ConfigureNewPath() { var points = path.vectorPath; var currentPosition = GetFeetPosition(); float bestFactor = 0; float bestDist = float.PositiveInfinity; int bestIndex = 0; for (int i = 0; i < points.Count - 1; i++) { float factor = AstarMath.NearestPointFactor(points[i], points[i + 1], currentPosition); Vector3 point = Vector3.Lerp(points[i], points[i + 1], factor); float dist = (currentPosition - point).sqrMagnitude; if (dist < bestDist) { bestDist = dist; bestFactor = factor; bestIndex = i + 1; } } currentWaypointIndex = bestIndex; lerpTime = bestFactor; }
// Token: 0x0600079F RID: 1951 RVA: 0x00049E78 File Offset: 0x00048278 public void Update() { if (this.rvoAgent == null) { return; } if (this.lastPosition != this.tr.position) { this.Teleport(this.tr.position); } if (this.lockWhenNotMoving) { this.locked = (this.desiredVelocity == Vector3.zero); } this.UpdateAgentProperties(); Vector3 interpolatedPosition = this.rvoAgent.InterpolatedPosition; interpolatedPosition.y = this.adjustedY; RaycastHit raycastHit; if (this.mask != 0 && Physics.Raycast(interpolatedPosition + Vector3.up * this.height * 0.5f, Vector3.down, out raycastHit, float.PositiveInfinity, this.mask)) { this.adjustedY = raycastHit.point.y; } else { this.adjustedY = 0f; } interpolatedPosition.y = this.adjustedY; this.rvoAgent.SetYPosition(this.adjustedY); Vector3 a = Vector3.zero; if (this.wallAvoidFalloff > 0f && this.wallAvoidForce > 0f) { List <ObstacleVertex> neighbourObstacles = this.rvoAgent.NeighbourObstacles; if (neighbourObstacles != null) { for (int i = 0; i < neighbourObstacles.Count; i++) { Vector3 position = neighbourObstacles[i].position; Vector3 position2 = neighbourObstacles[i].next.position; Vector3 vector = this.position - AstarMath.NearestPointStrict(position, position2, this.position); if (!(vector == position) && !(vector == position2)) { float sqrMagnitude = vector.sqrMagnitude; vector /= sqrMagnitude * this.wallAvoidFalloff; a += vector; } } } } this.rvoAgent.DesiredVelocity = this.desiredVelocity + a * this.wallAvoidForce; this.tr.position = interpolatedPosition + Vector3.up * this.height * 0.5f - this.center; this.lastPosition = this.tr.position; if (this.enableRotation && this.velocity != Vector3.zero) { base.transform.rotation = Quaternion.Lerp(base.transform.rotation, Quaternion.LookRotation(this.velocity), Time.deltaTime * this.rotationSpeed * Mathf.Min(this.velocity.magnitude, 0.2f)); } }
private void Update() { Vector3 a = this.PointToGraphSpace(this.graph.center); Vector3 b = this.PointToGraphSpace(this.target.position); if (AstarMath.SqrMagnitudeXZ(a, b) > this.updateDistance * this.updateDistance) { this.UpdateGraph(); } }
// Update is called once per frame void Update() { // Check the distance along the XZ plane // we only move the graph in the X and Z directions so // checking for if the Y coordinate has changed is // not something we want to do if (AstarMath.SqrMagnitudeXZ(target.position, graph.center) > updateDistance * updateDistance) { UpdateGraph(); } }
private Vector3 Plot(float t) { int num = this.points.Length; int num2 = Mathf.FloorToInt(t); Vector3 normalized = ((this.points[(num2 + 1) % num].position - this.points[num2 % num].position).normalized - (this.points[(num2 - 1 + num) % num].position - this.points[num2 % num].position).normalized).normalized; Vector3 normalized2 = ((this.points[(num2 + 2) % num].position - this.points[(num2 + 1) % num].position).normalized - (this.points[(num2 + num) % num].position - this.points[(num2 + 1) % num].position).normalized).normalized; Debug.DrawLine(this.points[num2 % num].position, this.points[num2 % num].position + normalized * this.tangentLengths, Color.red); Debug.DrawLine(this.points[(num2 + 1) % num].position - normalized2 * this.tangentLengths, this.points[(num2 + 1) % num].position, Color.green); return(AstarMath.CubicBezier(this.points[num2 % num].position, this.points[num2 % num].position + normalized * this.tangentLengths, this.points[(num2 + 1) % num].position - normalized2 * this.tangentLengths, this.points[(num2 + 1) % num].position, t - (float)num2)); }
/** Update is called once per frame */ void Update() { // Calculate where the graph center and the target position is in graph space var graphCenterInGraphSpace = PointToGraphSpace(graph.center); var targetPositionInGraphSpace = PointToGraphSpace(target.position); // Check the distance in graph space // We only care about the X and Z axes since the Y axis is the "height" coordinate of the nodes (in graph space) // We only care about the plane that the nodes are placed in if (AstarMath.SqrMagnitudeXZ(graphCenterInGraphSpace, targetPositionInGraphSpace) > updateDistance * updateDistance) { UpdateGraph(); } }
//public System.Object lockObject; public void AddSpan(uint bottom, uint top, int area, int voxelWalkableClimb) { VoxelSpan span = new VoxelSpan (bottom,top,area); if (firstSpan == null) { firstSpan = span; return; } VoxelSpan prev = null; VoxelSpan cSpan = firstSpan; while (cSpan != null) { if (cSpan.bottom > span.top) { break; } else if (cSpan.top < span.bottom) { prev = cSpan; cSpan = cSpan.next; } else { if (cSpan.bottom < bottom) { span.bottom = cSpan.bottom; } if (cSpan.top > top) { span.top = cSpan.top; } //1 is flagMergeDistance, when a walkable flag is favored before an unwalkable one if (AstarMath.Abs ((int)span.top - (int)cSpan.top) <= voxelWalkableClimb) { span.area = AstarMath.Max (span.area,cSpan.area); } VoxelSpan next = cSpan.next; if (prev != null) { prev.next = next; } else { firstSpan = next; } cSpan = next; } } if (prev != null) { span.next = prev.next; prev.next = span; } else { span.next = firstSpan; firstSpan = span; } }
Vector3 Plot(float t) { Vector3 inTang, outTang; int c = points.Length; int pt = Mathf.FloorToInt(t); inTang = ((points[(pt + 1) % c].position - points[(pt + 0) % c].position).normalized - (points[(pt - 1 + c) % c].position - points[(pt + 0) % c].position).normalized).normalized; outTang = ((points[(pt + 2) % c].position - points[(pt + 1) % c].position).normalized - (points[(pt - 0 + c) % c].position - points[(pt + 1) % c].position).normalized).normalized; Debug.DrawLine(points[pt % c].position, points[pt % c].position + inTang * tangentLengths, Color.red); Debug.DrawLine(points[(pt + 1) % c].position - outTang * tangentLengths, points[(pt + 1) % c].position, Color.green); return(AstarMath.CubicBezier(points[pt % c].position, points[pt % c].position + inTang * tangentLengths, points[(pt + 1) % c].position - outTang * tangentLengths, points[(pt + 1) % c].position, t - pt)); }
protected Vector3 CalculateTargetPoint(Vector3 p, Vector3 a, Vector3 b) { a.y = p.y; b.y = p.y; float magn = (a - b).magnitude; if (magn == 0) return a; float closest = AstarMath.Clamp01(AstarMath.NearestPointFactor(a, b, p)); Vector3 point = (b - a) * closest + a; float distance = (point - p).magnitude; float lookAhead = Mathf.Clamp(forwardLook - distance, 0.0F, forwardLook); float offset = lookAhead / magn; offset = Mathf.Clamp(offset + closest, 0.0F, 1.0F); return (b - a) * offset + a; }
private void OnDrawGizmos() { List <Vector3>[] paths = drawPaths; for (int i = 0; i < paths.Length; i++) { List <Vector3> pt = paths[i]; if (pt == null) { Debug.LogWarning("Path Number " + i + " cound not be found"); continue; } for (int j = 0; j < pt.Count - 1; j++) { Debug.DrawLine(pt[j], pt[j + 1], AstarMath.IntToColor(i, 0.5f)); } } }
public void OnPathComplete(Path p) { Debug.Log("Got Callback"); if (p.error) { Debug.Log("Ouch, the path returned an error"); Debug.LogError(p.errorLog); return; } List <Vector3> path = p.vectorPath; for (int j = 0; j < path.Count - 1; j++) { // Plot segment j to j+1 with a nice color got from Pathfinding.AstarMath.IntToColor Debug.DrawLine(path[j], path[j + 1], AstarMath.IntToColor(1, 0.5F), 1); } }
public void InsertObstacleNeighbour(ObstacleVertex ob1, float rangeSq) { ObstacleVertex obstacleVertex = ob1.next; float num = AstarMath.DistancePointSegmentStrict(ob1.position, obstacleVertex.position, this.Position); if (num < rangeSq) { this.obstacles.Add(ob1); this.obstacleDists.Add(num); int num2 = this.obstacles.Count - 1; while (num2 != 0 && num < this.obstacleDists[num2 - 1]) { this.obstacles[num2] = this.obstacles[num2 - 1]; this.obstacleDists[num2] = this.obstacleDists[num2 - 1]; num2--; } this.obstacles[num2] = ob1; this.obstacleDists[num2] = num; } }
/*public void UpdateNeighbours () { * neighbours.Clear (); * float sqrDist = neighbourDistance*neighbourDistance; * for ( int i = 0; i < simulator.agents.Count; i++ ) { * float dist = (simulator.agents[i].position - position).sqrMagnitude; * if ( dist <= sqrDist ) { * neighbours.Add ( simulator.agents[i] ); * } * } * }*/ public void InsertObstacleNeighbour(ObstacleVertex ob1, float rangeSq) { ObstacleVertex ob2 = ob1.next; float dist = AstarMath.DistancePointSegmentStrict(ob1.position, ob2.position, Position); if (dist < rangeSq) { obstacles.Add(ob1); obstacleDists.Add(dist); int i = obstacles.Count - 1; while (i != 0 && dist < obstacleDists[i - 1]) { obstacles[i] = obstacles[i - 1]; obstacleDists[i] = obstacleDists[i - 1]; i--; } obstacles[i] = ob1; obstacleDists[i] = dist; } }
protected Vector3 CalculateTargetPoint(Vector3 p, Vector3 a, Vector3 b, bool canGoDirectly) { if (canGoDirectly && (b - this.target.position).sqrMagnitude < 16f) { return(this.target.position); } a.y = p.y; b.y = p.y; float magnitude = (a - b).magnitude; if (magnitude == 0f) { return(a); } float num = AstarMath.Clamp01(AstarMath.NearestPointFactor(a, b, p)); Vector3 vector = (b - a) * num + a; float magnitude2 = (vector - p).magnitude; float num2 = Mathf.Clamp(this.forwardLook - magnitude2, 0f, this.forwardLook); float num3 = num2 / magnitude; num3 = Mathf.Clamp(num3 + num, 0f, 1f); return((b - a) * num3 + a); }
/** Builds a polygon mesh from a contour set. * \param nvp Maximum allowed vertices per polygon. \note Currently locked to 3 */ public void BuildPolyMesh(VoxelContourSet cset, int nvp, out VoxelMesh mesh) { AstarProfiler.StartProfile("Build Poly Mesh"); nvp = 3; int maxVertices = 0; int maxTris = 0; int maxVertsPerCont = 0; for (int i = 0; i < cset.conts.Count; i++) { // Skip null contours. if (cset.conts[i].nverts < 3) { continue; } maxVertices += cset.conts[i].nverts; maxTris += cset.conts[i].nverts - 2; maxVertsPerCont = AstarMath.Max(maxVertsPerCont, cset.conts[i].nverts); } if (maxVertices >= 65534) { Debug.LogWarning("To many vertices for unity to render - Unity might screw up rendering, but hopefully the navmesh will work ok"); //mesh = new VoxelMesh (); //yield break; //return; } //int[] vflags = new int[maxVertices]; /** \todo Could be cached to avoid allocations */ Int3[] verts = new Int3[maxVertices]; /** \todo Could be cached to avoid allocations */ int[] polys = new int[maxTris * nvp]; //int[] regs = new int[maxTris]; //int[] areas = new int[maxTris]; Pathfinding.Util.Memory.MemSet <int> (polys, 0xff, sizeof(int)); //for (int i=0;i<polys.Length;i++) { // polys[i] = 0xff; //} //int[] nexVert = new int[maxVertices]; //int[] firstVert = new int[VERTEX_BUCKET_COUNT]; int[] indices = new int[maxVertsPerCont]; int[] tris = new int[maxVertsPerCont * 3]; //ushort[] polys int vertexIndex = 0; int polyIndex = 0; for (int i = 0; i < cset.conts.Count; i++) { VoxelContour cont = cset.conts[i]; //Skip null contours if (cont.nverts < 3) { continue; } for (int j = 0; j < cont.nverts; j++) { indices[j] = j; cont.verts[j * 4 + 2] /= voxelArea.width; } //yield return (GameObject.FindObjectOfType (typeof(MonoBehaviour)) as MonoBehaviour).StartCoroutine ( //Triangulate (cont.nverts, cont.verts, indices, tris); int ntris = Triangulate(cont.nverts, cont.verts, ref indices, ref tris); /*if (ntris > cont.nverts-2) { * Debug.LogError (ntris + " "+cont.nverts+" "+cont.verts.Length+" "+(cont.nverts-2)); * } * * if (ntris > maxVertsPerCont) { * Debug.LogError (ntris*3 + " "+maxVertsPerCont); * } * * int tmp = polyIndex; * * Debug.Log (maxTris + " "+polyIndex+" "+polys.Length+" "+ntris+" "+(ntris*3) + " " + cont.nverts);*/ int startIndex = vertexIndex; for (int j = 0; j < ntris * 3; polyIndex++, j++) { //@Error sometimes polys[polyIndex] = tris[j] + startIndex; } /*int tmp2 = polyIndex; * if (tmp+ntris*3 != tmp2) { * Debug.LogWarning (tmp+" "+(tmp+ntris*3)+" "+tmp2+" "+ntris*3); * }*/ for (int j = 0; j < cont.nverts; vertexIndex++, j++) { verts[vertexIndex] = new Int3(cont.verts[j * 4], cont.verts[j * 4 + 1], cont.verts[j * 4 + 2]); } } mesh = new VoxelMesh(); //yield break; Int3[] trimmedVerts = new Int3[vertexIndex]; for (int i = 0; i < vertexIndex; i++) { trimmedVerts[i] = verts[i]; } int[] trimmedTris = new int[polyIndex]; System.Buffer.BlockCopy(polys, 0, trimmedTris, 0, polyIndex * sizeof(int)); //for (int i=0;i<polyIndex;i++) { // trimmedTris[i] = polys[i]; //} mesh.verts = trimmedVerts; mesh.tris = trimmedTris; /*for (int i=0;i<mesh.tris.Length/3;i++) { * * int p = i*3; * * int p1 = mesh.tris[p]; * int p2 = mesh.tris[p+1]; * int p3 = mesh.tris[p+2]; * * //Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p1].x,mesh.verts[p1].y,mesh.verts[p1].z),ConvertPosCorrZ (mesh.verts[p2].x,mesh.verts[p2].y,mesh.verts[p2].z),Color.yellow); * //Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p1].x,mesh.verts[p1].y,mesh.verts[p1].z),ConvertPosCorrZ (mesh.verts[p3].x,mesh.verts[p3].y,mesh.verts[p3].z),Color.yellow); * //Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p3].x,mesh.verts[p3].y,mesh.verts[p3].z),ConvertPosCorrZ (mesh.verts[p2].x,mesh.verts[p2].y,mesh.verts[p2].z),Color.yellow); * * //Debug.DrawLine (ConvertPosCorrZ (verts[p1],0,verts[p1+2]),ConvertPosCorrZ (verts[p2],0,verts[p2+2]),Color.blue); * //Debug.DrawLine (ConvertPosCorrZ (verts[p1],0,verts[p1+2]),ConvertPosCorrZ (verts[p3],0,verts[p3+2]),Color.blue); * //Debug.DrawLine (ConvertPosCorrZ (verts[p2],0,verts[p2+2]),ConvertPosCorrZ (verts[p3],0,verts[p3+2]),Color.blue); * * }*/ AstarProfiler.EndProfile("Build Poly Mesh"); }
/** Color from an angle */ public Color GetColor(float angle) { return(AstarMath.HSVToRGB(angle * rad2Deg, 0.8f, 0.6f)); }
//Code almost completely ripped from Recast public void FilterLedges(uint voxelWalkableHeight, int voxelWalkableClimb, float cs, float ch, Vector3 min) { int wd = voxelArea.width * voxelArea.depth; #if !ASTAR_RECAST_CLASS_BASED_LINKED_LIST LinkedVoxelSpan[] spans = voxelArea.linkedSpans; int[] DirectionX = voxelArea.DirectionX; int[] DirectionZ = voxelArea.DirectionZ; #endif int width = voxelArea.width; //Filter all ledges for (int z = 0, pz = 0; z < wd; z += width, pz++) { for (int x = 0; x < width; x++) { #if !ASTAR_RECAST_CLASS_BASED_LINKED_LIST if (spans[x + z].bottom == VoxelArea.InvalidSpanValue) { continue; } for (int s = x + z; s != -1; s = spans[s].next) { //Skip non-walkable spans if (spans[s].area == UnwalkableArea) { continue; } int bottom = (int)spans[s].top; int top = spans[s].next != -1 ? (int)spans[spans[s].next].bottom : VoxelArea.MaxHeightInt; int minHeight = VoxelArea.MaxHeightInt; int aMinHeight = (int)spans[s].top; int aMaxHeight = aMinHeight; for (int d = 0; d < 4; d++) { int nx = x + DirectionX[d]; int nz = z + DirectionZ[d]; //Skip out-of-bounds points if (nx < 0 || nz < 0 || nz >= wd || nx >= width) { spans[s].area = UnwalkableArea; break; } int nsx = nx + nz; int nbottom = -voxelWalkableClimb; int ntop = spans[nsx].bottom != VoxelArea.InvalidSpanValue ? (int)spans[nsx].bottom : VoxelArea.MaxHeightInt; if (System.Math.Min(top, ntop) - System.Math.Max(bottom, nbottom) > voxelWalkableHeight) { minHeight = System.Math.Min(minHeight, nbottom - bottom); } //Loop through spans if (spans[nsx].bottom != VoxelArea.InvalidSpanValue) { for (int ns = nsx; ns != -1; ns = spans[ns].next) { nbottom = (int)spans[ns].top; ntop = spans[ns].next != -1 ? (int)spans[spans[ns].next].bottom : VoxelArea.MaxHeightInt; if (System.Math.Min(top, ntop) - System.Math.Max(bottom, nbottom) > voxelWalkableHeight) { minHeight = System.Math.Min(minHeight, nbottom - bottom); if (System.Math.Abs(nbottom - bottom) <= voxelWalkableClimb) { if (nbottom < aMinHeight) { aMinHeight = nbottom; } if (nbottom > aMaxHeight) { aMaxHeight = nbottom; } } } } } } if (minHeight < -voxelWalkableClimb || (aMaxHeight - aMinHeight) > voxelWalkableClimb) { spans[s].area = UnwalkableArea; } } #else for (VoxelSpan s = voxelArea.cells[z + x].firstSpan; s != null; s = s.next) { //Skip non-walkable spans if (s.area == UnwalkableArea) { continue; } int bottom = (int)s.top; int top = s.next != null ? (int)s.next.bottom : VoxelArea.MaxHeightInt; int minHeight = VoxelArea.MaxHeightInt; int aMinHeight = (int)s.top; int aMaxHeight = (int)s.top; for (int d = 0; d < 4; d++) { int nx = x + voxelArea.DirectionX[d]; int nz = z + voxelArea.DirectionZ[d]; //Skip out-of-bounds points if (nx < 0 || nz < 0 || nz >= wd || nx >= voxelArea.width) { s.area = UnwalkableArea; break; } VoxelSpan nsx = voxelArea.cells[nx + nz].firstSpan; int nbottom = -voxelWalkableClimb; int ntop = nsx != null ? (int)nsx.bottom : VoxelArea.MaxHeightInt; if (AstarMath.Min(top, ntop) - AstarMath.Max(bottom, nbottom) > voxelWalkableHeight) { minHeight = AstarMath.Min(minHeight, nbottom - bottom); } //Loop through spans for (VoxelSpan ns = nsx; ns != null; ns = ns.next) { nbottom = (int)ns.top; ntop = ns.next != null ? (int)ns.next.bottom : VoxelArea.MaxHeightInt; if (AstarMath.Min(top, ntop) - AstarMath.Max(bottom, nbottom) > voxelWalkableHeight) { minHeight = AstarMath.Min(minHeight, nbottom - bottom); if (AstarMath.Abs(nbottom - bottom) <= voxelWalkableClimb) { if (nbottom < aMinHeight) { aMinHeight = nbottom; } if (nbottom > aMaxHeight) { aMaxHeight = nbottom; } } } } } if (minHeight < -voxelWalkableClimb || (aMaxHeight - aMinHeight) > voxelWalkableClimb) { s.area = UnwalkableArea; } } #endif } } }
public void BuildCompactField() { AstarProfiler.StartProfile("Build Compact Voxel Field"); //Build compact representation int spanCount = voxelArea.GetSpanCount(); voxelArea.compactSpanCount = spanCount; if (voxelArea.compactSpans == null || voxelArea.compactSpans.Length < spanCount) { voxelArea.compactSpans = new CompactVoxelSpan[spanCount]; voxelArea.areaTypes = new int[spanCount]; } uint idx = 0; int w = voxelArea.width; int d = voxelArea.depth; int wd = w * d; if (this.voxelWalkableHeight >= 0xFFFF) { Debug.LogWarning("Too high walkable height to guarantee correctness. Increase voxel height or lower walkable height."); } #if !ASTAR_RECAST_CLASS_BASED_LINKED_LIST LinkedVoxelSpan[] spans = voxelArea.linkedSpans; #endif //Parallel.For (0, voxelArea.depth, delegate (int pz) { for (int z = 0, pz = 0; z < wd; z += w, pz++) { for (int x = 0; x < w; x++) { #if !ASTAR_RECAST_CLASS_BASED_LINKED_LIST int spanIndex = x + z; if (spans[spanIndex].bottom == VoxelArea.InvalidSpanValue) { voxelArea.compactCells[x + z] = new CompactVoxelCell(0, 0); continue; } uint index = idx; uint count = 0; //Vector3 p = new Vector3(x,0,pz)*cellSize+voxelOffset; while (spanIndex != -1) { if (spans[spanIndex].area != UnwalkableArea) { int bottom = (int)spans[spanIndex].top; int next = spans[spanIndex].next; int top = next != -1 ? (int)spans[next].bottom : VoxelArea.MaxHeightInt; voxelArea.compactSpans[idx] = new CompactVoxelSpan((ushort)(bottom > 0xFFFF ? 0xFFFF : bottom), (uint)(top - bottom > 0xFFFF ? 0xFFFF : top - bottom)); voxelArea.areaTypes[idx] = spans[spanIndex].area; idx++; count++; } spanIndex = spans[spanIndex].next; } voxelArea.compactCells[x + z] = new CompactVoxelCell(index, count); #else VoxelSpan s = voxelArea.cells[x + z].firstSpan; if (s == null) { voxelArea.compactCells[x + z] = new CompactVoxelCell(0, 0); continue; } uint index = idx; uint count = 0; //Vector3 p = new Vector3(x,0,pz)*cellSize+voxelOffset; while (s != null) { if (s.area != UnwalkableArea) { int bottom = (int)s.top; int top = s.next != null ? (int)s.next.bottom : VoxelArea.MaxHeightInt; voxelArea.compactSpans[idx] = new CompactVoxelSpan((ushort)AstarMath.Clamp(bottom, 0, 0xffff), (uint)AstarMath.Clamp(top - bottom, 0, 0xffff)); voxelArea.areaTypes[idx] = s.area; idx++; count++; } s = s.next; } voxelArea.compactCells[x + z] = new CompactVoxelCell(index, count); #endif } } AstarProfiler.EndProfile("Build Compact Voxel Field"); }
/// <summary>Create a number of agents in circle and restart simulation</summary> public void CreateAgents(int num) { this.agentCount = num; agents = new List <IAgent>(agentCount); goals = new List <Vector3>(agentCount); colors = new List <Color>(agentCount); sim.ClearAgents(); if (type == RVOExampleType.Circle) { float circleRad = Mathf.Sqrt(agentCount * radius * radius * 4 / Mathf.PI) * exampleScale * 0.05f; for (int i = 0; i < agentCount; i++) { Vector3 pos = new Vector3(Mathf.Cos(i * Mathf.PI * 2.0f / agentCount), 0, Mathf.Sin(i * Mathf.PI * 2.0f / agentCount)) * circleRad * (1 + Random.value * 0.01f); IAgent agent = sim.AddAgent(new Vector2(pos.x, pos.z), pos.y); agents.Add(agent); goals.Add(-pos); colors.Add(AstarMath.HSVToRGB(i * 360.0f / agentCount, 0.8f, 0.6f)); } } else if (type == RVOExampleType.Line) { for (int i = 0; i < agentCount; i++) { Vector3 pos = new Vector3((i % 2 == 0 ? 1 : -1) * exampleScale, 0, (i / 2) * radius * 2.5f); IAgent agent = sim.AddAgent(new Vector2(pos.x, pos.z), pos.y); agents.Add(agent); goals.Add(new Vector3(-pos.x, pos.y, pos.z)); colors.Add(i % 2 == 0 ? Color.red : Color.blue); } } else if (type == RVOExampleType.Point) { for (int i = 0; i < agentCount; i++) { Vector3 pos = new Vector3(Mathf.Cos(i * Mathf.PI * 2.0f / agentCount), 0, Mathf.Sin(i * Mathf.PI * 2.0f / agentCount)) * exampleScale; IAgent agent = sim.AddAgent(new Vector2(pos.x, pos.z), pos.y); agents.Add(agent); goals.Add(new Vector3(0, pos.y, 0)); colors.Add(AstarMath.HSVToRGB(i * 360.0f / agentCount, 0.8f, 0.6f)); } } else if (type == RVOExampleType.RandomStreams) { float circleRad = Mathf.Sqrt(agentCount * radius * radius * 4 / Mathf.PI) * exampleScale * 0.05f; for (int i = 0; i < agentCount; i++) { float angle = Random.value * Mathf.PI * 2.0f; float targetAngle = Random.value * Mathf.PI * 2.0f; Vector3 pos = new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * uniformDistance(circleRad); IAgent agent = sim.AddAgent(new Vector2(pos.x, pos.z), pos.y); agents.Add(agent); goals.Add(new Vector3(Mathf.Cos(targetAngle), 0, Mathf.Sin(targetAngle)) * uniformDistance(circleRad)); colors.Add(AstarMath.HSVToRGB(targetAngle * Mathf.Rad2Deg, 0.8f, 0.6f)); } } else if (type == RVOExampleType.Crossing) { float distanceBetweenGroups = exampleScale * radius * 0.5f; int directions = (int)Mathf.Sqrt(agentCount / 25f); directions = Mathf.Max(directions, 2); const int AgentsPerDistance = 10; for (int i = 0; i < agentCount; i++) { float angle = ((i % directions) / (float)directions) * Mathf.PI * 2.0f; var dist = distanceBetweenGroups * ((i / (directions * AgentsPerDistance) + 1) + 0.3f * Random.value); Vector3 pos = new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * dist; IAgent agent = sim.AddAgent(new Vector2(pos.x, pos.z), pos.y); agent.Priority = (i % directions) == 0 ? 1 : 0.01f; agents.Add(agent); goals.Add(-pos.normalized * distanceBetweenGroups * 3); colors.Add(AstarMath.HSVToRGB(angle * Mathf.Rad2Deg, 0.8f, 0.6f)); } } SetAgentSettings(); verts = new Vector3[4 * agents.Count]; uv = new Vector2[verts.Length]; tris = new int[agents.Count * 2 * 3]; meshColors = new Color[verts.Length]; }