public void CullMeshes(ref ChunkCoordinate current, ref BoundingFrustum frustum)
        {
            BoundingBox box;
            if (!current.Equals(ref _previous))
            {
                _solidMeshes.Sort((x, y) => x.Position.LengthSquared().CompareTo(y.Position.LengthSquared()));
                _transparentMeshes.Sort((x, y) => -x.Position.LengthSquared().CompareTo(y.Position.LengthSquared()));
            }

            for (int i = 0; i < _solidMeshes.Count; i++)
            {
                _solidMeshes[i].GetBoundingBox(out box);
                if (frustum.Contains(box) != ContainmentType.Disjoint)
                {
                    _solidMeshRenderQueue.Enqueue(_solidMeshes[i]);
                }
            }

            for (int i = 0; i < _transparentMeshes.Count; i++)
            {
               _transparentMeshes[i].GetBoundingBox(out box);
               if (frustum.Contains(box) != ContainmentType.Disjoint)
               {
                   _transparentMeshRenderQueue.Enqueue(_transparentMeshes[i]);
               }
            }
        }
Esempio n. 2
0
        public int CompareDistance(ref ChunkCoordinate other, ref ChunkCoordinate origin)
        {
            int dist = DistanceSquared(ref origin);
            int otherdist = other.DistanceSquared(ref origin);

            return dist.CompareTo(otherdist);
        }
Esempio n. 3
0
        public bool Contains(ref ChunkCoordinate coords, out Chunk chunk)
        {
            int x = coords.X & _dimMask;
            int z = coords.Z & _dimMask;

            chunk = Chunks[x, z];
            return (chunk != null) ? chunk.Coords.Equals(ref coords) : false;
        }
Esempio n. 4
0
 public void Add(int x, int z, out ChunkCoordinate coords)
 {
     x = X + x;
     z = Z + z;
     if (Math.Abs(x) > WrapDistance) x = -x;
     if (Math.Abs(z) > WrapDistance) z = -z;
     coords.X = x;
     coords.Z = z;
     coords.WrapDistance = WrapDistance;
 }
Esempio n. 5
0
        public Chunk(ChunkManager manager, ref ChunkCoordinate coords, ref Vector3 initialPosition)
        {
            ObjectCount += 1;
            ObjectNumber = ObjectCount;
            Position = initialPosition;
            Coords = coords;
            _heightMap = new int[WIDTH, WIDTH];
            Meshes = new List<ChunkMesh>();

            Xstart = coords.X * Chunk.WIDTH;
            Zstart = coords.Z * Chunk.WIDTH;
            manager.CubeStorage.WrapCoords(ref Xstart, ref Zstart);

            ChangedSinceLoad = false;
            Empty = true;
        }
Esempio n. 6
0
 public void GetShiftedX(int x, out ChunkCoordinate coords)
 {
     int temp = X + x;
     if (Math.Abs(temp) > WrapDistance) temp = -temp;
     coords.X = temp;
     coords.Z = Z;
     coords.WrapDistance = WrapDistance;
 }
Esempio n. 7
0
 public bool Equals(ref ChunkCoordinate coords)
 {
     return (coords.X == X) && (coords.Z == Z) && (coords.WrapDistance == WrapDistance);
 }
Esempio n. 8
0
 public int DistanceSquared(ref ChunkCoordinate other)
 {
     int x = other.X - X;
     int z = other.Z - Z;
     return x * x + z * z;
 }
Esempio n. 9
0
 public int Distance(ref ChunkCoordinate other)
 {
     int x = other.X - X;
     int z = other.Z - Z;
     return (int)Math.Sqrt(x * x + z * z);
 }
Esempio n. 10
0
        public byte Neighbors(ref ChunkCoordinate coord2)
        {
            int diffX = coord2.X - X;
            int diffZ = coord2.Z - Z;

            if (diffZ == 0 && diffX == 1) return 1;
            else if (diffZ == 0 && diffX == -1) return 2;
            else if (diffX == 0 && diffZ == 1) return 4;
            else if (diffX == 0 && diffZ == -1) return 8;
            else if (diffX == 1 && diffZ == 1) return 16;
            else if (diffX == -1 && diffZ == 1) return 32;
            else if (diffX == 1 && diffZ == -1) return 64;
            else if (diffX == -1 && diffZ == -1) return 128;
            else return 0;
        }
Esempio n. 11
0
 public void GetShiftedZ(int z, out ChunkCoordinate coords)
 {
     int temp = Z + z;
     if (Math.Abs(temp) > WrapDistance) temp = -temp;
     coords.X = X;
     coords.Z = temp;
     coords.WrapDistance = WrapDistance;
 }
Esempio n. 12
0
        public void Update(float dt, ChunkCoordinate playerPosition, Vector3 deltaPosition)
        {
            watch1.Start();

            _numToLoad = PER_TICK_CHUNKS_LOAD;
            _numToLight = PER_TICK_CHUNKS_LIGHT;
            _numToBuild = PER_TICK_CHUNKS_BUILD;

            PlayerPosition = playerPosition;

            //Queue chunks for processing
            _timeSinceQueue += dt;
            if (_timeSinceQueue > TIME_BETWEEN_QUEUES)
            {
                _timeSinceQueue -= TIME_BETWEEN_QUEUES;

                watch2.Start();
                ManageChunks();
                watch2.Stop();
                QueueTime = (float)watch2.Elapsed.TotalMilliseconds;
            }

            //Rebuild chunk vertices, always done sequentially to ensure that changes are immediately noticed by player.
            watch2.Reset();
            watch2.Start();
            RebuildChunkVertices();
            watch2.Stop();
            RebuildTime = (float)watch2.Elapsed.TotalMilliseconds;

            //Unload chunks by transferring them back to hard drive with changes and then release to object pool (eventually)
            if (UnloadQueue.Count > 0 && _running)
            {
                _running = false;
                ThreadPool.UnsafeQueueUserWorkItem(UnloadChunks,false);
            }

            //Update all chunks
            watch2.Reset();
            watch2.Start();
            ChunkStorage.UpdateChunks(dt, deltaPosition);
            watch2.Stop();
            UpdateTime = (float)watch2.Elapsed.TotalMilliseconds;

            //Store previous player position
            PreviousPlayerPosition = PlayerPosition;

            watch1.Stop();
            TotalUpdateTime = (float)watch1.Elapsed.TotalMilliseconds;

            watch1.Reset();
            watch2.Reset();
        }
Esempio n. 13
0
 public void Reload()
 {
     ChunkStorage.UnloadAll(this);
     Vector3 positionInChunk = -Vector3.Up * Chunk.HEIGHT * 0.9f;
     ChunkCoordinate chunkPlayerIsIn = new ChunkCoordinate(0, 0, 8000);
     Chunk seed = new Chunk(this, ref chunkPlayerIsIn, ref positionInChunk);
     ChunkStorage.Store(seed, this);
     _loadQueue.TryAdd(seed);
     Monitor.Pulse(_loadQueue);
 }
Esempio n. 14
0
        public ChunkManager(Game game, ChunkCoordinate chunkPlayerIsIn, Vector3 positionInChunk, bool useThreading)
        {
            _graphics = game.GraphicsDevice;
            ChunkRenderer = new ChunkMeshRenderer(game);

            UseThreading = useThreading;

            int width = 1;
            while (width < 2*CHUNK_LOAD_DIST) width *= 2;
            ChunkStorage = new ChunkStorage(width);
            //WARN: When load dist is a power of 2 queue chunks infinitely adds delegates to the ChunkStateChange event resulting in an eventual
            //out of memory exception.
            CHUNK_LOAD_DIST = width / 2-1;
            CHUNK_LIGHT_DIST = CHUNK_LOAD_DIST;// -1;
            CHUNK_BUILD_DIST = CHUNK_LIGHT_DIST;// -1;
            width *= Chunk.WIDTH;
            CubeStorage = new CubeStorage(width, Chunk.HEIGHT, width);

            _loadQueue = new ConcurrentSerialQueue<Chunk>();
            _vertexBuffer = new CubeVertex[1000];

            LightQueue = new ConcurrentSerialQueue<Chunk>();
            BuildQueue = new ConcurrentSerialQueue<Chunk>();
            RebuildQueue = new Queue<Chunk>();
            UnloadQueue = new ConcurrentSerialQueue<Chunk>();
            DrawList = new List<Chunk>();

            _timeSinceQueue = TIME_BETWEEN_QUEUES;
            _timeSinceLoad = TIME_BETWEEN_LOADS;
            _timeSinceLight = TIME_BETWEEN_LIGHTS * 0.5f;
            _timeSinceBuild = 0.0f;

            _running = true;
            _running = true;
            _running = true;
            _running = true;

            watch1 = new Stopwatch();
            watch2 = new Stopwatch();

            Thread thread = new Thread(LoadChunks);
            thread.IsBackground = true;
            thread.SetApartmentState(ApartmentState.MTA);
            thread.Name = "LoadThread1";
            thread.Priority = ThreadPriority.Lowest;
            thread.Start();

            //thread = new Thread(LoadChunks);
            //thread.IsBackground = true;
            //thread.SetApartmentState(ApartmentState.MTA);
            //thread.Name = "LoadThread2";
            //thread.Priority = ThreadPriority.Lowest;
            //thread.Start();

            thread = new Thread(LightChunks);
            thread.IsBackground = true;
            thread.SetApartmentState(ApartmentState.MTA);
            thread.Name = "LightThread";
            thread.Priority = ThreadPriority.Lowest;
            thread.Start();

            thread = new Thread(BuildChunkVertices);
            thread.IsBackground = true;
            thread.SetApartmentState(ApartmentState.MTA);
            thread.Name = "BuildThread";
            thread.Priority = ThreadPriority.Lowest;
            thread.Start();

            //Initialize chunk loading.
            positionInChunk = -positionInChunk;
            Chunk seed = new Chunk(this, ref chunkPlayerIsIn, ref positionInChunk);
            _loadQueue.TryAdd(seed);
            ChunkStorage.Store(seed, this);
        }