Example #1
0
        public TerrainDrawStreaming(int maximumLength, int meshSize, ComputeShader transformShader)
        {
            current = this;
            if (meshSize % 2 != 0)
            {
                Debug.LogError("Terrain panel's size should be even number!");
                meshSize++;
            }
            this.meshSize = meshSize;
            //Initialize Mesh and triangles
            int vertexCount = meshSize + 1;

            vertSize      = vertexCount;
            heightMapSize = vertSize * vertSize;
            NativeArray <float2> terrainVertexArray = new NativeArray <float2>(vertexCount * vertexCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
            float2 *arrPtr = terrainVertexArray.Ptr();

            for (int x = 0; x < vertexCount; ++x)
            {
                for (int y = 0; y < vertexCount; ++y)
                {
                    arrPtr[y * vertexCount + x] = new float2(x, y) / meshSize - new float2(0.5f, 0.5f);
                }
            }
            verticesBuffer = new ComputeBuffer(terrainVertexArray.Length, sizeof(float2));
            verticesBuffer.SetData(terrainVertexArray);
            heightMapBuffer = new ComputeBuffer(maximumLength * (vertexCount * vertexCount), sizeof(float));
            NativeArray <int> triangles = new NativeArray <int>(6 * meshSize * meshSize, Allocator.Temp, NativeArrayOptions.UninitializedMemory);

            int *trianglePtr = triangles.Ptr();

            for (int x = 0, count = 0; x < meshSize; ++x)
            {
                for (int y = 0; y < meshSize; ++y)
                {
                    int4 indices = new int4(vertexCount * y + x, vertexCount * (y + 1) + x, vertexCount * y + (x + 1), vertexCount * (y + 1) + (x + 1));
                    trianglePtr[count]     = indices.x;
                    trianglePtr[count + 1] = indices.y;
                    trianglePtr[count + 2] = indices.z;
                    trianglePtr[count + 3] = indices.y;
                    trianglePtr[count + 4] = indices.w;
                    trianglePtr[count + 5] = indices.z;
                    count += 6;
                }
            }
            triangleBuffer = new ComputeBuffer(triangles.Length, sizeof(int));
            triangleBuffer.SetData(triangles);
            triangles.Dispose();
            terrainVertexArray.Dispose();
            removebuffer = new ComputeBuffer(100, sizeof(int2));
            //Initialize indirect
            clusterBuffer        = new ComputeBuffer(maximumLength, sizeof(TerrainPanel));
            referenceBuffer      = new NativeList <ulong>(maximumLength, Allocator.Persistent);
            this.transformShader = transformShader;
            resultBuffer         = new ComputeBuffer(maximumLength, sizeof(int));
            instanceCountBuffer  = new ComputeBuffer(5, sizeof(int), ComputeBufferType.IndirectArguments);
            NativeArray <int> indirect = new NativeArray <int>(5, Allocator.Temp, NativeArrayOptions.ClearMemory);

            indirect[0] = triangleBuffer.count;
            instanceCountBuffer.SetData(indirect);
            indirect.Dispose();
            notUsedHeightmapIndices = new NativeList <int>(maximumLength, Allocator.Persistent);
            for (int i = 0; i < maximumLength; ++i)
            {
                notUsedHeightmapIndices.Add(i);
            }
        }
Example #2
0
        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);
            transformList.Dispose();
        }
Example #3
0
        public void GenerateAsync(bool listCommand = true)
        {
            clusterBuffer = new NativeArray <CullBox>(property.clusterCount, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
            pointsBuffer  = new NativeArray <Point>(property.clusterCount * PipelineBaseBuffer.CLUSTERCLIPCOUNT, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
            indicesBuffer = new NativeArray <int>(property.clusterCount, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
            NativeList <ulong> pointerContainer = SceneController.pointerContainer;

            pointerContainer.AddCapacityTo(pointerContainer.Length + indicesBuffer.Length);
            CullBox *      clusterData  = clusterBuffer.Ptr();
            Point *        verticesData = pointsBuffer.Ptr();
            const string   infosPath    = "Assets/BinaryData/MapInfos/";
            const string   pointsPath   = "Assets/BinaryData/MapPoints/";
            MStringBuilder sb           = new MStringBuilder(pointsPath.Length + property.name.Length + ".mpipe".Length);

            allStrings[0] = infosPath;
            allStrings[1] = property.name;
            allStrings[2] = ".mpipe";
            sb.Combine(allStrings);
            // FileStream fileStream = new FileStream(sb.str, FileMode.Open, FileAccess.Read);
            using (FileStream reader = new FileStream(sb.str, FileMode.Open, FileAccess.Read))
            {
                int    length = (int)reader.Length;
                byte[] bytes  = GetByteArray(length);
                reader.Read(bytes, 0, length);
                fixed(byte *b = bytes)
                {
                    UnsafeUtility.MemCpy(clusterData, b, length);
                }
            }
            allStrings[0] = pointsPath;
            sb.Combine(allStrings);
            using (FileStream reader = new FileStream(sb.str, FileMode.Open, FileAccess.Read))
            {
                int    length = (int)reader.Length;
                byte[] bytes  = GetByteArray(length);
                reader.Read(bytes, 0, length);
                fixed(byte *b = bytes)
                {
                    UnsafeUtility.MemCpy(verticesData, b, length);
                }
            }
            int *indicesPtr = indicesBuffer.Ptr();
            LoadingCommandQueue commandQueue = SceneController.commandQueue;

            for (int i = 0; i < indicesBuffer.Length; ++i)
            {
                indicesPtr[i] = pointerContainer.Length;
                pointerContainer.Add((ulong)(indicesPtr + i));
            }
            LoadTextures();
            propertiesPool = SceneController.commonData.GetPropertyIndex(property.properties.Length);
            uint *poolPtr = propertiesPool.Ptr();

            lightmapIndices = new NativeArray <int>(allLightmapDatas.Count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
            int *ptr = lightmapIndices.Ptr();

            for (int i = 0; i < lightmapIndices.Length; ++i)
            {
                ptr[i] = allLightmapDatas[i].index;
            }
            if (listCommand)
            {
                lock (commandQueue)
                {
                    commandQueue.Queue(GenerateRun());
                }
            }
        }
Example #4
0
 public static void ReleaseRTAfterFrame(int targetRT)
 {
     waitReleaseRT.Add(targetRT);
 }
        public void Awake(MonoBehaviour behavior)
        {
            current          = this;
            addList          = new NativeList <ulong>(10, Allocator.Persistent);
            this.behavior    = behavior;
            baseBuffer       = new PipelineBaseBuffer();
            clusterResources = Resources.Load <ClusterMatResources>("MapMat/" + mapResources);
            int clusterCount = 0;

            allScenes = new List <SceneStreaming>(clusterResources.clusterProperties.Count);
            foreach (var i in clusterResources.clusterProperties)
            {
                clusterCount += i.clusterCount;
                allScenes.Add(new SceneStreaming(i));
            }
            PipelineFunctions.InitBaseBuffer(baseBuffer, clusterResources, mapResources, clusterCount);
            pointerContainer = new NativeList <ulong>(clusterCount, Allocator.Persistent);
            commandQueue     = new LoadingCommandQueue();
            RenderTextureDescriptor desc = new RenderTextureDescriptor
            {
                autoGenerateMips   = false,
                bindMS             = false,
                colorFormat        = RenderTextureFormat.ARGB32,
                depthBufferBits    = 0,
                dimension          = TextureDimension.Tex2DArray,
                enableRandomWrite  = false,
                height             = resolution,
                width              = resolution,
                memoryless         = RenderTextureMemoryless.None,
                msaaSamples        = 1,
                vrUsage            = VRTextureUsage.None,
                volumeDepth        = texArrayCapacity,
                shadowSamplingMode = ShadowSamplingMode.None,
                sRGB      = false,
                useMipMap = false
            };

            commonData = new SceneCommonData
            {
                texDict              = new Dictionary <string, SceneCommonData.TextureIdentifier>(),
                avaiableProperties   = new NativeList <int>(propertyCapacity, Allocator.Persistent),
                avaiableTexs         = new NativeList <int>(texArrayCapacity, Allocator.Persistent),
                texCopyBuffer        = new ComputeBuffer(resolution * resolution, sizeof(int)),
                propertyBuffer       = new ComputeBuffer(propertyCapacity, sizeof(PropertyValue)),
                copyTextureMat       = new Material(RenderPipeline.current.resources.copyShader),
                texArray             = new RenderTexture(desc),
                clusterMaterial      = new Material(RenderPipeline.current.resources.clusterRenderShader),
                terrainMaterial      = new Material(RenderPipeline.current.resources.terrainShader),
                terrainDrawStreaming = new TerrainDrawStreaming(100, 16, RenderPipeline.current.resources.terrainCompute)
            };
            commonData.clusterMaterial.SetBuffer(ShaderIDs._PropertiesBuffer, commonData.propertyBuffer);
            commonData.clusterMaterial.SetTexture(ShaderIDs._MainTex, commonData.texArray);
            commonData.copyTextureMat.SetVector("_TextureSize", new Vector4(resolution, resolution));
            commonData.copyTextureMat.SetBuffer("_TextureBuffer", commonData.texCopyBuffer);
            for (int i = 0; i < propertyCapacity; ++i)
            {
                commonData.avaiableProperties.Add(i);
            }
            for (int i = 0; i < texArrayCapacity; ++i)
            {
                commonData.avaiableTexs.Add(i);
            }
            testNodeArray = new NativeList <ulong>(terrainTransforms.Length, Allocator.Persistent);
            foreach (var i in terrainTransforms)
            {
                TerrainQuadTree.QuadTreeNode *testNode = (TerrainQuadTree.QuadTreeNode *)UnsafeUtility.Malloc(sizeof(TerrainQuadTree.QuadTreeNode), 16, Allocator.Persistent);
                testNode->listPosition = -1;
                ref TerrainPanel panel = ref testNode->panel;
                if (i.localScale.x > 1.1f)
                {
                    panel.edgeFlag = 0;
                }
                else
                {
                    panel.edgeFlag = 15;
                }
                panel.extent         = i.localScale * 0.5f;
                panel.position       = i.position;
                panel.textureIndex   = 0;
                panel.heightMapIndex = 0;
                testNodeArray.Add((ulong)testNode);
            }