private RasterizationMesh RasterizeCollider(Collider col, Matrix4x4 localToWorldMatrix) { RasterizationMesh result = null; if (col is BoxCollider) { result = this.RasterizeBoxCollider(col as BoxCollider, localToWorldMatrix); } else if (col is SphereCollider || col is CapsuleCollider) { SphereCollider sphereCollider = col as SphereCollider; CapsuleCollider capsuleCollider = col as CapsuleCollider; float num = (!(sphereCollider != null)) ? capsuleCollider.radius : sphereCollider.radius; float height = (!(sphereCollider != null)) ? (capsuleCollider.height * 0.5f / num - 1f) : 0f; Matrix4x4 matrix4x = Matrix4x4.TRS((!(sphereCollider != null)) ? capsuleCollider.center : sphereCollider.center, Quaternion.identity, Vector3.one * num); matrix4x = localToWorldMatrix * matrix4x; result = this.RasterizeCapsuleCollider(num, height, col.bounds, matrix4x); } else if (col is MeshCollider) { MeshCollider meshCollider = col as MeshCollider; if (meshCollider.sharedMesh != null && meshCollider.sharedMesh.isReadable) { result = new RasterizationMesh(meshCollider.sharedMesh.vertices, meshCollider.sharedMesh.triangles, meshCollider.bounds, localToWorldMatrix); } } return(result); }
// Token: 0x060027D2 RID: 10194 RVA: 0x001B4B24 File Offset: 0x001B2D24 private void CollectTreeMeshes(Terrain terrain, List <RasterizationMesh> result) { TerrainData terrainData = terrain.terrainData; for (int i = 0; i < terrainData.treeInstances.Length; i++) { TreeInstance treeInstance = terrainData.treeInstances[i]; TreePrototype treePrototype = terrainData.treePrototypes[treeInstance.prototypeIndex]; if (!(treePrototype.prefab == null)) { Collider component = treePrototype.prefab.GetComponent <Collider>(); Vector3 pos = terrain.transform.position + Vector3.Scale(treeInstance.position, terrainData.size); if (component == null) { Bounds bounds = new Bounds(terrain.transform.position + Vector3.Scale(treeInstance.position, terrainData.size), new Vector3(treeInstance.widthScale, treeInstance.heightScale, treeInstance.widthScale)); Matrix4x4 matrix = Matrix4x4.TRS(pos, Quaternion.identity, new Vector3(treeInstance.widthScale, treeInstance.heightScale, treeInstance.widthScale) * 0.5f); RasterizationMesh item = new RasterizationMesh(RecastMeshGatherer.BoxColliderVerts, RecastMeshGatherer.BoxColliderTris, bounds, matrix); result.Add(item); } else { Vector3 s = new Vector3(treeInstance.widthScale, treeInstance.heightScale, treeInstance.widthScale); RasterizationMesh rasterizationMesh = this.RasterizeCollider(component, Matrix4x4.TRS(pos, Quaternion.identity, s)); if (rasterizationMesh != null) { rasterizationMesh.RecalculateBounds(); result.Add(rasterizationMesh); } } } } }
// Token: 0x0600262F RID: 9775 RVA: 0x001A8028 File Offset: 0x001A6228 private List <RasterizationMesh>[] PutMeshesIntoTileBuckets(List <RasterizationMesh> meshes) { List <RasterizationMesh>[] array = new List <RasterizationMesh> [this.tiles.Length]; Vector3 amount = new Vector3(1f, 0f, 1f) * this.TileBorderSizeInWorldUnits * 2f; for (int i = 0; i < array.Length; i++) { array[i] = ListPool <RasterizationMesh> .Claim(); } for (int j = 0; j < meshes.Count; j++) { RasterizationMesh rasterizationMesh = meshes[j]; Bounds bounds = rasterizationMesh.bounds; bounds.Expand(amount); IntRect touchingTiles = base.GetTouchingTiles(bounds); for (int k = touchingTiles.ymin; k <= touchingTiles.ymax; k++) { for (int l = touchingTiles.xmin; l <= touchingTiles.xmax; l++) { array[l + k * this.tileXCount].Add(rasterizationMesh); } } } return(array); }
// Token: 0x060027D5 RID: 10197 RVA: 0x001B4D9C File Offset: 0x001B2F9C private RasterizationMesh RasterizeCollider(Collider col, Matrix4x4 localToWorldMatrix) { RasterizationMesh result = null; if (col is BoxCollider) { result = this.RasterizeBoxCollider(col as BoxCollider, localToWorldMatrix); } else if (col is SphereCollider || col is CapsuleCollider) { SphereCollider sphereCollider = col as SphereCollider; CapsuleCollider capsuleCollider = col as CapsuleCollider; float num = (sphereCollider != null) ? sphereCollider.radius : capsuleCollider.radius; float height = (sphereCollider != null) ? 0f : (capsuleCollider.height * 0.5f / num - 1f); Quaternion q = Quaternion.identity; if (capsuleCollider != null) { q = Quaternion.Euler((float)((capsuleCollider.direction == 2) ? 90 : 0), 0f, (float)((capsuleCollider.direction == 0) ? 90 : 0)); } Matrix4x4 matrix4x = Matrix4x4.TRS((sphereCollider != null) ? sphereCollider.center : capsuleCollider.center, q, Vector3.one * num); matrix4x = localToWorldMatrix * matrix4x; result = this.RasterizeCapsuleCollider(num, height, col.bounds, matrix4x); } else if (col is MeshCollider) { MeshCollider meshCollider = col as MeshCollider; if (meshCollider.sharedMesh != null) { result = new RasterizationMesh(meshCollider.sharedMesh.vertices, meshCollider.sharedMesh.triangles, meshCollider.bounds, localToWorldMatrix); } } return(result); }
/** 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 CollectColliderMeshes(List <RasterizationMesh> result) { var colls = MonoBehaviour.FindObjectsOfType <Collider>(); if (tagMask.Count > 0 || mask != 0) { for (int i = 0; i < colls.Length; i++) { Collider col = colls[i]; if ((((mask >> col.gameObject.layer) & 1) != 0 || tagMask.Contains(col.tag)) && col.enabled && !col.isTrigger && col.bounds.Intersects(bounds) && col.GetComponent <RecastMeshObj>() == null) { RasterizationMesh emesh = RasterizeCollider(col); //Make sure a valid ExtraMesh was returned if (emesh != null) { result.Add(emesh); } } } } // Clear cache to avoid memory leak capsuleCache.Clear(); }
public void CollectColliderMeshes(List <RasterizationMesh> result) { /// <summary>TODO: Use Physics.OverlapBox on newer Unity versions</summary> // Find all colliders that could possibly be inside the bounds var colls = Physics.OverlapSphere(bounds.center, bounds.size.magnitude, -1, QueryTriggerInteraction.Ignore); if (tagMask.Count > 0 || mask != 0) { for (int i = 0; i < colls.Length; i++) { Collider collider = colls[i]; if ((((mask >> collider.gameObject.layer) & 1) != 0 || tagMask.Contains(collider.tag)) && collider.enabled && !collider.isTrigger && collider.bounds.Intersects(bounds) && collider.GetComponent <RecastMeshObj>() == null) { RasterizationMesh emesh = RasterizeCollider(collider); //Make sure a valid RasterizationMesh was returned if (emesh != null) { result.Add(emesh); } } } } // Clear cache to avoid memory leak capsuleCache.Clear(); }
private RasterizationMesh RasterizeCollider(Collider col, Matrix4x4 localToWorldMatrix) { RasterizationMesh mesh = null; if (col is BoxCollider) { return(this.RasterizeBoxCollider(col as BoxCollider, localToWorldMatrix)); } if ((col is SphereCollider) || (col is CapsuleCollider)) { SphereCollider collider = col as SphereCollider; CapsuleCollider collider2 = col as CapsuleCollider; float radius = (collider == null) ? collider2.radius : collider.radius; float height = (collider == null) ? (((collider2.height * 0.5f) / radius) - 1f) : 0f; Matrix4x4 matrixx = Matrix4x4.TRS((collider == null) ? collider2.center : collider.center, Quaternion.identity, (Vector3)(Vector3.one * radius)); matrixx = localToWorldMatrix * matrixx; return(this.RasterizeCapsuleCollider(radius, height, col.bounds, matrixx)); } if (col is MeshCollider) { MeshCollider collider3 = col as MeshCollider; if (collider3.sharedMesh != null) { mesh = new RasterizationMesh(collider3.sharedMesh.vertices, collider3.sharedMesh.triangles, collider3.bounds, localToWorldMatrix); } } return(mesh); }
private void GenerateTerrainChunks(Terrain terrain, Bounds bounds, float desiredChunkSize, List <RasterizationMesh> result) { TerrainData terrainData = terrain.terrainData; if (terrainData == null) { throw new ArgumentException("Terrain contains no terrain data"); } Vector3 position = terrain.GetPosition(); Vector3 center = position + ((Vector3)(terrainData.size * 0.5f)); Bounds bounds2 = new Bounds(center, terrainData.size); if (bounds2.Intersects(bounds)) { int heightmapWidth = terrainData.heightmapWidth; int heightmapHeight = terrainData.heightmapHeight; float[,] heights = terrainData.GetHeights(0, 0, heightmapWidth, heightmapHeight); Vector3 heightmapScale = terrainData.heightmapScale; heightmapScale.y = terrainData.size.y; int a = Mathf.CeilToInt(Mathf.Max((float)(desiredChunkSize / (heightmapScale.x * this.terrainSampleSize)), (float)12f)) * this.terrainSampleSize; int num5 = Mathf.CeilToInt(Mathf.Max((float)(desiredChunkSize / (heightmapScale.z * this.terrainSampleSize)), (float)12f)) * this.terrainSampleSize; for (int i = 0; i < heightmapHeight; i += num5) { for (int j = 0; j < heightmapWidth; j += a) { int width = Mathf.Min(a, heightmapWidth - j); int depth = Mathf.Min(num5, heightmapHeight - i); RasterizationMesh item = this.GenerateHeightmapChunk(heights, heightmapScale, position, j, i, width, depth, this.terrainSampleSize); result.Add(item); } } } }
public void CollectRecastMeshObjs(List <RasterizationMesh> buffer) { List <RecastMeshObj> list = ListPool <RecastMeshObj> .Claim(); RecastMeshObj.GetAllInBounds(list, this.bounds); Dictionary <Mesh, Vector3[]> dictionary = new Dictionary <Mesh, Vector3[]>(); Dictionary <Mesh, int[]> dictionary2 = new Dictionary <Mesh, int[]>(); for (int i = 0; i < list.Count; i++) { MeshFilter meshFilter = list[i].GetMeshFilter(); Renderer renderer = (!(meshFilter != null)) ? null : meshFilter.GetComponent <Renderer>(); if (meshFilter != null && renderer != null) { Mesh sharedMesh = meshFilter.sharedMesh; RasterizationMesh rasterizationMesh = new RasterizationMesh(); rasterizationMesh.matrix = renderer.localToWorldMatrix; rasterizationMesh.original = meshFilter; rasterizationMesh.area = list[i].area; if (dictionary.ContainsKey(sharedMesh)) { rasterizationMesh.vertices = dictionary[sharedMesh]; rasterizationMesh.triangles = dictionary2[sharedMesh]; } else { rasterizationMesh.vertices = sharedMesh.vertices; rasterizationMesh.triangles = sharedMesh.triangles; dictionary[sharedMesh] = rasterizationMesh.vertices; dictionary2[sharedMesh] = rasterizationMesh.triangles; } rasterizationMesh.bounds = renderer.bounds; buffer.Add(rasterizationMesh); } else { Collider collider = list[i].GetCollider(); if (collider == null) { Debug.LogError("RecastMeshObject (" + list[i].gameObject.name + ") didn't have a collider or MeshFilter+Renderer attached", list[i].gameObject); } else { RasterizationMesh rasterizationMesh2 = this.RasterizeCollider(collider); if (rasterizationMesh2 != null) { rasterizationMesh2.area = list[i].area; buffer.Add(rasterizationMesh2); } } } } this.capsuleCache.Clear(); ListPool <RecastMeshObj> .Release(list); }
void CollectTreeMeshes(Terrain terrain, List <RasterizationMesh> result) { TerrainData data = terrain.terrainData; for (int i = 0; i < data.treeInstances.Length; i++) { TreeInstance instance = data.treeInstances[i]; TreePrototype prot = data.treePrototypes[instance.prototypeIndex]; // Make sure that the tree prefab exists if (prot.prefab == null) { continue; } var collider = prot.prefab.GetComponent <Collider>(); var treePosition = terrain.transform.position + Vector3.Scale(instance.position, data.size); var scale = new Vector3(instance.widthScale, instance.heightScale, instance.widthScale); scale = Vector3.Scale(scale, prot.prefab.transform.localScale); if (collider == null) { var instanceBounds = new Bounds(terrain.transform.position + Vector3.Scale(instance.position, data.size), new Vector3(instance.widthScale, instance.heightScale, instance.widthScale)); Matrix4x4 matrix = Matrix4x4.TRS(treePosition, Quaternion.identity, scale * 0.5f); var mesh = new RasterizationMesh(BoxColliderVerts, BoxColliderTris, instanceBounds, matrix); result.Add(mesh); } else { // The prefab has a collider, use that instead // Generate a mesh from the collider RasterizationMesh mesh = RasterizeCollider(collider, Matrix4x4.TRS(treePosition, Quaternion.identity, scale)); // Make sure a valid mesh was generated if (mesh != null) { // The bounds are incorrectly based on collider.bounds. // It is incorrect because the collider is on the prefab, not on the tree instance // so we need to recalculate the bounds based on the actual vertex positions mesh.RecalculateBounds(); result.Add(mesh); } } } }
/// <summary> /// Rasterizes a collider to a mesh assuming it's vertices should be multiplied with the matrix. /// Note that the bounds of the returned RasterizationMesh is based on collider.bounds. So you might want to /// call myExtraMesh.RecalculateBounds on the returned mesh to recalculate it if the collider.bounds would /// not give the correct value. /// </summary> RasterizationMesh RasterizeCollider(Collider col, Matrix4x4 localToWorldMatrix) { RasterizationMesh result = null; if (col is BoxCollider) { result = RasterizeBoxCollider(col as BoxCollider, localToWorldMatrix); } else if (col is SphereCollider || col is CapsuleCollider) { var scollider = col as SphereCollider; var ccollider = col as CapsuleCollider; float radius = (scollider != null ? scollider.radius : ccollider.radius); float height = scollider != null ? 0 : (ccollider.height * 0.5f / radius) - 1; Quaternion rot = Quaternion.identity; // Capsule colliders can be aligned along the X, Y or Z axis if (ccollider != null) { rot = Quaternion.Euler(ccollider.direction == 2 ? 90 : 0, 0, ccollider.direction == 0 ? 90 : 0); } Matrix4x4 matrix = Matrix4x4.TRS(scollider != null ? scollider.center : ccollider.center, rot, Vector3.one * radius); matrix = localToWorldMatrix * matrix; result = RasterizeCapsuleCollider(radius, height, col.bounds, matrix); } else if (col is MeshCollider) { var collider = col as MeshCollider; if (collider.sharedMesh != null) { result = new RasterizationMesh(collider.sharedMesh.vertices, collider.sharedMesh.triangles, collider.bounds, localToWorldMatrix); } } #if ASTARDEBUG for (int i = 0; i < result.triangles.Length; i += 3) { Debug.DrawLine(result.matrix.MultiplyPoint3x4(result.vertices[result.triangles[i]]), result.matrix.MultiplyPoint3x4(result.vertices[result.triangles[i + 1]]), Color.yellow); Debug.DrawLine(result.matrix.MultiplyPoint3x4(result.vertices[result.triangles[i + 2]]), result.matrix.MultiplyPoint3x4(result.vertices[result.triangles[i + 1]]), Color.yellow); Debug.DrawLine(result.matrix.MultiplyPoint3x4(result.vertices[result.triangles[i]]), result.matrix.MultiplyPoint3x4(result.vertices[result.triangles[i + 2]]), Color.yellow); } #endif return(result); }
// Token: 0x060027D1 RID: 10193 RVA: 0x001B497C File Offset: 0x001B2B7C private RasterizationMesh GenerateHeightmapChunk(float[,] heights, Vector3 sampleSize, Vector3 offset, int x0, int z0, int width, int depth, int stride) { int num = RecastMeshGatherer.CeilDivision(width, this.terrainSampleSize) + 1; int num2 = RecastMeshGatherer.CeilDivision(depth, this.terrainSampleSize) + 1; int length = heights.GetLength(0); int length2 = heights.GetLength(1); int num3 = num * num2; Vector3[] array = ArrayPool <Vector3> .Claim(num3); for (int i = 0; i < num2; i++) { for (int j = 0; j < num; j++) { int num4 = Math.Min(x0 + j * stride, length - 1); int num5 = Math.Min(z0 + i * stride, length2 - 1); array[i * num + j] = new Vector3((float)num5 * sampleSize.x, heights[num4, num5] * sampleSize.y, (float)num4 * sampleSize.z) + offset; } } int num6 = (num - 1) * (num2 - 1) * 2 * 3; int[] array2 = ArrayPool <int> .Claim(num6); int num7 = 0; for (int k = 0; k < num2 - 1; k++) { for (int l = 0; l < num - 1; l++) { array2[num7] = k * num + l; array2[num7 + 1] = k * num + l + 1; array2[num7 + 2] = (k + 1) * num + l + 1; num7 += 3; array2[num7] = k * num + l; array2[num7 + 1] = (k + 1) * num + l + 1; array2[num7 + 2] = (k + 1) * num + l; num7 += 3; } } RasterizationMesh rasterizationMesh = new RasterizationMesh(array, array2, default(Bounds)); rasterizationMesh.numVertices = num3; rasterizationMesh.numTriangles = num6; rasterizationMesh.pool = true; rasterizationMesh.RecalculateBounds(); return(rasterizationMesh); }
public void CollectSceneMeshes(List <RasterizationMesh> meshes) { if (this.tagMask.Count > 0 || this.mask != 0) { MeshFilter[] meshFilters = UnityEngine.Object.FindObjectsOfType <MeshFilter>(); List <MeshFilter> list = RecastMeshGatherer.FilterMeshes(meshFilters, this.tagMask, this.mask); Dictionary <Mesh, Vector3[]> dictionary = new Dictionary <Mesh, Vector3[]>(); Dictionary <Mesh, int[]> dictionary2 = new Dictionary <Mesh, int[]>(); bool flag = false; for (int i = 0; i < list.Count; i++) { MeshFilter meshFilter = list[i]; Renderer component = meshFilter.GetComponent <Renderer>(); if (component.isPartOfStaticBatch) { flag = true; } else if (component.bounds.Intersects(this.bounds)) { Mesh sharedMesh = meshFilter.sharedMesh; RasterizationMesh rasterizationMesh = new RasterizationMesh(); rasterizationMesh.matrix = component.localToWorldMatrix; rasterizationMesh.original = meshFilter; if (dictionary.ContainsKey(sharedMesh)) { rasterizationMesh.vertices = dictionary[sharedMesh]; rasterizationMesh.triangles = dictionary2[sharedMesh]; } else { rasterizationMesh.vertices = sharedMesh.vertices; rasterizationMesh.triangles = sharedMesh.triangles; dictionary[sharedMesh] = rasterizationMesh.vertices; dictionary2[sharedMesh] = rasterizationMesh.triangles; } rasterizationMesh.bounds = component.bounds; meshes.Add(rasterizationMesh); } if (flag) { Debug.LogWarning("Some meshes were statically batched. These meshes can not be used for navmesh calculation due to technical constraints.\nDuring runtime scripts cannot access the data of meshes which have been statically batched.\nOne way to solve this problem is to use cached startup (Save & Load tab in the inspector) to only calculate the graph when the game is not playing."); } } } }
// Token: 0x060027CF RID: 10191 RVA: 0x001B47A4 File Offset: 0x001B29A4 private void GenerateTerrainChunks(Terrain terrain, Bounds bounds, float desiredChunkSize, List <RasterizationMesh> result) { TerrainData terrainData = terrain.terrainData; if (terrainData == null) { throw new ArgumentException("Terrain contains no terrain data"); } Vector3 position = terrain.GetPosition(); Vector3 center = position + terrainData.size * 0.5f; Bounds bounds2 = new Bounds(center, terrainData.size); if (!bounds2.Intersects(bounds)) { return; } int heightmapResolution = terrainData.heightmapResolution; int heightmapResolution2 = terrainData.heightmapResolution; float[,] heights = terrainData.GetHeights(0, 0, heightmapResolution, heightmapResolution2); Vector3 heightmapScale = terrainData.heightmapScale; heightmapScale.y = terrainData.size.y; int num = Mathf.CeilToInt(Mathf.Max(desiredChunkSize / (heightmapScale.x * (float)this.terrainSampleSize), 12f)) * this.terrainSampleSize; int num2 = Mathf.CeilToInt(Mathf.Max(desiredChunkSize / (heightmapScale.z * (float)this.terrainSampleSize), 12f)) * this.terrainSampleSize; for (int i = 0; i < heightmapResolution2; i += num2) { for (int j = 0; j < heightmapResolution; j += num) { int num3 = Mathf.Min(num, heightmapResolution - j); int num4 = Mathf.Min(num2, heightmapResolution2 - i); Vector3 min = position + new Vector3((float)i * heightmapScale.x, 0f, (float)j * heightmapScale.z); Vector3 max = position + new Vector3((float)(i + num4) * heightmapScale.x, heightmapScale.y, (float)(j + num3) * heightmapScale.z); Bounds bounds3 = default(Bounds); bounds3.SetMinMax(min, max); if (bounds3.Intersects(bounds)) { RasterizationMesh item = this.GenerateHeightmapChunk(heights, heightmapScale, position, j, i, num3, num4, this.terrainSampleSize); result.Add(item); } } } }
public void CollectColliderMeshes(List <RasterizationMesh> result) { Collider[] array = UnityEngine.Object.FindObjectsOfType <Collider>(); if (this.tagMask.Count > 0 || this.mask != 0) { foreach (Collider collider in array) { if (((this.mask >> collider.gameObject.layer & 1) != 0 || this.tagMask.Contains(collider.tag)) && collider.enabled && !collider.isTrigger && collider.bounds.Intersects(this.bounds) && collider.GetComponent <RecastMeshObj>() == null) { RasterizationMesh rasterizationMesh = this.RasterizeCollider(collider); if (rasterizationMesh != null) { result.Add(rasterizationMesh); } } } } this.capsuleCache.Clear(); }
// Token: 0x060027D3 RID: 10195 RVA: 0x001B4C8C File Offset: 0x001B2E8C public void CollectColliderMeshes(List <RasterizationMesh> result) { Collider[] array = Physics.OverlapSphere(this.bounds.center, this.bounds.size.magnitude, -1, QueryTriggerInteraction.Ignore); if (this.tagMask.Count > 0 || this.mask != 0) { foreach (Collider collider in array) { if (((this.mask >> collider.gameObject.layer & 1) != 0 || this.tagMask.Contains(collider.tag)) && collider.enabled && !collider.isTrigger && collider.bounds.Intersects(this.bounds) && collider.GetComponent <RecastMeshObj>() == null) { RasterizationMesh rasterizationMesh = this.RasterizeCollider(collider); if (rasterizationMesh != null) { result.Add(rasterizationMesh); } } } } this.capsuleCache.Clear(); }
public void CollectColliderMeshes(List <RasterizationMesh> result) { Collider[] colliderArray = UnityEngine.Object.FindObjectsOfType <Collider>(); if ((this.tagMask.Count > 0) || (this.mask != 0)) { for (int i = 0; i < colliderArray.Length; i++) { Collider col = colliderArray[i]; if (((((this.mask >> (col.gameObject.layer & 0x1f)) & 1) != 0) || this.tagMask.Contains(col.tag)) && ((col.enabled && !col.isTrigger) && (col.bounds.Intersects(this.bounds) && (col.GetComponent <RecastMeshObj>() == null)))) { RasterizationMesh item = this.RasterizeCollider(col); if (item != null) { result.Add(item); } } } } this.capsuleCache.Clear(); }
private RasterizationMesh GenerateHeightmapChunk(float[,] heights, Vector3 sampleSize, Vector3 offset, int x0, int z0, int width, int depth, int stride) { int num = CeilDivision(width, this.terrainSampleSize) + 1; int num2 = CeilDivision(depth, this.terrainSampleSize) + 1; int length = heights.GetLength(0); int num4 = heights.GetLength(1); Vector3[] vertices = new Vector3[num * num2]; for (int i = 0; i < num2; i++) { for (int k = 0; k < num; k++) { int num7 = Math.Min((int)(x0 + (k * stride)), (int)(length - 1)); int num8 = Math.Min((int)(z0 + (i * stride)), (int)(num4 - 1)); vertices[(i * num) + k] = new Vector3(num8 * sampleSize.x, heights[num7, num8] * sampleSize.y, num7 * sampleSize.z) + offset; } } int[] triangles = new int[(((num - 1) * (num2 - 1)) * 2) * 3]; int index = 0; for (int j = 0; j < (num2 - 1); j++) { for (int m = 0; m < (num - 1); m++) { triangles[index] = (j * num) + m; triangles[index + 1] = ((j * num) + m) + 1; triangles[index + 2] = (((j + 1) * num) + m) + 1; index += 3; triangles[index] = (j * num) + m; triangles[index + 1] = (((j + 1) * num) + m) + 1; triangles[index + 2] = ((j + 1) * num) + m; index += 3; } } RasterizationMesh mesh = new RasterizationMesh(vertices, triangles, new Bounds()); mesh.RecalculateBounds(); return(mesh); }
private RasterizationMesh GenerateHeightmapChunk(float[,] heights, Vector3 sampleSize, Vector3 offset, int x0, int z0, int width, int depth, int stride) { int num = RecastMeshGatherer.CeilDivision(width, this.terrainSampleSize) + 1; int num2 = RecastMeshGatherer.CeilDivision(depth, this.terrainSampleSize) + 1; int length = heights.GetLength(0); int length2 = heights.GetLength(1); Vector3[] array = new Vector3[num * num2]; for (int i = 0; i < num2; i++) { for (int j = 0; j < num; j++) { int num3 = Math.Min(x0 + j * stride, length - 1); int num4 = Math.Min(z0 + i * stride, length2 - 1); array[i * num + j] = new Vector3((float)num4 * sampleSize.x, heights[num3, num4] * sampleSize.y, (float)num3 * sampleSize.z) + offset; } } int[] array2 = new int[(num - 1) * (num2 - 1) * 2 * 3]; int num5 = 0; for (int k = 0; k < num2 - 1; k++) { for (int l = 0; l < num - 1; l++) { array2[num5] = k * num + l; array2[num5 + 1] = k * num + l + 1; array2[num5 + 2] = (k + 1) * num + l + 1; num5 += 3; array2[num5] = k * num + l; array2[num5 + 1] = (k + 1) * num + l + 1; array2[num5 + 2] = (k + 1) * num + l; num5 += 3; } } RasterizationMesh rasterizationMesh = new RasterizationMesh(array, array2, default(Bounds)); rasterizationMesh.RecalculateBounds(); return(rasterizationMesh); }
public void CollectSceneMeshes(List <RasterizationMesh> meshes) { if (tagMask.Count > 0 || mask != 0) { // This is unfortunately the fastest way to find all mesh filters.. and it is not particularly fast. var meshFilters = GameObject.FindObjectsOfType <MeshFilter>(); var filteredMeshes = FilterMeshes(meshFilters, tagMask, mask); var cachedVertices = new Dictionary <Mesh, Vector3[]>(); var cachedTris = new Dictionary <Mesh, int[]>(); bool containedStatic = false; for (int i = 0; i < filteredMeshes.Count; i++) { MeshFilter filter = filteredMeshes[i]; // Note, guaranteed to have a renderer Renderer rend = filter.GetComponent <Renderer>(); if (rend.isPartOfStaticBatch) { // Statically batched meshes cannot be used due to Unity limitations // log a warning about this containedStatic = true; } else { // Only include it if it intersects with the graph if (rend.bounds.Intersects(bounds)) { Mesh mesh = filter.sharedMesh; RasterizationMesh smesh; // Check the cache to avoid allocating // a new array unless necessary if (cachedVertices.ContainsKey(mesh)) { smesh = new RasterizationMesh(cachedVertices[mesh], cachedTris[mesh], rend.bounds); } else { smesh = new RasterizationMesh(mesh.vertices, mesh.triangles, rend.bounds); cachedVertices[mesh] = smesh.vertices; cachedTris[mesh] = smesh.triangles; } smesh.matrix = rend.localToWorldMatrix; smesh.original = filter; meshes.Add(smesh); } } if (containedStatic) { Debug.LogWarning("Some meshes were statically batched. These meshes can not be used for navmesh calculation" + " due to technical constraints.\nDuring runtime scripts cannot access the data of meshes which have been statically batched.\n" + "One way to solve this problem is to use cached startup (Save & Load tab in the inspector) to only calculate the graph when the game is not playing."); } } #if ASTARDEBUG int y = 0; foreach (RasterizationMesh smesh in meshes) { y++; Vector3[] vecs = smesh.vertices; int[] tris = smesh.triangles; for (int i = 0; i < tris.Length; i += 3) { Vector3 p1 = smesh.matrix.MultiplyPoint3x4(vecs[tris[i + 0]]); Vector3 p2 = smesh.matrix.MultiplyPoint3x4(vecs[tris[i + 1]]); Vector3 p3 = smesh.matrix.MultiplyPoint3x4(vecs[tris[i + 2]]); Debug.DrawLine(p1, p2, Color.red, 1); Debug.DrawLine(p2, p3, Color.red, 1); Debug.DrawLine(p3, p1, Color.red, 1); } } #endif } }
public MeshCollection Finalize() { #if UNITY_2020_1_OR_NEWER Mesh.MeshDataArray data = Mesh.AcquireReadOnlyMeshData(meshData); var meshes = new NativeArray <RasterizationMesh>(this.meshes.Count, Allocator.Persistent); int meshBufferOffset = vertexBuffers.Count; UnityEngine.Profiling.Profiler.BeginSample("Copying vertices"); for (int i = 0; i < data.Length; i++) { var rawMeshData = data[i]; var verts = new NativeArray <Vector3>(rawMeshData.vertexCount, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); rawMeshData.GetVertices(verts); int totalIndices = 0; for (int subMeshIndex = 0; subMeshIndex < rawMeshData.subMeshCount; subMeshIndex++) { totalIndices += rawMeshData.GetSubMesh(subMeshIndex).indexCount; } var tris = new NativeArray <int>(totalIndices, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); int offset = 0; for (int subMeshIndex = 0; subMeshIndex < rawMeshData.subMeshCount; subMeshIndex++) { var submesh = rawMeshData.GetSubMesh(subMeshIndex); rawMeshData.GetIndices(tris.GetSubArray(offset, submesh.indexCount), subMeshIndex); offset += submesh.indexCount; } vertexBuffers.Add(verts); triangleBuffers.Add(tris); } UnityEngine.Profiling.Profiler.EndSample(); for (int i = 0; i < meshes.Length; i++) { var gatheredMesh = this.meshes[i]; int bufferIndex; if (gatheredMesh.meshDataIndex >= 0) { bufferIndex = meshBufferOffset + gatheredMesh.meshDataIndex; } else { bufferIndex = -(gatheredMesh.meshDataIndex + 1); } var bounds = gatheredMesh.bounds; var slice = vertexBuffers[bufferIndex].Reinterpret <float3>(); if (bounds == new Bounds()) { UnityEngine.Profiling.Profiler.BeginSample("CalculateBounds"); // Recalculate bounding box float4x4 m = gatheredMesh.matrix; unsafe { CalculateBoundsInvoke((float3 *)slice.GetUnsafeReadOnlyPtr(), slice.Length, ref m, out bounds); } UnityEngine.Profiling.Profiler.EndSample(); } var triangles = triangleBuffers[bufferIndex]; meshes[i] = new RasterizationMesh { vertices = new UnsafeSpan <float3>(slice), triangles = new UnsafeSpan <int>(triangles.Slice(0, gatheredMesh.indicesCount != -1 ? gatheredMesh.indicesCount : triangles.Length)), area = gatheredMesh.area, bounds = bounds, matrix = gatheredMesh.matrix, solid = gatheredMesh.solid, }; } cachedMeshes.Clear(); ObjectPoolSimple <Dictionary <MeshCacheItem, int> > .Release(ref cachedMeshes); ListPool <GatheredMesh> .Release(ref this.meshes); data.Dispose(); return(new MeshCollection(vertexBuffers, triangleBuffers, meshes)); #else throw new System.NotImplementedException("The burst version of recast is only supported in Unity 2020.1 or later"); #endif }
/// <summary>Find all relevant RecastMeshObj components and create ExtraMeshes for them</summary> public void CollectRecastMeshObjs(List <RasterizationMesh> buffer) { var buffer2 = Util.ListPool <RecastMeshObj> .Claim(); // Get all recast mesh objects inside the bounds RecastMeshObj.GetAllInBounds(buffer2, bounds); var cachedVertices = new Dictionary <Mesh, Vector3[]>(); var cachedTris = new Dictionary <Mesh, int[]>(); // Create an RasterizationMesh object // for each RecastMeshObj for (int i = 0; i < buffer2.Count; i++) { MeshFilter filter = buffer2[i].GetMeshFilter(); Renderer rend = filter != null?filter.GetComponent <Renderer>() : null; if (filter != null && rend != null && filter.sharedMesh != null) { Mesh mesh = filter.sharedMesh; RasterizationMesh smesh; // Don't read the vertices and triangles from the // mesh if we have seen the same mesh previously if (cachedVertices.ContainsKey(mesh)) { smesh = new RasterizationMesh(cachedVertices[mesh], cachedTris[mesh], rend.bounds); } else { smesh = new RasterizationMesh(mesh.vertices, mesh.triangles, rend.bounds); cachedVertices[mesh] = smesh.vertices; cachedTris[mesh] = smesh.triangles; } smesh.matrix = rend.localToWorldMatrix; smesh.original = filter; smesh.area = buffer2[i].area; buffer.Add(smesh); } else { Collider coll = buffer2[i].GetCollider(); if (coll == null) { Debug.LogError("RecastMeshObject (" + buffer2[i].gameObject.name + ") didn't have a collider or MeshFilter+Renderer attached", buffer2[i].gameObject); continue; } RasterizationMesh smesh = RasterizeCollider(coll); // Make sure a valid RasterizationMesh was returned if (smesh != null) { smesh.area = buffer2[i].area; buffer.Add(smesh); } } } // Clear cache to avoid memory leak capsuleCache.Clear(); Util.ListPool <RecastMeshObj> .Release(ref buffer2); }