Ejemplo n.º 1
0
 public VirtualTextureLoader(string pathName, ComputeShader terrainEditShader, int terrainMaskCount, long resolution, bool is16Bit, MTerrainLoadingThread loadingThread)
 {
     this.loadingThread = loadingThread;
     if (is16Bit)
     {
         readPass  = 4;
         writePass = 5;
         bitLength = 2;
     }
     else
     {
         bitLength = 1;
         readPass  = 2;
         writePass = 3;
     }
     this.resolution        = resolution;
     size                   = resolution * resolution * bitLength;
     this.terrainMaskCount  = terrainMaskCount;
     fileReadBuffer         = new byte[size];
     maskLoader             = new FileStream(pathName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
     loadingCommandQueue    = new NativeQueue <MaskBuffer>(100, Allocator.Persistent);
     this.terrainEditShader = terrainEditShader;
     readWriteBuffer        = new ComputeBuffer((int)(size / sizeof(uint)), sizeof(uint));
     loadingThreadExecutor  = () =>
     {
         MaskBuffer mb;
         while (loadingCommandQueue.TryDequeue(out mb))
         {
             maskLoader.Position = mb.offset;
             maskLoader.Read(fileReadBuffer, 0, (int)size);
             UnsafeUtility.MemCpy(mb.bytesData, fileReadBuffer.Ptr(), size);
             *mb.isFinished = true;
         }
     };
 }
 public VirtualTextureLoader(int initialMipCount, int mipLevel, string path, object lockerObj)
 {
     enabled = true;
     this.initialMipCount = initialMipCount;
     handlerQueue         = new NativeQueue <LoadingHandler>(100, Allocator.Persistent);
     this.lockerObj       = lockerObj;
     this.mipLevel        = mipLevel;
     resetEvent           = new AutoResetEvent(true);
     bufferBytes          = new byte[CHUNK_SIZE];
     streamPositionOffset = GetStreamingPositionOffset(initialMipCount, mipLevel);
     streamer             = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, (int)CHUNK_SIZE);
     loadingThread        = new Thread(() =>
     {
         while (enabled)
         {
             while (true)
             {
                 LoadingHandler handler;
                 lock (lockerObj)
                 {
                     if (!handlerQueue.TryDequeue(out handler))
                     {
                         break;
                     }
                 }
                 try
                 {
                     streamer.Position = CHUNK_SIZE * ((long)(0.1 + pow(2.0, handler.mipLevel)) * handler.position.y + handler.position.x + streamPositionOffset[handler.mipLevel - initialMipCount]);
                     streamer.Read(bufferBytes, 0, (int)CHUNK_SIZE);
                     UnsafeUtility.MemCpy(handler.allBytes, bufferBytes.Ptr(), CHUNK_SIZE);
                 }
                 finally
                 {
                     *handler.isComplete = true;
                 }
             }
             resetEvent.WaitOne();
         }
     });
     loadingThread.Start();
 }
Ejemplo n.º 3
0
        private IEnumerator Loader()
        {
            while (enabled)
            {
                LoadCommand cmd;
                if (allLoadingCommand.TryDequeue(out cmd))
                {
                    switch (cmd.ope)
                    {
                    case LoadCommand.Operator.Combine:
                        childrenList.Clear();
                        if (allGPURPScene[cmd.leftDownSon])
                        {
                            childrenList.Add(allGPURPScene[cmd.leftDownSon]);
                        }
                        if (allGPURPScene[cmd.leftUpSon])
                        {
                            childrenList.Add(allGPURPScene[cmd.leftUpSon]);
                        }
                        if (allGPURPScene[cmd.rightDownSon])
                        {
                            childrenList.Add(allGPURPScene[cmd.rightDownSon]);
                        }
                        if (allGPURPScene[cmd.rightUpSon])
                        {
                            childrenList.Add(allGPURPScene[cmd.rightUpSon]);
                        }
                        yield return(SceneStreaming.Combine(allGPURPScene[cmd.parent], childrenList));

                        break;

                    case LoadCommand.Operator.Disable:
                        yield return(allGPURPScene[cmd.parent].Delete());

                        break;

                    case LoadCommand.Operator.Enable:
                        yield return(allGPURPScene[cmd.parent].Generate());

                        break;

                    case LoadCommand.Operator.Separate:
                        childrenList.Clear();
                        if (allGPURPScene[cmd.leftDownSon])
                        {
                            childrenList.Add(allGPURPScene[cmd.leftDownSon]);
                        }
                        if (allGPURPScene[cmd.leftUpSon])
                        {
                            childrenList.Add(allGPURPScene[cmd.leftUpSon]);
                        }
                        if (allGPURPScene[cmd.rightDownSon])
                        {
                            childrenList.Add(allGPURPScene[cmd.rightDownSon]);
                        }
                        if (allGPURPScene[cmd.rightUpSon])
                        {
                            childrenList.Add(allGPURPScene[cmd.rightUpSon]);
                        }
                        yield return(SceneStreaming.Separate(allGPURPScene[cmd.parent], childrenList));

                        break;
                    }
                }
                else
                {
                    yield return(null);
                }
            }
        }
Ejemplo n.º 4
0
        void OnFinishRead(AsyncGPUReadbackRequest request)
        {
            bool useConnection = false;

            commandQueue.TryDequeue(out useConnection);
            float    depth    = request.GetData <float>().Element(0);
            float4x4 invvp    = (GL.GetGPUProjectionMatrix(cam.projectionMatrix, false) * cam.worldToCameraMatrix).inverse;
            float4   worldPos = mul(invvp, float4(uv * 2 - 1, depth, 1));

            worldPos.xyz /= worldPos.w;
            MTerrain terrain = MTerrain.current;

            if (!terrain)
            {
                return;
            }
            NativeList <ulong> allMaskTree = new NativeList <ulong>(5, Allocator.Temp);

            value = Mathf.Clamp(value, 0, terrain.terrainData.allMaterials.Length - 1);
            terrain.treeRoot->GetMaterialMaskRoot(worldPos.xz, paintRange, ref allMaskTree);
            terrainEditShader.SetInt(ShaderIDs._Count, MTerrain.MASK_RESOLUTION);
            if (!useConnection)
            {
                //TODO
                terrainEditShader.SetVector("_Circle0", float4(worldPos.xz, paintRange, 1));
                terrainEditShader.SetVector("_Circle1", float4(worldPos.xz, paintRange, 1));
                terrainEditShader.SetMatrix("_QuadMatrix", float4x4(0));
            }
            else
            {
                terrain.treeRoot->GetMaterialMaskRoot(lastFrameWorldPos.xz, paintRange, ref allMaskTree);
                float2 moveDir = lastFrameWorldPos.xz - worldPos.xz;
                float  len     = length(moveDir);
                moveDir /= len;
                float    dotMove      = dot(moveDir, moveDir);
                float2   verticleDir  = float2(-moveDir.y / dotMove, moveDir.x / dotMove);
                float3x3 localToWorld = float3x3(float3(moveDir * len, 0), float3(verticleDir * paintRange * 2, 0), float3((lastFrameWorldPos.xz + worldPos.xz) * 0.5f, 1));
                float3x3 worldToLocal = inverse(localToWorld);
                terrainEditShader.SetVector("_Circle0", float4(worldPos.xz, paintRange, 1));
                terrainEditShader.SetVector("_Circle1", float4(lastFrameWorldPos.xz, paintRange, 1));
                terrainEditShader.SetMatrix("_QuadMatrix", float4x4(float4(worldToLocal.c0, 0), float4(worldToLocal.c1, 0), float4(worldToLocal.c2, 0), 0));
            }
            const int disp = MTerrain.MASK_RESOLUTION / 8;

            foreach (var i in allMaskTree)
            {
                var treeNodePtr = (TerrainQuadTree *)i;
                if (treeNodePtr == null)
                {
                    continue;
                }
                int2 maskPos  = treeNodePtr->rootPos + (int2)treeNodePtr->maskScaleOffset.yz;
                int  texIndex = terrain.maskVT.GetChunkIndex(maskPos);
                if (texIndex < 0)
                {
                    continue;
                }
                terrainEditShader.SetVector("_SrcDestCorner", (float4)treeNodePtr->BoundedWorldPos);
                terrainEditShader.SetInt(ShaderIDs._OffsetIndex, texIndex);
                PaintMask(terrain, treeNodePtr, texIndex, disp);
            }
            if (!useConnection)
            {
                terrain.treeRoot->UpdateChunks(double3(worldPos.xz, paintRange));
            }
            else
            {
                terrain.treeRoot->UpdateChunks(double3(0.5f * (worldPos.xz + lastFrameWorldPos.xz), 0.5f * distance(worldPos.xz, lastFrameWorldPos.xz) + paintRange));
            }
            lastFrameWorldPos = worldPos.xyz;
        }