Esempio n. 1
0
        public void ClampTurnsPositiveNumberToOne()
        {
            float number = 1;
            var   want   = 1f;

            float got = GridMath.Clamp(number, 0, 1);

            Assert.Equal(want, got);
        }
Esempio n. 2
0
        public void ClampTurnsNegativeNumberToZero()
        {
            float number = -1;
            var   want   = 0f;

            float got = GridMath.Clamp(number, 0, 1);

            Assert.Equal(want, got);
        }
Esempio n. 3
0
    void UpdateChunks()
    {
        // Get focal point.
        Vector3 targetPosition = Target.transform.position;
        int3    focalChunk     = GridMath.WorldToGrid(targetPosition, BlockSize);

        DebugDrawChunk(GridMath.Clamp(targetPosition, BlockSize), Color.cyan);

        //TODO: fix extents being treated differently (-extents is in bounds. +extents is not) and remove the +0.5 in chunk to world. Figure out a more elegant approach? maybe

        Profiler.BeginSample("LevelGenerator - Queue Create Chunks");

        int3 loadSize = LoadExtents * 2;

        loadSize = new int3(Collapse.x ? 1 :loadSize.x, Collapse.y ? 1 :loadSize.y, Collapse.z ? 1 :loadSize.z);
        float volume       = loadSize.x * loadSize.y * loadSize.z;
        float blockExtents = BlockSize / 2f;

        // Create new chunks
        for (int i = 0; i < volume; i++)
        {
            //still in chunk space but moved from 1d to 3d
            int3 positiveChunkPosition = GridMath.IndexToPosition(i, loadSize.x,
                                                                  loadSize.y);

            //subtract extents to center position on focal chunk (otherwise it starts at focalChunk and extends into positive only.
            int3 centeredPosition = positiveChunkPosition - new int3(Collapse.x?0:LoadExtents.x,
                                                                     Collapse.y?0:LoadExtents.y, Collapse.z?0:LoadExtents.z);

            int3 chunkPosition = focalChunk + centeredPosition;

            //Convert to world position and add extents so the blocks corner is at the position of the chunk (chunks origin is in corner, we want it in center)
            float3 chunkWorldPosition = GridMath.GridToWorld(chunkPosition, BlockSize) +
                                        new float3(Collapse.x?0:blockExtents, Collapse.y?0:blockExtents, Collapse.z?0:blockExtents);


            //Dont want to generate a block outside of the cameras view
            if (!BlockInViewFrustum(chunkWorldPosition))
            {
                continue;
            }

            uint positionHash = math.hash(chunkPosition);
            bool chunkExists  = _validChunks.ContainsKey(positionHash);

            //If we are unloading a chunk in a valid cell we need to cancel it before its too late!
            if (_unloadingChunks.Contains(positionHash))
            {
                _unloadingChunks.Remove(positionHash);
            }

            //Additions
            if (chunkExists)
            {
                //Draw existing chunk bounds
                DebugDrawChunk(chunkWorldPosition, new Color(1, 1, 1, 0.25f));
            }
            else if (_loadingChunks.Contains(positionHash))
            {
                DebugDrawChunk(chunkWorldPosition, Color.green);     //Draw green if busy loading
            }
            else
            {
                //Load a new chunk
                _loadingChunks.Add(positionHash);
                OnChunkLoadBegin(positionHash, chunkPosition, BlockSize, () =>
                {
                    _validChunks.Add(positionHash, chunkPosition);
                    _loadingChunks.Remove(positionHash);
                });
            }
        }

        Profiler.EndSample();
        Profiler.BeginSample("LevelGenerator - Queue Remove Chunks");

        //Remove out of bounds chunks. Need to iterate over all (cant check just around valid area) to ensure they are removed even if we teleport
        if (_validChunks.Count > volume)
        {
            List <Tuple <uint, int3> > toRemove = new List <Tuple <uint, int3> >();
            foreach (var chunkKVP in _validChunks)
            {
                int3 pos = chunkKVP.Value;

                bool alreadyUnloading = _unloadingChunks.Contains(chunkKVP.Key);

                float3 worldPos = GridMath.GridToWorld(pos, BlockSize) + new float3(blockExtents);
                //Dont want to keep a block outside of the bounds or the cameras view
                if (!GridMath.BlockInBounds(pos, focalChunk, LoadExtents) || !BlockInViewFrustum(worldPos))
                {
                    //Offset position so its centered
                    DebugDrawChunk(worldPos, Color.red);
                    if (!alreadyUnloading)
                    {
                        toRemove.Add(new Tuple <uint, int3>(chunkKVP.Key, chunkKVP.Value));
                    }
                }
            }

            foreach (Tuple <uint, int3> data in toRemove)
            {
                uint hash          = data.Item1;
                int3 chunkPosition = data.Item2;
                _unloadingChunks.Add(hash);
                OnChunkUnloadBegin(hash, chunkPosition, BlockSize, () =>
                {
                    _validChunks.Remove(hash);     //only mark invalid after removal as removal is atomic and we want to still treat the chunk as active before its unloaded. //TODO: this true?
                    _unloadingChunks.Remove(hash);
                });
            }
        }
        Profiler.EndSample();
    }