Exemple #1
0
        public ChunkColumn(int x, int z)
        {
            X = x;
            Z = z;

            for (int i = 0; i < Sections.Length; i++)
            {
                Sections[i] = null;
            }

            BlockEntities = new ConcurrentDictionary <BlockCoordinates, BlockEntity>();
            _lightUpdateWatch.Start();

            ChunkData = new ChunkData(new ChunkCoordinates(x, z));

            var     index     = new Vector3(x << 4, 0, z << 4);
            var     sizeOffs  = 16 * 0.5f - 0.5f;
            Vector3 boundsMin = new Vector3(
                index.X - sizeOffs,
                -0.5f,
                index.Z - sizeOffs
                );
            Vector3 boundsMax = new Vector3(
                index.X + sizeOffs,
                0.5f + 256,
                index.Z + sizeOffs
                );
            var bounds = new BoundingBox(boundsMin, boundsMax);

            _octree = new ChunkOctree(bounds);
        }
        public ClientChunkStateManager(
            IChunkOctreeFactory chunkOctreeFactory,
            IPositionScaleTranslation positionScaleTranslation,
            IPredeterminedChunkPositions predeterminedChunkPositions,
            MxClient client)
        {
            this.m_PositionScaleTranslation = positionScaleTranslation;
            this.m_PredeterminedChunkPositions = predeterminedChunkPositions;

            this.m_ClientHasChunkOctree = chunkOctreeFactory.CreateChunkOctree<ServerChunk>();
        }
Exemple #3
0
 public RPGWorld(LevelReference levelRef)
     : base()
 {
     if (levelRef != null)
     {
         this.m_DiskLevel = levelRef.Source.LoadLevel(levelRef.Name);
     }
     this.m_Octree = new ChunkOctree();
     new Chunk(this.m_DiskLevel, this.m_Octree, 0, 0, 0);
     this.m_Player = new Player(this);
     this.m_Player.SearchForTerrain = true;
     this.Entities.Add(this.m_Player);
 }
        public ClientChunk CreateClientChunk(ChunkOctree<ClientChunk> octree, long x, long y, long z)
        {
            var existing = octree.Get(x, y, z);

            if (existing != null)
            {
                return existing;
            }

            var @new = new ClientChunk(x, y, z);
            octree.Set(@new);

            return @new;
        }
Exemple #5
0
    void OnDrawGizmoss()
    {
        float       time   = Time.realtimeSinceStartup;
        ChunkOctree octree = new ChunkOctree(16, 4);

        Debug.Log(Time.realtimeSinceStartup - time);

        octree.AddBlockToOctree(ConvertBlockPosToLocalPos(new Vector3Int(0, 0, 0)), octree.OctreeHandle);
        octree.AddBlockToOctree(ConvertBlockPosToLocalPos(new Vector3Int(0, 1, 0)), octree.OctreeHandle);
        octree.AddBlockToOctree(ConvertBlockPosToLocalPos(new Vector3Int(5, 10, 5)), octree.OctreeHandle);
        octree.AddBlockToOctree(ConvertBlockPosToLocalPos(new Vector3Int(6, 10, 5)), octree.OctreeHandle);

        octree.RemoveBlockFromOctree(ConvertBlockPosToLocalPos(new Vector3Int(0, 0, 0)), octree.OctreeHandle);
        octree.RemoveBlockFromOctree(ConvertBlockPosToLocalPos(new Vector3Int(0, 1, 0)), octree.OctreeHandle);
        octree.RemoveBlockFromOctree(ConvertBlockPosToLocalPos(new Vector3Int(6, 10, 5)), octree.OctreeHandle);

        DrawNode(octree.OctreeHandle);
    }
        public void RecalculateDesiredChunks(
            PlayerServerEntity playerEntity,
            ChunkOctree<ServerChunk> serverOctree,
            Action<long, long, long> chunkRequired)
        {
            var chunks = new List<ChunkPos>();

            var current = serverOctree.Get((long)playerEntity.X, (long)playerEntity.Y, (long)playerEntity.Z);

            foreach (var l in this.m_PredeterminedChunkPositions.GetAbsolutePositions(new Vector3(
                (float)current.X,
                (float)current.Y,
                (float)current.Z)))
            {
                chunks.Add(
                    new ChunkPos
                    {
                        X = (long)l.X,
                        Y = (long)l.Y,
                        Z = (long)l.Z
                    });
            }

            // Check if each of the chunks is already in the octree.
            foreach (var pos in chunks.ToArray())
            {
                if (this.m_ClientHasChunkOctree.Get(pos.X, pos.Y, pos.Z) != null)
                {
                    chunks.Remove(pos);
                }
            }

            // Callback for required chunks.
            foreach (var chunk in chunks)
            {
                chunkRequired(chunk.X, chunk.Y, chunk.Z);
            }
        }
        private ClientChunk GetChunkOrGenerate(ChunkOctree<ClientChunk> octree, ILevel level, long x, long y, long z)
        {
            using (this.m_Profiler.Measure("tychaia-chunk_test"))
            {
                var existing = octree.Get(x, y, z);
                if (existing != null)
                    return existing;
            }

            using (this.m_Profiler.Measure("tychaia-chunk_create"))
            {
                return this.m_ClientChunkFactory.CreateClientChunk(
                    octree,
                    x,
                    y,
                    z);
            }
        }
        protected override void DrawTilesBelow(GameContext context)
        {
            // Ensure we have a chunk manager to source chunks from.
            if (!(context.World is RPGWorld))
            {
                return;
            }
            this.Octree = (context.World as RPGWorld).ChunkOctree;
            if (this.Octree == null)
            {
                return;
            }
            if (this.Chunk == null)
            {
                this.Chunk = this.Octree.Get(0, 0, 0);
            }

            // Determine our Z offset.
            int zoffset = -(Chunk.Depth - this.ZLevel) * TileIsometricifier.TILE_CUBE_HEIGHT;

            // Get rendering information.
            ChunkRenderer.ResetNeeded();
            IEnumerable <RelativeRenderInformation> renders = this.GetRelativeRenderInformation(context, this.Chunk);

            ChunkRenderer.LastRenderedCountOnScreen = renders.Count();

            // Render chunks.
            if (FilteredFeatures.IsEnabled(Feature.DepthBuffer))
            {
                context.EndSpriteBatch();
                context.Graphics.GraphicsDevice.SetRenderTarget(RenderingBuffers.ScreenBuffer);
                context.StartSpriteBatch();
            }
            foreach (RelativeRenderInformation ri in renders)
            {
                if (ri.Target == this.Chunk)
                {
                    this.m_ChunkCenterX = ri.X + TileIsometricifier.CHUNK_TOP_WIDTH / 2;
                    this.m_ChunkCenterY = ri.Y;
                }
                Texture2D tex = ri.Target.Texture;
                ChunkRenderer.MarkNeeded(ri.Target);
                if (tex != null)
                {
                    ChunkRenderer.MarkUsed(ri.Target);
                    if (FilteredFeatures.IsEnabled(Feature.DepthBuffer))
                    {
                        context.SpriteBatch.Draw(tex, new Vector2(ri.X, ri.Y + zoffset), Color.White);
                    }
                    else
                    {
                        if (FilteredFeatures.IsEnabled(Feature.RenderingBuffers))
                        {
                            context.Graphics.GraphicsDevice.SetRenderTarget(RenderingBuffers.ScreenBuffer);
                        }
                        context.SpriteBatch.Draw(tex, new Vector2(ri.X, ri.Y + zoffset), Color.White);
                    }
                    FilteredConsole.WriteLine(FilterCategory.RenderingActive, "Rendering chunk at " + ri.X + ", " + ri.Y + ".");
                }
                else
                {
                    FilteredConsole.WriteLine(FilterCategory.Rendering, "No texture yet for chunk to render at " + ri.X + ", " + ri.Y + ".");
                }
            }

            // Render depth maps.
            if (FilteredFeatures.IsEnabled(Feature.DepthBuffer))
            {
                context.EndSpriteBatch();
                context.Graphics.GraphicsDevice.SetRenderTarget(RenderingBuffers.DepthBuffer);
                context.StartSpriteBatch();
                foreach (RelativeRenderInformation ri in renders)
                {
                    Texture2D depth = ri.Target.DepthMap;
                    if (depth != null)
                    {
                        ChunkRenderer.MarkUsed(ri.Target);
                        if (FilteredFeatures.IsEnabled(Feature.DepthBuffer))
                        {
                            context.SpriteBatch.Draw(depth, new Vector2(ri.X, ri.Y + zoffset), Color.White);
                        }
                    }
                }
            }

            // Finish drawing.
            context.EndSpriteBatch();
            context.Graphics.GraphicsDevice.SetRenderTarget(null);
            context.StartSpriteBatch();
        }
        protected override void HandleRenderOfEntity(GameContext context, IEntity a)
        {
            if (!FilteredFeatures.IsEnabled(Feature.RenderEntities))
            {
                return;
            }

            if (a is ChunkEntity)
            {
                // Ensure we have a chunk manager to source chunks from.
                if (!(context.World is RPGWorld))
                {
                    return;
                }
                this.Octree = (context.World as RPGWorld).ChunkOctree;
                if (this.Octree == null)
                {
                    return;
                }
                if (this.Chunk == null)
                {
                    this.Chunk = this.Octree.Get(0, 0, 0);
                }

                // Special handling for entities in the 3D world.
                ChunkEntity ce  = a as ChunkEntity;
                Vector2     pos = this.TranslatePoint(ce.X, ce.Y, ce.Z);

                // Set depth information.
                if (RenderingBuffers.DepthBuffer != null && FilteredFeatures.IsEnabled(Feature.IsometricOcclusion))
                {
                    // Draw image with depth.
                    float depth = ((
                                       ((int)((ce.X < 0) ? Chunk.Width : 0) + (ce.X / Scale.CUBE_X) % Chunk.Width) +
                                       ((int)((ce.Y < 0) ? Chunk.Height : 0) + (ce.Y / Scale.CUBE_Y) % Chunk.Height) +
                                       ((int)((ce.Z < 0) ? Chunk.Depth : 0) + ((ce.Z / Scale.CUBE_Z) - 1) % Chunk.Depth)) / 255f);
                    this.m_OccludingSpriteBatch.DrawOccludable(
                        context.Textures[ce.Image],
                        new Rectangle((int)(pos.X - ce.ImageOffsetX), (int)(pos.Y - ce.ImageOffsetY),
                                      context.Textures[ce.Image].Width, context.Textures[ce.Image].Height),
                        ce.Color.ToPremultiplied(),
                        depth
                        );
                }
                else
                {
                    // Draw image normally.
                    context.SpriteBatch.Draw(
                        context.Textures[ce.Image],
                        new Rectangle((int)(pos.X - ce.ImageOffsetX), (int)(pos.Y - ce.ImageOffsetY),
                                      context.Textures[ce.Image].Width, context.Textures[ce.Image].Height),
                        ce.Color.ToPremultiplied()
                        );
                }
            }
            else
            {
                // Render using the default settings.
                base.HandleRenderOfEntity(context, a);
            }
        }