private void ChunkResyncing_Threaded(VisualChunk chunk)
 {
     if (chunk.IsServerResyncMode)
     {
         _landscapeManager.CreateLandScape(chunk);
     }
     chunk.ThreadStatus = ThreadsManager.ThreadStatus.Idle;
 }
Example #2
0
        /// <summary>
        /// Get a world's chunk from a chunk location in world coordinate with array bound test
        /// </summary>
        /// <param name="X">Chunk X coordinate</param>
        /// <param name="Z">Chunk Z coordinate</param>
        /// <returns></returns>
        public bool GetSafeChunkFromChunkCoord(int X, int Z, out VisualChunk chunk)
        {
            //From Chunk coordinate to World Coordinate
            X *= AbstractChunk.ChunkSize.X;
            Z *= AbstractChunk.ChunkSize.Z;

            return(GetSafeChunk(X, Z, out chunk));
        }
        //Will create the chunk buffer, ready to be sent to the GC
        private void CreateChunkMeshes_Threaded(VisualChunk chunk)
        {
#if PERFTEST
            Utopia.Worlds.Chunks.WorldChunks.perf.AddData("CreateChunkMeshes_Threaded Started  " + chunk.ChunkID);
#endif

            //The chunk surrounding me must all have their landscape created !
            _chunkMeshManager.CreateChunkMesh(chunk);
            chunk.ThreadStatus = ThreadsManager.ThreadStatus.Idle;
        }
Example #4
0
        /// <summary>
        /// Get a world's chunk from a Cube location in world coordinate with out of array check
        /// </summary>
        /// <param name="X">Cube X coordinate in world coordinate</param>
        /// <param name="Z">Cube Z coordinate in world coordinate</param>
        /// <param name="chunk">The VisualChunk return</param>
        /// <returns>True if the chunk was found</returns>
        public bool GetSafeChunk(int X, int Z, out VisualChunk chunk)
        {
            if (X < VisualWorldParameters.WorldRange.Position.X || X >= VisualWorldParameters.WorldRange.Max.X || Z < VisualWorldParameters.WorldRange.Position.Z || Z >= VisualWorldParameters.WorldRange.Max.Z)
            {
                chunk = null;
                return(false);
            }

            chunk = GetChunk(X, Z);
            return(true);
        }
Example #5
0
        /// <summary>
        /// Get a world's chunk from a chunk location in world coordinate
        /// </summary>
        /// <param name="X">Chunk X coordinate</param>
        /// <param name="Z">Chunk Z coordinate</param>
        /// <returns></returns>
        public VisualChunk[] GetFourSurroundingChunkFromChunkCoord(int X, int Z)
        {
            VisualChunk[] surroundingChunk = new VisualChunk[4];

            surroundingChunk[0] = GetChunkFromChunkCoord(X + 1, Z);
            surroundingChunk[1] = GetChunkFromChunkCoord(X, Z + 1);
            surroundingChunk[2] = GetChunkFromChunkCoord(X - 1, Z);
            surroundingChunk[3] = GetChunkFromChunkCoord(X, Z - 1);

            return(surroundingChunk);
        }
        //Will propagate light from chunk surrounding the current chunk
        private void ChunkOuterLightPropagation_Threaded(VisualChunk chunk)
        {
#if PERFTEST
            Utopia.Worlds.Chunks.WorldChunks.perf.AddData("ChunkOuterLightPropagation_Threaded Started " + chunk.ChunkID);
#endif

            _lightingManager.PropagateOutsideChunkLightSources(chunk);
            chunk.ThreadStatus = ThreadsManager.ThreadStatus.Idle;
            //The state will always be OuterLightSourcesProcessed, but the logic could not be implementated if the chunk was a Border chunk. In this case its
            //IsOutsideLightSourcePropagated will be False, it will be process as soon as the chunk isBorderChunk change to false !
        }
Example #7
0
 public void DrawStaticEntitiesShadow(DeviceContext context, VisualChunk chunk)
 {
     //For Each different entity Model
     foreach (var pair in chunk.AllPairs())
     {
         if (pair.Value.Count == 0)
         {
             continue;
         }
         var entity = pair.Value.First();
         entity.VisualVoxelModel.DrawInstanced(context, pair.Value.Where(ve => IsEntityVisible(ve.Entity.Position)).Select(ve => ve.VoxelEntity.ModelInstance).ToList());
     }
 }
        //Will create new chunks based on chunks with state = Empty
        private void CreateNewChunk()
        {
            //Process each chunk that are in Empty state, and not currently processed
            foreach (VisualChunk chunk in SortedChunks.Where(x => (x.State == ChunkState.Empty || x.State == ChunkState.LandscapeCreated) && x.ThreadStatus == ThreadsManager.ThreadStatus.Idle))
            {
                VisualChunk localChunk = chunk;

                //Start chunk creation process in a threaded way !
                localChunk.ThreadStatus = ThreadsManager.ThreadStatus.Locked;           //Lock the thread before entering async process.
#if DEBUG
                localChunk.ThreadLockedBy = "CreateNewChunk";
#endif
                //SmartThread.ThreadPool.QueueWorkItem(ChunkCreationThreadedSteps_Threaded, chunk, WorkItemPriority.Normal);
                S33M3DXEngine.Threading.ThreadsManager.RunAsync(() => ChunkCreationThreadedSteps_Threaded(localChunk));
            }
        }
Example #9
0
        private void DrawStaticEntities(DeviceContext context, VisualChunk chunk)
        {
            //For Each different entity Model
            foreach (var pair in chunk.AllPairs())
            {
                // For each instance of the model - update data
                foreach (var staticEntity in pair.Value)
                {
                    //The staticEntity.Color is affected at entity creation time in the LightingManager.PropagateLightInsideStaticEntities(...)
                    var sunPart     = (float)staticEntity.BlockLight.A / 255;
                    var sunColor    = Skydome.SunColor * sunPart;
                    var resultColor = Color3.Max(staticEntity.BlockLight.ToColor3(), sunColor);
                    staticEntity.VoxelEntity.ModelInstance.LightColor    = resultColor;
                    staticEntity.VoxelEntity.ModelInstance.SunLightLevel = sunPart;
                    if (!DrawStaticInstanced)
                    {
                        if (IsEntityVisible(staticEntity.Entity.Position))
                        {
                            var sw = Stopwatch.StartNew();
                            staticEntity.VisualVoxelModel.Draw(context, _voxelModelEffect, staticEntity.VoxelEntity.ModelInstance);
                            sw.Stop();
                            _staticEntityDrawTime += sw.Elapsed.TotalMilliseconds;
                            _staticEntityDrawCalls++;
                        }
                    }
                }

                if (DrawStaticInstanced)
                {
                    if (pair.Value.Count == 0)
                    {
                        continue;
                    }
                    var entity = pair.Value.First();
                    var sw     = Stopwatch.StartNew();
                    entity.VisualVoxelModel.DrawInstanced(context, _voxelModelInstancedEffect, pair.Value.Where(ve => IsEntityVisible(ve.Entity.Position)).Select(ve => ve.VoxelEntity.ModelInstance).ToList());
                    sw.Stop();
                    _staticEntityDrawTime += sw.Elapsed.TotalMilliseconds;
                    _staticEntityDrawCalls++;
                }
            }
        }
Example #10
0
        //Will take the newly created chunks || the chunk that didn't had the outside light propagate (Border chunk), and propagate the light from the surroundings chunks
        private void PropagateOuterChunkLights()
        {
            //Process each chunk that are in InnerLightsSourcePropagated state, and not being currently processed
            foreach (VisualChunk chunk in SortedChunks.Where(x =>
                                                             (x.State == ChunkState.InnerLightsSourcePropagated || (x.IsOutsideLightSourcePropagated == false && x.IsBorderChunk == false && x.State >= ChunkState.InnerLightsSourcePropagated)) &&
                                                             x.ThreadStatus == ThreadsManager.ThreadStatus.Idle))
            {
                VisualChunk localChunk = chunk;

                //all the surrounding chunks must have had their LightSources Processed at minimum.
                if (localChunk.IsBorderChunk == true || localChunk.SurroundingChunksMinimumState(ChunkState.InnerLightsSourcePropagated))
                {
                    //Check if the surrounding chunk from this chunk are in the correct state = ChunkState.InnerLightsSourcePropagated
                    localChunk.ThreadStatus = ThreadsManager.ThreadStatus.Locked;           //Lock the thread before entering async process.
#if DEBUG
                    localChunk.ThreadLockedBy = "PropagateOuterChunkLights";
#endif
                    S33M3DXEngine.Threading.ThreadsManager.RunAsync(() => ChunkOuterLightPropagation_Threaded(localChunk));
                }
            }
        }
Example #11
0
        private void CreateChunkMeshes(int maximumUpdateOrderPossible)
        {
            //Process each chunk that are in IsOutsideLightSourcePropagated state, and not currently processed
            foreach (VisualChunk chunk in SortedChunks.Where(x => x.State == ChunkState.OuterLightSourcesProcessed && x.ThreadStatus == ThreadsManager.ThreadStatus.Idle))
            {
                VisualChunk localChunk = chunk;
                if (maximumUpdateOrderPossible > 0 && localChunk.UpdateOrder == 0)
                {
                    continue;
                }

                //all the surrounding chunks must have had their LightSources Processed at minimum.
                if (localChunk.SurroundingChunksMinimumState(ChunkState.OuterLightSourcesProcessed))
                {
                    localChunk.ThreadStatus = ThreadsManager.ThreadStatus.Locked;
#if DEBUG
                    localChunk.ThreadLockedBy = "CreateChunkMeshes";
#endif
                    S33M3DXEngine.Threading.ThreadsManager.RunAsync(() => CreateChunkMeshes_Threaded(localChunk), localChunk.UpdateOrder > 0 ? ThreadsManager.ThreadTaskPriority.High : ThreadsManager.ThreadTaskPriority.Normal);
                }
            }
        }
Example #12
0
        //Chunk creation steps
        //The process done isnight this step is impacting only the chunk that need to be creation
        private void ChunkCreationThreadedSteps_Threaded(VisualChunk chunk)
        {
#if PERFTEST
            Utopia.Worlds.Chunks.WorldChunks.perf.AddData("ChunkCreationThreadedSteps_Threaded Started " + chunk.ChunkID);
#endif

            //Create the landscape, by updating the "Big Array" area under the chunk
            if (chunk.State == ChunkState.Empty)
            {
                _landscapeManager.CreateLandScape(chunk);
            }

            //Was my landscape Creation, if not it means that the chunk has been requested to the server, waiting for server answer
            if (chunk.State == ChunkState.LandscapeCreated)
            {
                //Create Inner chunk Light sources
                _lightingManager.CreateChunkLightSources(chunk);
                //Propagate Inner chunk LightSources
                _lightingManager.PropagateInnerChunkLightSources(chunk);
                //The Thread status will be ChunkState.InnerLightsSourcePropagated if going out of this
            }

            chunk.ThreadStatus = ThreadsManager.ThreadStatus.Idle;
        }
Example #13
0
        /// <summary>
        /// Initiliaze the chunks array
        /// </summary>
        private void InitChunks()
        {
            //Init serverEventArea around player
            var areaSize = _server.GameInformations.AreaSize;

            var notificationAreaSize = new Vector3I(areaSize.X / AbstractChunk.ChunkSize.X, 0, areaSize.Y / AbstractChunk.ChunkSize.Z) + Vector3I.One;

            _eventNotificationArea = new Range3I
            {
                Position = BlockHelper.EntityToChunkPosition(PlayerManager.Player.Position) - notificationAreaSize / 2,
                Size     = notificationAreaSize
            };

            //Defining the World Offset, to be used to reference the 2d circular array of dim defined in chunk
            VisualWorldParameters.WorldRange = new Range3I()
            {
                Size     = VisualWorldParameters.WorldVisibleSize,
                Position = VisualWorldParameters.WorldChunkStartUpPosition
            };

            //Create the chunks that will be used as "Rendering" array
            Chunks       = new VisualChunk[VisualWorldParameters.VisibleChunkInWorld.X * VisualWorldParameters.VisibleChunkInWorld.Y];
            SortedChunks = new VisualChunk[VisualWorldParameters.VisibleChunkInWorld.X * VisualWorldParameters.VisibleChunkInWorld.Y];

            Range3I     cubeRange;      //Used to define the blocks inside the chunks
            int         arrayX, arrayZ; //Chunk Array indexes
            VisualChunk chunk;

            //Chunk Server request variables
            List <Vector3I> chunkPosition = new List <Vector3I>();
            List <Md5Hash>  chunkHash     = new List <Md5Hash>();
            Md5Hash         chunkMD5;

            for (int chunkX = 0; chunkX < VisualWorldParameters.VisibleChunkInWorld.X; chunkX++)
            {
                for (int chunkZ = 0; chunkZ < VisualWorldParameters.VisibleChunkInWorld.Y; chunkZ++)
                {
                    cubeRange = new Range3I()
                    {
                        Position = new Vector3I(VisualWorldParameters.WorldChunkStartUpPosition.X + (chunkX * AbstractChunk.ChunkSize.X), 0, VisualWorldParameters.WorldChunkStartUpPosition.Z + (chunkZ * AbstractChunk.ChunkSize.Z)),
                        Size     = AbstractChunk.ChunkSize
                                   //Max = new Vector3I(VisualWorldParameters.WorldChunkStartUpPosition.X + ((chunkX + 1) * AbstractChunk.ChunkSize.X), AbstractChunk.ChunkSize.Y, VisualWorldParameters.WorldChunkStartUpPosition.Y + ((chunkZ + 1) * AbstractChunk.ChunkSize.Z))
                    };

                    arrayX = MathHelper.Mod(cubeRange.Position.X, VisualWorldParameters.WorldVisibleSize.X);
                    arrayZ = MathHelper.Mod(cubeRange.Position.Z, VisualWorldParameters.WorldVisibleSize.Z);

                    //Create the new VisualChunk
                    chunk = new VisualChunk(_d3dEngine, _worldFocusManager, VisualWorldParameters, ref cubeRange, _cubesHolder, _camManager, this, _voxelModelManager, _chunkEntityImpactManager);
                    chunk.IsServerRequested = true;
                    //Ask the chunk Data to the DB, in case my local MD5 is equal to the server one.
                    chunk.StorageRequestTicket = _chunkstorage.RequestDataTicket_async(chunk.Position);

                    chunk.ReadyToDraw += ChunkReadyToDraw;

                    //Store this chunk inside the arrays.
                    Chunks[(arrayX >> VisualWorldParameters.ChunkPOWsize) + (arrayZ >> VisualWorldParameters.ChunkPOWsize) * VisualWorldParameters.VisibleChunkInWorld.X]       = chunk;
                    SortedChunks[(arrayX >> VisualWorldParameters.ChunkPOWsize) + (arrayZ >> VisualWorldParameters.ChunkPOWsize) * VisualWorldParameters.VisibleChunkInWorld.X] = chunk;

                    //Is this chunk inside the Client storage manager ?
                    if (_chunkstorage.ChunkHashes.TryGetValue(chunk.Position, out chunkMD5))
                    {
                        chunkPosition.Add(new Vector3I((VisualWorldParameters.WorldChunkStartUpPosition.X + (chunkX * AbstractChunk.ChunkSize.X)) / AbstractChunk.ChunkSize.X, 0,
                                                       (VisualWorldParameters.WorldChunkStartUpPosition.Z + (chunkZ * AbstractChunk.ChunkSize.Z)) / AbstractChunk.ChunkSize.Z));
                        chunkHash.Add(chunkMD5);
                    }
                }
            }


            var chunkRange = new Range3I(
                new Vector3I(
                    VisualWorldParameters.WorldChunkStartUpPosition.X / AbstractChunk.ChunkSize.X,
                    0,
                    VisualWorldParameters.WorldChunkStartUpPosition.Z / AbstractChunk.ChunkSize.Z
                    ),
                new Vector3I(
                    VisualWorldParameters.VisibleChunkInWorld.X,
                    1,
                    VisualWorldParameters.VisibleChunkInWorld.Y
                    )
                );

#if DEBUG
            logger.Trace("Chunk bulk request to server (Init Phases, data in chunk unit) position : {0} ; Size : {1}", chunkRange.Position, chunkRange.Size);
#endif

            _server.ServerConnection.Send(
                new GetChunksMessage()
            {
                Range       = chunkRange,
                Md5Hashes   = chunkHash.ToArray(),
                Positions   = chunkPosition.ToArray(),
                HashesCount = chunkHash.Count,
                Flag        = GetChunksMessageFlag.DontSendChunkDataIfNotModified
            }
                );

            ChunkNeed2BeSorted = true; // Will force the SortedChunks array to be sorted against the "camera position" (The player).

            OnChunksArrayInitialized();
        }
Example #14
0
 /// <summary>
 /// Get a world's chunk from a Cube location in world coordinate with out of array check
 /// </summary>
 /// <param name="X">Cube X coordinate in world coordinate</param>
 /// <param name="Z">Cube Z coordinate in world coordinate</param>
 /// <param name="chunk">The VisualChunk return</param>
 /// <returns>True if the chunk was found</returns>
 public bool GetSafeChunk(float X, float Z, out VisualChunk chunk)
 {
     return(GetSafeChunk((int)X, (int)Z, out chunk));
 }
Example #15
0
 /// <summary>
 /// Get a world's chunk from a chunk location in world coordinate with array bound test
 /// </summary>
 /// <param name="X">Chunk X coordinate</param>
 /// <param name="Z">Chunk Z coordinate</param>
 /// <returns></returns>
 public bool GetSafeChunkFromChunkCoord(Vector3I chunkPos, out VisualChunk chunk)
 {
     return(GetSafeChunkFromChunkCoord(chunkPos.X, chunkPos.Z, out chunk));
 }