public void AddQuadTrees(NativeList <ulong> addList, NativeArray <float> heightMap) { TerrainQuadTree.QuadTreeNode **tree = (TerrainQuadTree.QuadTreeNode * *)addList.unsafePtr; int length = addList.Length; NativeArray <TerrainPanel> panel = new NativeArray <TerrainPanel>(length, Allocator.Temp, NativeArrayOptions.UninitializedMemory); TerrainPanel *panelPtr = panel.Ptr(); for (int i = 0; i < length; ++i) { tree[i]->listPosition = referenceBuffer.Length + i; int heightIndex = notUsedHeightmapIndices[notUsedHeightmapIndices.Length - 1]; tree[i]->panel.heightMapIndex = heightIndex; notUsedHeightmapIndices.RemoveLast(); heightMapBuffer.SetData(heightMap, 0, heightIndex * (meshSize + 1) * (meshSize + 1), heightMap.Length); panelPtr[i] = tree[i]->panel; } clusterBuffer.SetData(panel, 0, referenceBuffer.Length, length); panel.Dispose(); referenceBuffer.AddRange(addList); }
public void RemoveQuadTrees(NativeList <ulong> removeList) { void ErasePoint(TerrainQuadTree.QuadTreeNode *node) { node->listPosition = -1; notUsedHeightmapIndices.Add(node->panel.heightMapIndex); } int length = removeList.Length; TerrainQuadTree.QuadTreeNode **tree = (TerrainQuadTree.QuadTreeNode * *)removeList.unsafePtr; int targetLength = referenceBuffer.Length - length; int len = 0; if (targetLength <= 0) { for (int i = 0; i < length; ++i) { ErasePoint(tree[i]); } referenceBuffer.Clear(); return; } for (int i = 0; i < length; ++i) { TerrainQuadTree.QuadTreeNode *currentNode = tree[i]; if (currentNode->listPosition >= targetLength) { referenceBuffer[currentNode->listPosition] = 0; ErasePoint(currentNode); } } NativeArray <int2> transformList = new NativeArray <int2>(length, Allocator.Temp, NativeArrayOptions.UninitializedMemory); int2 *transformPtr = transformList.Ptr(); len = 0; int currentIndex = referenceBuffer.Length - 1; for (int i = 0; i < length; ++i) { TerrainQuadTree.QuadTreeNode *treeNode = tree[i]; if (treeNode->listPosition < 0) { continue; } while (referenceBuffer[currentIndex] == 0) { currentIndex--; if (currentIndex < 0) { goto FINALIZE; } } TerrainQuadTree.QuadTreeNode *lastNode = (TerrainQuadTree.QuadTreeNode *)referenceBuffer[currentIndex]; currentIndex--; transformPtr[len] = new int2(treeNode->listPosition, lastNode->listPosition); len++; lastNode->listPosition = treeNode->listPosition; referenceBuffer[lastNode->listPosition] = (ulong)lastNode; ErasePoint(treeNode); } FINALIZE: referenceBuffer.RemoveLast(length); if (len <= 0) { return; } if (len > removebuffer.count) { removebuffer.Dispose(); removebuffer = new ComputeBuffer(len, sizeof(int2)); } removebuffer.SetData(transformList, 0, 0, len); transformShader.SetBuffer(0, ShaderIDs._IndexBuffer, removebuffer); transformShader.SetBuffer(0, ShaderIDs.clusterBuffer, clusterBuffer); ComputeShaderUtility.Dispatch(transformShader, 0, len, 64); transformList.Dispose(); }