/// <summary> /// Removes duplicate vertices from the array and updates the triangle array. /// Returns: The new array of vertices /// </summary> public static Int3[] RemoveDuplicateVertices(Int3[] vertices, int[] triangles) { // Get a dictionary from an object pool to avoid allocating a new one var firstVerts = ObjectPoolSimple <Dictionary <Int3, int> > .Claim(); firstVerts.Clear(); // Remove duplicate vertices var compressedPointers = new int[vertices.Length]; int count = 0; for (int i = 0; i < vertices.Length; i++) { if (!firstVerts.ContainsKey(vertices[i])) { firstVerts.Add(vertices[i], count); compressedPointers[i] = count; vertices[count] = vertices[i]; count++; } else { // There are some cases, rare but still there, that vertices are identical compressedPointers[i] = firstVerts[vertices[i]]; } } firstVerts.Clear(); ObjectPoolSimple <Dictionary <Int3, int> > .Release(ref firstVerts); for (int i = 0; i < triangles.Length; i++) { triangles[i] = compressedPointers[triangles[i]]; } var compressed = new Int3[count]; for (int i = 0; i < count; i++) { compressed[i] = vertices[i]; } return(compressed); }
public void LateStart() { print("Starting Belt System"); itemPool = new ObjectPoolSimple <BeltItem>(maxItemCount, maxItemCount); itemPool.SetUp(); entityPoolEcs = GetComponent <ObjectPoolECS>(); SetupBeltSystem(); //StartCoroutine(CreateGfxsSlowly()); StartBeltSystemLoops(); allCreators = new List <MagicItemCreator>(FindObjectsOfType <MagicItemCreator>()); allDestroyers = new List <MagicItemDestroyer>(FindObjectsOfType <MagicItemDestroyer>()); FindObjectOfType <AutoRotate>().speed *= -1f; }
public RecastMeshGathererBurst(Bounds bounds, int terrainSampleSize, LayerMask mask, List <string> tagMask, float colliderRasterizeDetail) { // Clamp to at least 1 since that's the resolution of the heightmap terrainSampleSize = Math.Max(terrainSampleSize, 1); this.bounds = bounds; this.terrainSampleSize = terrainSampleSize; this.mask = mask; this.tagMask = tagMask ?? new List <string>(); this.colliderRasterizeDetail = colliderRasterizeDetail; meshes = ListPool <GatheredMesh> .Claim(); vertexBuffers = ListPool <NativeArray <Vector3> > .Claim(); triangleBuffers = ListPool <NativeArray <int> > .Claim(); cachedMeshes = ObjectPoolSimple <Dictionary <MeshCacheItem, int> > .Claim(); meshData = ListPool <Mesh> .Claim(); }
// Token: 0x0600281E RID: 10270 RVA: 0x001B9E94 File Offset: 0x001B8094 public static Int3[] RemoveDuplicateVertices(Int3[] vertices, int[] triangles) { Dictionary <Int3, int> dictionary = ObjectPoolSimple <Dictionary <Int3, int> > .Claim(); dictionary.Clear(); int[] array = new int[vertices.Length]; int num = 0; for (int i = 0; i < vertices.Length; i++) { if (!dictionary.ContainsKey(vertices[i])) { dictionary.Add(vertices[i], num); array[i] = num; vertices[num] = vertices[i]; num++; } else { array[i] = dictionary[vertices[i]]; } } dictionary.Clear(); ObjectPoolSimple <Dictionary <Int3, int> > .Release(ref dictionary); for (int j = 0; j < triangles.Length; j++) { triangles[j] = array[triangles[j]]; } Int3[] array2 = new Int3[num]; for (int k = 0; k < num; k++) { array2[k] = vertices[k]; } return(array2); }
void SerializeUnityNavMesh(NavMeshTriangulation unityNavMesh, ref RecastGraph recast) { if (active == null || active.data == null) { return; } var vertMap = ObjectPoolSimple <Dictionary <int, int> > .Claim(); var totalVoxelWidth = (int)(recast.forcedBoundsSize.x / recast.cellSize + 0.5f); var totalVoxelDepth = (int)(recast.forcedBoundsSize.z / recast.cellSize + 0.5f); var tileSizeX = recast.editorTileSize; var tileSizeZ = recast.editorTileSize; var tileXCount = (totalVoxelWidth + tileSizeX - 1) / tileSizeX; var tileZCount = (totalVoxelDepth + tileSizeZ - 1) / tileSizeZ; var tileWorldSize = recast.TileWorldSizeX; var bucket = ArrayPool <List <int> > .Claim((tileXCount + 1) *(tileZCount + 1)); for (int i = 0; i < unityNavMesh.vertices.Length; i++) { var v = unityNavMesh.vertices[i]; var tileIndex = vertexOnTile( v, recast.forcedBoundsCenter, recast.forcedBoundsSize, tileWorldSize, tileXCount, tileZCount); tileIndex = 0; if (bucket[tileIndex] == null) { bucket[tileIndex] = ListPool <int> .Claim(); } bucket[tileIndex].Add(i); } foreach (var b in bucket) { if (b == null) { continue; } for (int i = 0; i < b.Count; i++) { for (int j = 0; j < i; j++) { if (b[i] >= unityNavMesh.vertices.Length || b[j] >= unityNavMesh.vertices.Length) { continue; } if (Vector3.Distance(unityNavMesh.vertices[b[i]], unityNavMesh.vertices[b[j]]) < 1e-3) { vertMap[b[i]] = b[j]; break; } } } } ArrayPool <List <int> > .Release(ref bucket, true); // only one tile recast.transform = recast.CalculateTransform(); recast.tileXCount = 1; recast.tileZCount = 1; recast.tileSizeX = totalVoxelWidth + 1; recast.tileSizeZ = totalVoxelDepth + 1; recast.ResetTiles(recast.tileXCount * recast.tileZCount); TriangleMeshNode.SetNavmeshHolder((int)recast.graphIndex, recast); var graphUpdateLock = active.PausePathfinding(); for (int z = 0; z < recast.tileZCount; z++) { for (int x = 0; x < recast.tileXCount; x++) { var tileOffset = recast.forcedBoundsCenter - recast.forcedBoundsSize * 0.5f + new Vector3( x * tileWorldSize, 0, z * tileWorldSize ); var trisClaim = ArrayPool <int> .Claim(unityNavMesh.indices.Length); var tris = Memory.ShrinkArray(trisClaim, unityNavMesh.indices.Length); ArrayPool <int> .Release(ref trisClaim, true); for (int i = 0; i < tris.Length; i++) { var tri = unityNavMesh.indices[i]; if (vertMap.ContainsKey(tri)) { tri = vertMap[tri]; } tris[i] = tri; } var vertsClaim = ArrayPool <Int3> .Claim(unityNavMesh.vertices.Length); var verts = Memory.ShrinkArray(vertsClaim, unityNavMesh.vertices.Length); ArrayPool <Int3> .Release(ref vertsClaim, true); for (int i = 0; i < verts.Length; i++) { var vertInWorld = unityNavMesh.vertices[i]; var vertInTile = vertInWorld - tileOffset; verts[i] = new Int3(vertInTile); } recast.ReplaceTile(x, z, 1, 1, verts, tris); } } graphUpdateLock.Release(); ObjectPoolSimple <Dictionary <int, int> > .Release(ref vertMap); }
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 }
public BeltItemSlotUpdateProcessor(ObjectPoolSimple <BeltItem> _beltItemPool, List <BeltPreProcessor.BeltGroup> _beltGroups) { beltItemPool = _beltItemPool; beltGroups = _beltGroups; }