Ejemplo n.º 1
0
        public static BoxPrimitive CreatePrimitive(GraphicsDevice graphics, Texture2D textureMap, int width, int height, Point top, Point sides, Point bottom)
        {
            BoxPrimitive.BoxTextureCoords coords = new BoxPrimitive.BoxTextureCoords(textureMap.Width, textureMap.Height, width, height, sides, sides, top, bottom, sides, sides);
            BoxPrimitive cube = new BoxPrimitive(graphics, 1.0f, 1.0f, 1.0f, coords);

            return cube;
        }
Ejemplo n.º 2
0
        public void InitializeFromChunk(VoxelChunk chunk, DesignationSet DesignationSet, WorldManager World)
        {
            DebugHelper.AssertNotNull(chunk);
            DebugHelper.AssertNotNull(DesignationSet);
            DebugHelper.AssertNotNull(World);

            BoxPrimitive bedrockModel    = Library.GetVoxelPrimitive("Bedrock");
            var          sliceStack      = new List <RawPrimitive>();
            var          cache           = new Cache();
            int          maxViewingLevel = World.Renderer.PersistentSettings.MaxViewingLevel;

            for (var localY = 0; localY < maxViewingLevel - chunk.Origin.Y && localY < VoxelConstants.ChunkSizeY; ++localY) // Todo: Only iterate inside the chunk.
            {
                RawPrimitive sliceGeometry = null;

                lock (chunk.Data.SliceCache)
                {
                    var cachedSlice = chunk.Data.SliceCache[localY];

                    if (cachedSlice != null)
                    {
                        cache.Clear();

                        sliceStack.Add(cachedSlice);

                        if (GameSettings.Default.GrassMotes)
                        {
                            chunk.RebuildMoteLayerIfNull(localY);
                        }

                        continue;
                    }

                    sliceGeometry = new RawPrimitive
                    {
                        Vertices = null,
                        Indexes  = null
                    };

                    chunk.Data.SliceCache[localY] = sliceGeometry;
                }

                if (GameSettings.Default.CalculateRamps)
                {
                    UpdateCornerRamps(World.ChunkManager, chunk, localY);
                    UpdateNeighborEdgeRamps(World.ChunkManager, chunk, localY);
                }

                if (GameSettings.Default.GrassMotes)
                {
                    chunk.RebuildMoteLayer(localY);
                }

                DebugHelper.AssertNotNull(sliceGeometry);
                BuildSliceGeometry(chunk, bedrockModel, cache, localY, sliceGeometry, DesignationSet, World);

                sliceStack.Add(sliceGeometry);
            }

            var combinedGeometry = RawPrimitive.Concat(sliceStack);

            Vertices    = combinedGeometry.Vertices;
            VertexCount = combinedGeometry.VertexCount;
            Indexes     = combinedGeometry.Indexes.Select(s => (ushort)s).ToArray();
            IndexCount  = combinedGeometry.IndexCount;
        }
Ejemplo n.º 3
0
        public static void InitializeDefaultLibrary(GraphicsDevice graphics, Texture2D cubeTexture)
        {
            if (PrimitiveMap.Count > 0)
            {
                return;
            }

            BoxPrimitive grassCube       = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(0, 0), new Point(2, 0), new Point(2, 0));
            BoxPrimitive dirtCube        = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(2, 0), new Point(2, 0), new Point(2, 0));
            BoxPrimitive stoneCube       = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(4, 2), new Point(1, 0), new Point(4, 2));
            BoxPrimitive sandCube        = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(1, 1), new Point(1, 1), new Point(1, 1));
            BoxPrimitive ironCube        = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(4, 1), new Point(1, 2), new Point(4, 1));
            BoxPrimitive goldCube        = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(3, 1), new Point(0, 2), new Point(3, 1));
            BoxPrimitive coalCube        = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(3, 2), new Point(2, 2), new Point(2, 2));
            BoxPrimitive manaCube        = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(7, 1), new Point(6, 1), new Point(7, 1));
            BoxPrimitive frostCube       = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(0, 1), new Point(2, 1), new Point(2, 0));
            BoxPrimitive scaffoldCube    = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(7, 0), new Point(7, 0), new Point(7, 0));
            BoxPrimitive plankCube       = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(4, 0), new Point(4, 0), new Point(4, 0));
            BoxPrimitive waterCube       = CreatePrimitive(graphics, cubeTexture, cubeTexture.Width, cubeTexture.Height, new Point(0, 0), new Point(0, 0), new Point(0, 0));
            BoxPrimitive cobblestoneCube = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(5, 2), new Point(5, 2), new Point(5, 2));
            BoxPrimitive magicCube       = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(0, 10), new Point(0, 10), new Point(0, 10));
            BoxPrimitive bedrockCube     = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(6, 2), new Point(6, 2), new Point(6, 2));
            BoxPrimitive brownTileCube   = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(5, 0), new Point(5, 0), new Point(5, 0));
            BoxPrimitive blueTileCube    = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(6, 0), new Point(6, 0), new Point(6, 0));
            BoxPrimitive tilledSoilCube  = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(5, 1), new Point(2, 0), new Point(2, 0));

            emptyType = new VoxelType
            {
                Name             = "empty",
                ReleasesResource = false,
                IsBuildable      = false
            };

            VoxelType tilledSoil = new VoxelType
            {
                Name             = "TilledSoil",
                ReleasesResource = false,
                StartingHealth   = 20,
                CanRamp          = true,
                IsBuildable      = false,
                ParticleType     = "dirt_particle",
                IsSoil           = true
            };

            RegisterType(tilledSoil, tilledSoilCube);

            VoxelType brownTileFloor = new VoxelType
            {
                Name             = "BrownTileFloor",
                ReleasesResource = false,
                StartingHealth   = 20,
                CanRamp          = false,
                IsBuildable      = false,
                ParticleType     = "stone_particle"
            };

            RegisterType(brownTileFloor, brownTileCube);

            VoxelType blueTileFloor = new VoxelType
            {
                Name             = "BlueTileFloor",
                ReleasesResource = false,
                StartingHealth   = 20,
                CanRamp          = false,
                IsBuildable      = false,
                ParticleType     = "stone_particle"
            };

            RegisterType(blueTileFloor, blueTileCube);

            VoxelType cobblestoneFloor = new VoxelType
            {
                Name                  = "CobblestoneFloor",
                ReleasesResource      = false,
                StartingHealth        = 20,
                CanRamp               = false,
                IsBuildable           = false,
                ParticleType          = "stone_particle",
                HasTransitionTextures = true
            };

            RegisterType(cobblestoneFloor, cobblestoneCube);
            CreateTransitionUVs(graphics, cubeTexture, 32, 32, new Point(0, 8), new Point(5, 2), new Point(5, 2), cobblestoneFloor.TransitionTextures);

            VoxelType stockpileType = new VoxelType
            {
                Name                  = "Stockpile",
                ReleasesResource      = false,
                StartingHealth        = 20,
                CanRamp               = false,
                IsBuildable           = false,
                ParticleType          = "stone_particle",
                HasTransitionTextures = true
            };

            RegisterType(stockpileType, plankCube);

            CreateTransitionUVs(graphics, cubeTexture, 32, 32, new Point(0, 9), new Point(4, 0), new Point(4, 0), stockpileType.TransitionTextures);

            VoxelType plankType = new VoxelType
            {
                Name = "Plank",
                ProbabilityOfRelease = 1.0f,
                ResourceToRelease    = ResourceLibrary.ResourceType.Wood,
                StartingHealth       = 20,
                ReleasesResource     = true,
                CanRamp               = true,
                RampSize              = 0.5f,
                IsBuildable           = true,
                ParticleType          = "stone_particle",
                HasTransitionTextures = true
            };


            CreateTransitionUVs(graphics, cubeTexture, 32, 32, new Point(0, 9), new Point(4, 0), new Point(4, 0), plankType.TransitionTextures);

            VoxelType magicType = new VoxelType
            {
                Name = "Magic",
                ProbabilityOfRelease = 0.0f,
                ResourceToRelease    = ResourceLibrary.ResourceType.Mana,
                StartingHealth       = 1,
                ReleasesResource     = true,
                CanRamp               = false,
                IsBuildable           = false,
                ParticleType          = "star_particle",
                ExplosionSound        = ContentPaths.Audio.wurp,
                HasTransitionTextures = false,
                EmitsLight            = true
            };


            CreateTransitionUVs(graphics, cubeTexture, 32, 32, new Point(0, 10), new Point(15, 10), new Point(15, 10), magicType.TransitionTextures);


            VoxelType scaffoldType = new VoxelType
            {
                Name                 = "Scaffold",
                StartingHealth       = 20,
                ProbabilityOfRelease = 1.0f,
                ResourceToRelease    = ResourceLibrary.ResourceType.Wood,
                ReleasesResource     = false,
                CanRamp              = false,
                RampSize             = 0.5f,
                IsBuildable          = true,
                ParticleType         = "stone_particle"
            };

            VoxelType grassType = new VoxelType
            {
                Name = "Grass",
                ProbabilityOfRelease = 0.1f,
                ResourceToRelease    = ResourceLibrary.ResourceType.Dirt,
                StartingHealth       = 10,
                ReleasesResource     = true,
                CanRamp               = true,
                RampSize              = 0.5f,
                IsBuildable           = false,
                ParticleType          = "dirt_particle",
                HasTransitionTextures = true,
                IsSoil = true
            };

            CreateTransitionUVs(graphics, cubeTexture, 32, 32, new Point(0, 3), new Point(2, 0), new Point(2, 0), grassType.TransitionTextures);



            VoxelType frostType = new VoxelType
            {
                Name = "Frost",
                ProbabilityOfRelease = 0.1f,
                ResourceToRelease    = ResourceLibrary.ResourceType.Dirt,
                StartingHealth       = 10,
                ReleasesResource     = true,
                CanRamp               = true,
                RampSize              = 0.5f,
                IsBuildable           = false,
                ParticleType          = "dirt_particle",
                HasTransitionTextures = true
            };

            CreateTransitionUVs(graphics, cubeTexture, 32, 32, new Point(0, 4), new Point(2, 0), new Point(2, 0), frostType.TransitionTextures);


            VoxelType desertGrass = new VoxelType
            {
                Name = "DesertGrass",
                ProbabilityOfRelease = 0.1f,
                ResourceToRelease    = ResourceLibrary.ResourceType.Sand,
                StartingHealth       = 10,
                ReleasesResource     = true,
                CanRamp               = true,
                RampSize              = 0.5f,
                IsBuildable           = false,
                ParticleType          = "sand_particle",
                HasTransitionTextures = true
            };

            CreateTransitionUVs(graphics, cubeTexture, 32, 32, new Point(0, 6), new Point(1, 1), new Point(1, 1), desertGrass.TransitionTextures);

            VoxelType jungleGrass = new VoxelType
            {
                Name = "JungleGrass",
                ProbabilityOfRelease = 0.1f,
                ResourceToRelease    = ResourceLibrary.ResourceType.Dirt,
                StartingHealth       = 10,
                ReleasesResource     = true,
                CanRamp               = true,
                RampSize              = 0.5f,
                IsBuildable           = false,
                ParticleType          = "dirt_particle",
                HasTransitionTextures = true
            };

            CreateTransitionUVs(graphics, cubeTexture, 32, 32, new Point(0, 5), new Point(2, 0), new Point(2, 0), jungleGrass.TransitionTextures);


            VoxelType dirtType = new VoxelType
            {
                Name                 = "Dirt",
                ReleasesResource     = true,
                ResourceToRelease    = ResourceLibrary.ResourceType.Dirt,
                ProbabilityOfRelease = 0.3f,
                StartingHealth       = 10,
                RampSize             = 0.5f,
                CanRamp              = true,
                IsBuildable          = true,
                ParticleType         = "dirt_particle",
                IsSoil               = true
            };

            VoxelType stoneType = new VoxelType
            {
                Name = "Stone",
                ProbabilityOfRelease = 0.5f,
                ReleasesResource     = true,
                ResourceToRelease    = ResourceLibrary.ResourceType.Stone,
                StartingHealth       = 30,
                IsBuildable          = true,
                ParticleType         = "stone_particle"
            };

            VoxelType bedrockType = new VoxelType
            {
                Name           = "Bedrock",
                StartingHealth = 255,
                IsBuildable    = false,
                IsInvincible   = true
            };

            VoxelType waterType = new VoxelType
            {
                Name             = "water",
                ReleasesResource = false,
                IsBuildable      = false,
                StartingHealth   = 255
            };

            VoxelType sandType = new VoxelType
            {
                Name             = "Sand",
                ReleasesResource = false,
                StartingHealth   = 5,
                CanRamp          = true,
                RampSize         = 0.5f,
                IsBuildable      = false,
                ParticleType     = "sand_particle"
            };

            VoxelType ironType = new VoxelType
            {
                Name = "Iron",
                ProbabilityOfRelease = 0.99f,
                ReleasesResource     = true,
                ResourceToRelease    = ResourceLibrary.ResourceType.Iron,
                StartingHealth       = 80,
                IsBuildable          = false,
                ParticleType         = "stone_particle"
            };

            ResourceSpawns["Iron"] = new ResourceSpawnRate
            {
                VeinSize           = 0.2f,
                VeinSpawnThreshold = 0.9f,
                MinimumHeight      = -100,
                MaximumHeight      = 100,
                Probability        = 0.5f
            };

            VoxelType coalType = new VoxelType
            {
                Name = "Coal",
                ProbabilityOfRelease = 0.99f,
                ReleasesResource     = true,
                ResourceToRelease    = ResourceLibrary.ResourceType.Coal,
                StartingHealth       = 75,
                IsBuildable          = false,
                ParticleType         = "stone_particle"
            };

            ResourceSpawns["Coal"] = new ResourceSpawnRate
            {
                VeinSize           = 0.085f,
                VeinSpawnThreshold = 0.9f,
                MinimumHeight      = -100,
                MaximumHeight      = 100,
                Probability        = 0.5f
            };


            VoxelType goldType = new VoxelType
            {
                Name = "Gold",
                ProbabilityOfRelease = 1.0f,
                ReleasesResource     = true,
                ResourceToRelease    = ResourceLibrary.ResourceType.Gold,
                StartingHealth       = 90,
                IsBuildable          = false,
                ParticleType         = "stone_particle"
            };

            ResourceSpawns["Gold"] = new ResourceSpawnRate
            {
                VeinSize           = 0.07f,
                VeinSpawnThreshold = 0.8f,
                MinimumHeight      = -150,
                MaximumHeight      = 15,
                Probability        = 0.6f
            };

            VoxelType manaType = new VoxelType
            {
                Name = "Mana",
                ProbabilityOfRelease = 1.0f,
                ReleasesResource     = true,
                ResourceToRelease    = ResourceLibrary.ResourceType.Mana,
                StartingHealth       = 200,
                IsBuildable          = false,
                ParticleType         = "stone_particle"
            };

            ResourceSpawns["Mana"] = new ResourceSpawnRate
            {
                VeinSize           = 0.05f,
                VeinSpawnThreshold = 0.85f,
                MinimumHeight      = -800,
                MaximumHeight      = 8,
                Probability        = 0.5f
            };

            RegisterType(grassType, grassCube);
            RegisterType(frostType, frostCube);
            RegisterType(desertGrass, grassCube);
            RegisterType(jungleGrass, grassCube);
            RegisterType(emptyType, null);
            RegisterType(dirtType, dirtCube);
            RegisterType(stoneType, stoneCube);
            RegisterType(waterType, waterCube);
            RegisterType(sandType, sandCube);
            RegisterType(ironType, ironCube);
            RegisterType(goldType, goldCube);
            RegisterType(manaType, manaCube);
            RegisterType(plankType, plankCube);
            RegisterType(scaffoldType, scaffoldCube);
            RegisterType(bedrockType, bedrockCube);
            RegisterType(coalType, coalCube);
            RegisterType(magicType, magicCube);

            foreach (VoxelType type in VoxelType.TypeList)
            {
                Types[type.Name] = type;
            }
        }
Ejemplo n.º 4
0
 public static void RegisterType(VoxelType type, BoxPrimitive primitive)
 {
     PrimitiveMap[type] = primitive;
 }
Ejemplo n.º 5
0
        private static void BuildVoxelTopFaceGeometry(
            RawPrimitive Into,
            VoxelChunk Chunk,
            Cache Cache,
            BoxPrimitive Primitive,
            VoxelHandle V,
            BoxPrimitive.BoxTextureCoords UVs)
        {
            if (!IsFaceVisible(V, BoxFace.Top, Chunk.Manager, out var _))
            {
                return;
            }

            var faceDescriptor = Primitive.GetFace(BoxFace.Top);
            int exploredVerts  = 0;
            var vertexColors   = new VertexColorInfo[4];
            var vertexTint     = new Color[4];

            // Find all verticies to use for geometry later, and for the fringe
            var vertexPositions = new Vector3[4];

            for (int faceVertex = 0; faceVertex < faceDescriptor.VertexCount; faceVertex++)
            {
                var vertex      = Primitive.Vertices[faceDescriptor.VertexOffset + faceVertex];
                var voxelVertex = Primitive.VertexClassifications[faceDescriptor.VertexOffset + faceVertex];

                var rampOffset = Vector3.Zero;
                if (V.IsExplored && V.Type.CanRamp && ShouldRamp(voxelVertex, V.RampType))
                {
                    rampOffset = new Vector3(0, -0.5f, 0);
                }

                var worldPosition = V.WorldPosition + vertex.Position + rampOffset;
                //worldPosition += VertexNoise.GetNoiseVectorFromRepeatingTexture(worldPosition);

                vertexPositions[faceVertex] = worldPosition;
            }

            // Figure out if this vertex is adjacent to any explored voxel.
            if (V.IsExplored)
            {
                exploredVerts = 4;
            }
            else
            {
                for (int faceVertex = 0; faceVertex < faceDescriptor.VertexCount; ++faceVertex)
                {
                    var voxelVertex         = Primitive.VertexClassifications[faceDescriptor.VertexOffset + faceVertex];
                    var cacheKey            = GetCacheKey(V, voxelVertex);
                    var anyNeighborExplored = true;

                    if (!Cache.ExploredCache.TryGetValue(cacheKey, out anyNeighborExplored))
                    {
                        anyNeighborExplored = VoxelHelpers.EnumerateVertexNeighbors2D(V.Coordinate, voxelVertex)
                                              .Select(c => new VoxelHandle(V.Chunk.Manager, c))
                                              .Any(n => n.IsValid && n.IsExplored);
                        Cache.ExploredCache.Add(cacheKey, anyNeighborExplored);
                    }

                    if (anyNeighborExplored)
                    {
                        exploredVerts += 1;
                    }
                }
            }

            for (int faceVertex = 0; faceVertex < faceDescriptor.VertexCount; ++faceVertex)
            {
                var voxelVertex = Primitive.VertexClassifications[faceDescriptor.VertexOffset + faceVertex];
                var cacheKey    = GetCacheKey(V, voxelVertex);

                VertexColorInfo vertexColor;
                if (!Cache.LightCache.TryGetValue(cacheKey, out vertexColor))
                {
                    vertexColor = CalculateVertexLight(V, voxelVertex, Chunk.Manager);
                    Cache.LightCache.Add(cacheKey, vertexColor);
                }

                vertexColors[faceVertex] = vertexColor;

                vertexTint[faceVertex] = new Color(1.0f, 1.0f, 1.0f, 1.0f);

                // Turn face solid black if there are no explored neighbors - this is an optimization; it means we do not need to apply a solid black decal.
                if (exploredVerts != 4)
                {
                    var anyNeighborExplored = true;
                    if (!Cache.ExploredCache.TryGetValue(cacheKey, out anyNeighborExplored))
                    {
                        throw new InvalidProgramException("Failed cache lookup");
                    }

                    if (!anyNeighborExplored)
                    {
                        vertexTint[faceVertex] = new Color(0.0f, 0.0f, 0.0f, 1.0f);
                    }
                }

                vertexTint[faceVertex] = new Color(vertexTint[faceVertex].ToVector4() * V.Type.Tint.ToVector4());
            }

            if (exploredVerts != 0)
            {
                var baseUVs = UVs.Uvs[11]; // EW

                var baseUVBounds = new Vector4(baseUVs.X + 0.001f, baseUVs.Y + 0.001f, baseUVs.X + (1.0f / 16.0f) - 0.001f, baseUVs.Y + (1.0f / 16.0f) - 0.001f);

                // Draw the base voxel
                AddTopFaceGeometry(Into,
                                   Cache.AmbientValues, Primitive,
                                   faceDescriptor,
                                   vertexPositions,
                                   vertexColors,
                                   vertexTint,
                                   Vector2.One,
                                   baseUVs, baseUVBounds);

                if (V.GrassType != 0)
                {
                    BuildGrassFringeGeometry(Into, Chunk, Cache, Primitive, V, vertexColors, vertexTint, vertexPositions, faceDescriptor);
                }

                if (V.DecalType != 0)
                {
                    BuildDecalGeometry(Into, Chunk, Cache, Primitive, V, vertexColors, vertexTint, vertexPositions, faceDescriptor, exploredVerts);
                }
            }
            else
            {
                // Apparently being unexplored hides all grass and decals. Is that the behavior we actually want?

                if (!Debugger.Switches.HideSliceTop)
                {
                    var indexOffset = Into.VertexCount;

                    for (int faceVertex = 0; faceVertex < faceDescriptor.VertexCount; faceVertex++)
                    {
                        Into.AddVertex(new ExtendedVertex(
                                           vertexPositions[faceVertex] + VertexNoise.GetNoiseVectorFromRepeatingTexture(vertexPositions[faceVertex]),
                                           new Color(0, 0, 0, 255),
                                           new Color(0, 0, 0, 255),
                                           new Vector2(12.5f / 16.0f, 0.5f / 16.0f),
                                           new Vector4(12.0f / 16.0f, 0.0f, 13.0f / 16.0f, 1.0f / 16.0f)));
                    }

                    for (int idx = faceDescriptor.IndexOffset; idx < faceDescriptor.IndexCount +
                         faceDescriptor.IndexOffset; idx++)
                    {
                        ushort offset  = Primitive.Indexes[idx];
                        ushort offset0 = Primitive.Indexes[faceDescriptor.IndexOffset];
                        Into.AddIndex((short)(indexOffset + offset - offset0));
                    }
                }
            }
        }
Ejemplo n.º 6
0
        // Do not delete: Used to generate block icon texture for menu.
        public static Texture2D RenderIcons(GraphicsDevice device, Shader shader, ChunkManager chunks, int width, int height, int tileSize)
        {
            if (width == -1)
            {
                int sqrt = (int)(Math.Ceiling(Math.Sqrt(PrimitiveMap.Count)));
                width  = MathFunctions.NearestPowerOf2(sqrt * tileSize);
                height = MathFunctions.NearestPowerOf2(sqrt * tileSize);
            }

            RenderTarget2D toReturn = new RenderTarget2D(device, width, height, false, SurfaceFormat.Color, DepthFormat.Depth16, 16, RenderTargetUsage.PreserveContents);

            device.SetRenderTarget(toReturn);
            device.Clear(Color.Transparent);
            shader.SetIconTechnique();
            shader.MainTexture              = chunks.ChunkData.Tilemap;
            shader.SelfIlluminationEnabled  = true;
            shader.SelfIlluminationTexture  = chunks.ChunkData.IllumMap;
            shader.EnableShadows            = false;
            shader.EnableLighting           = false;
            shader.ClippingEnabled          = false;
            shader.CameraPosition           = new Vector3(-0.5f, 0.5f, 0.5f);
            shader.VertexColorTint          = Color.White;
            shader.LightRampTint            = Color.White;
            shader.SunlightGradient         = chunks.ChunkData.SunMap;
            shader.AmbientOcclusionGradient = chunks.ChunkData.AmbientMap;
            shader.TorchlightGradient       = chunks.ChunkData.TorchMap;
            Viewport         oldview      = device.Viewport;
            List <VoxelType> voxelsByType = Types.Select(type => type.Value).ToList();

            voxelsByType.Sort((a, b) => a.ID < b.ID ? -1 : 1);
            int rows = height / tileSize;
            int cols = width / tileSize;

            device.ScissorRectangle  = new Rectangle(0, 0, tileSize, tileSize);
            device.RasterizerState   = RasterizerState.CullNone;
            device.DepthStencilState = DepthStencilState.Default;
            Vector3 half = Vector3.One * 0.5f;

            half = new Vector3(half.X, half.Y, half.Z);
            foreach (EffectPass pass in shader.CurrentTechnique.Passes)
            {
                foreach (var type in voxelsByType)
                {
                    int          row       = type.ID / cols;
                    int          col       = type.ID % cols;
                    BoxPrimitive primitive = GetPrimitive(type);
                    if (primitive == null)
                    {
                        continue;
                    }

                    if (type.HasTransitionTextures)
                    {
                        primitive = new BoxPrimitive(device, 1, 1, 1, type.TransitionTextures[new BoxTransition()]);
                    }

                    device.Viewport = new Viewport(col * tileSize, row * tileSize, tileSize, tileSize);
                    Matrix viewMatrix       = Matrix.CreateLookAt(new Vector3(-1.2f, 1.0f, -1.5f), Vector3.Zero, Vector3.Up);
                    Matrix projectionMatrix = Matrix.CreateOrthographic(1.5f, 1.5f, 0, 5);
                    shader.View       = viewMatrix;
                    shader.Projection = projectionMatrix;
                    shader.World      = Matrix.CreateTranslation(-half);
                    pass.Apply();
                    primitive.Render(device);
                }
            }
            device.Viewport = oldview;
            return((Texture2D)toReturn);
        }
Ejemplo n.º 7
0
 public void GetRightFace(BoxPrimitive.BoxTextureCoords uvs, out int idx, out int count)
 {
     idx = 30;
     count = 6;
 }
Ejemplo n.º 8
0
        private static void BuildGrassFringeGeometry(
            RawPrimitive Into,
            VoxelChunk Chunk,
            Cache Cache,
            BoxPrimitive Primitive,
            VoxelHandle V,
            VertexColorInfo[] VertexColors,
            Color[] VertexTint,
            Vector3[] VertexPositions,
            BoxPrimitive.FaceDescriptor Face,
            int ExploredVerts)
        {
            if (V.GrassType == 0)
            {
                return;
            }

            var decalType = Library.GetGrassType(V.GrassType);

            AddGrassGeometry(Into, Cache.AmbientValues, Primitive, V, Face, ExploredVerts, VertexPositions, VertexColors, VertexTint, decalType);

            // Draw fringe
            if (decalType.FringeTransitionUVs == null)
            {
                return;
            }

            for (var s = 0; s < 4; ++s)
            {
                var neighborCoord = V.Coordinate + VoxelHelpers.ManhattanNeighbors2D[s];
                var neighbor      = new VoxelHandle(Chunk.Manager, neighborCoord);

                if (!neighbor.IsValid)
                {
                    continue;
                }

                var aboveNeighbor = new VoxelHandle(Chunk.Manager, neighborCoord + new GlobalVoxelOffset(0, 1, 0));

                if (!aboveNeighbor.IsValid || aboveNeighbor.IsEmpty)
                {
                    // Draw horizontal fringe.
                    if (!neighbor.IsEmpty)
                    {
                        if (neighbor.GrassType != 0 &&
                            Library.GetGrassType(neighbor.GrassType).FringePrecedence >= decalType.FringePrecedence)
                        {
                            continue;
                        }
                    }

                    // Twizzle vertex positions.
                    var newPositions = new Vector3[4];
                    newPositions[FringeIndicies[s, 0]] = VertexPositions[FringeIndicies[s, 4]];
                    newPositions[FringeIndicies[s, 1]] = VertexPositions[FringeIndicies[s, 4]]
                                                         + (VoxelHelpers.ManhattanNeighbors2D[s].AsVector3() * 0.5f);
                    newPositions[FringeIndicies[s, 2]] = VertexPositions[FringeIndicies[s, 5]]
                                                         + (VoxelHelpers.ManhattanNeighbors2D[s].AsVector3() * 0.5f);
                    newPositions[FringeIndicies[s, 3]] = VertexPositions[FringeIndicies[s, 5]];

                    var newColors = new VertexColorInfo[4];
                    newColors[FringeIndicies[s, 0]] = VertexColors[FringeIndicies[s, 4]];
                    newColors[FringeIndicies[s, 1]] = VertexColors[FringeIndicies[s, 4]];
                    newColors[FringeIndicies[s, 2]] = VertexColors[FringeIndicies[s, 5]];
                    newColors[FringeIndicies[s, 3]] = VertexColors[FringeIndicies[s, 5]];

                    var slopeTweak = new Vector3(0.0f, 0.0f, 0.0f);
                    if (neighbor.IsEmpty)
                    {
                        slopeTweak.Y = -0.5f;
                    }
                    else
                    {
                        slopeTweak.Y = 0.125f;
                    }

                    newPositions[FringeIndicies[s, 1]] += slopeTweak;
                    newPositions[FringeIndicies[s, 2]] += slopeTweak;

                    var newTints = new Color[4];
                    newTints[FringeIndicies[s, 0]] = VertexTint[FringeIndicies[s, 4]];
                    newTints[FringeIndicies[s, 1]] = VertexTint[FringeIndicies[s, 4]];
                    newTints[FringeIndicies[s, 2]] = VertexTint[FringeIndicies[s, 5]];
                    newTints[FringeIndicies[s, 3]] = VertexTint[FringeIndicies[s, 5]];

                    AddTopFaceGeometry(Into,
                                       Cache.AmbientValues, Primitive,
                                       Face,
                                       newPositions,
                                       newColors,
                                       newTints,
                                       SideFringeUVScales[s],
                                       decalType.FringeTransitionUVs[s].UV,
                                       decalType.FringeTransitionUVs[s].Bounds);
                }
                else
                {
                    // Draw vertical fringe!

                    var newPositions = new Vector3[4];
                    newPositions[FringeIndicies[s, 0]] = VertexPositions[FringeIndicies[s, 4]];
                    newPositions[FringeIndicies[s, 1]] = VertexPositions[FringeIndicies[s, 4]]
                                                         + new Vector3(0.0f, 0.5f, 0.0f)
                                                         + (VoxelHelpers.ManhattanNeighbors2D[s].AsVector3() * -0.05f);
                    newPositions[FringeIndicies[s, 2]] = VertexPositions[FringeIndicies[s, 5]]
                                                         + new Vector3(0.0f, 0.5f, 0.0f)
                                                         + (VoxelHelpers.ManhattanNeighbors2D[s].AsVector3() * -0.05f);
                    newPositions[FringeIndicies[s, 3]] = VertexPositions[FringeIndicies[s, 5]];

                    var newColors = new VertexColorInfo[4];
                    newColors[FringeIndicies[s, 0]] = VertexColors[FringeIndicies[s, 4]];
                    newColors[FringeIndicies[s, 1]] = VertexColors[FringeIndicies[s, 4]];
                    newColors[FringeIndicies[s, 2]] = VertexColors[FringeIndicies[s, 5]];
                    newColors[FringeIndicies[s, 3]] = VertexColors[FringeIndicies[s, 5]];

                    var newTints = new Color[4];
                    newTints[FringeIndicies[s, 0]] = VertexTint[FringeIndicies[s, 4]];
                    newTints[FringeIndicies[s, 1]] = VertexTint[FringeIndicies[s, 4]];
                    newTints[FringeIndicies[s, 2]] = VertexTint[FringeIndicies[s, 5]];
                    newTints[FringeIndicies[s, 3]] = VertexTint[FringeIndicies[s, 5]];

                    AddTopFaceGeometry(Into,
                                       Cache.AmbientValues, Primitive,
                                       Face,
                                       newPositions,
                                       newColors,
                                       newTints,
                                       SideFringeUVScales[s],
                                       decalType.FringeTransitionUVs[s].UV,
                                       decalType.FringeTransitionUVs[s].Bounds);
                }
            }

            for (var s = 0; s < 4; ++s)
            {
                var neighborCoord = V.Coordinate + VoxelHelpers.DiagonalNeighbors2D[s];
                var handle        = new VoxelHandle(Chunk.Manager, neighborCoord);

                if (handle.IsValid)
                {
                    if (!handle.IsEmpty)
                    {
                        if (handle.GrassType != 0 &&
                            Library.GetGrassType(handle.GrassType).FringePrecedence >= decalType.FringePrecedence)
                        {
                            continue;
                        }
                    }

                    var manhattanA = new VoxelHandle(Chunk.Manager, V.Coordinate + VoxelHelpers.ManhattanNeighbors2D[s]);
                    if (!manhattanA.IsValid || (manhattanA.GrassType == V.GrassType))
                    {
                        continue;
                    }

                    manhattanA = new VoxelHandle(Chunk.Manager, V.Coordinate + VoxelHelpers.ManhattanNeighbors2D[FringeIndicies[4 + s, 5]]);
                    if (!manhattanA.IsValid || (manhattanA.GrassType == V.GrassType))
                    {
                        continue;
                    }

                    // Twizzle vertex positions.
                    var newPositions = new Vector3[4];
                    var pivot        = VertexPositions[FringeIndicies[4 + s, 4]];
                    var nDelta       = VoxelHelpers.DiagonalNeighbors2D[s].AsVector3();

                    newPositions[FringeIndicies[4 + s, 0]] = pivot;
                    newPositions[FringeIndicies[4 + s, 1]] = pivot + new Vector3(nDelta.X * 0.5f, 0, 0);
                    newPositions[FringeIndicies[4 + s, 2]] = pivot + new Vector3(nDelta.X * 0.5f, 0, nDelta.Z * 0.5f);
                    newPositions[FringeIndicies[4 + s, 3]] = pivot + new Vector3(0, 0, nDelta.Z * 0.5f);

                    var slopeTweak = new Vector3(0.0f, 0.0f, 0.0f);
                    if (handle.IsEmpty)
                    {
                        slopeTweak.Y = -0.5f;
                    }
                    else
                    {
                        slopeTweak.Y = 0.125f;
                    }

                    newPositions[FringeIndicies[4 + s, 1]] += slopeTweak;
                    newPositions[FringeIndicies[4 + s, 2]] += slopeTweak;
                    newPositions[FringeIndicies[4 + s, 3]] += slopeTweak;

                    var newColors = new VertexColorInfo[4];
                    newColors[FringeIndicies[4 + s, 0]] = VertexColors[FringeIndicies[4 + s, 4]];
                    newColors[FringeIndicies[4 + s, 1]] = VertexColors[FringeIndicies[4 + s, 4]];
                    newColors[FringeIndicies[4 + s, 2]] = VertexColors[FringeIndicies[4 + s, 4]];
                    newColors[FringeIndicies[4 + s, 3]] = VertexColors[FringeIndicies[4 + s, 4]];

                    var newTints = new Color[4];
                    newTints[FringeIndicies[4 + s, 0]] = VertexTint[FringeIndicies[4 + s, 4]];
                    newTints[FringeIndicies[4 + s, 1]] = VertexTint[FringeIndicies[4 + s, 4]];
                    newTints[FringeIndicies[4 + s, 2]] = VertexTint[FringeIndicies[4 + s, 4]];
                    newTints[FringeIndicies[4 + s, 3]] = VertexTint[FringeIndicies[4 + s, 4]];

                    AddTopFaceGeometry(Into,
                                       Cache.AmbientValues, Primitive,
                                       Face,
                                       newPositions,
                                       newColors,
                                       newTints,
                                       new Vector2(0.5f, 0.5f),
                                       decalType.FringeTransitionUVs[4 + s].UV,
                                       decalType.FringeTransitionUVs[4 + s].Bounds);
                }
            }
        }
Ejemplo n.º 9
0
 public void GetFace(BoxFace face, BoxPrimitive.BoxTextureCoords uvs, out int index, out int count)
 {
     switch (face)
     {
         case BoxFace.Back:
             GetBackFace(uvs, out index, out count);
             return;
         case BoxFace.Front:
             GetFrontFace(uvs, out index, out count);
             return;
         case BoxFace.Left:
             GetLeftFace(uvs, out index, out count);
             return;
         case BoxFace.Right:
             GetRightFace(uvs, out index, out count);
             return;
         case BoxFace.Top:
             GetTopFace(uvs, out index, out count);
             return;
         case BoxFace.Bottom:
             GetBottomFace(uvs, out index, out count);
             return;
     }
     index = 0;
     count = 0;
 }
Ejemplo n.º 10
0
 public void GetLeftFace(BoxPrimitive.BoxTextureCoords uvs, out int idx, out int count)
 {
     idx = 24;
     count = 6;
 }
Ejemplo n.º 11
0
 public void GetBottomFace(BoxPrimitive.BoxTextureCoords uvs, out int idx, out int count)
 {
     idx = 18;
     count = 6;
 }
Ejemplo n.º 12
0
        private static void BuildVoxelGeometryFromPrimitive(RawPrimitive Into, VoxelChunk Chunk, Cache Cache, VoxelHandle v, BoxPrimitive primitive)
        {
            var tint = v.Type.Tint;

            var uvs = primitive.UVs;

            if (v.Type.HasTransitionTextures && v.IsExplored)
            {
                uvs = ComputeTransitionTexture(new VoxelHandle(v.Chunk.Manager, v.Coordinate));
            }

            BuildVoxelTopFaceGeometry(Into, Chunk, Cache, primitive, v, uvs, 0);

            for (int i = 1; i < 6; i++)
            {
                BuildVoxelFaceGeometry(Into, Chunk, Cache, primitive, v, tint, uvs, Matrix.Identity, i, true);
            }
        }
Ejemplo n.º 13
0
        public void InitializeFromChunk(VoxelChunk chunk)
        {
            if (chunk == null)
            {
                return;
            }

            BoxPrimitive bedrockModel = VoxelLibrary.GetPrimitive("Bedrock");
            var          sliceStack   = new List <RawPrimitive>();
            var          cache        = new Cache();

            for (var y = 0; y < chunk.Manager.ChunkData.MaxViewingLevel; ++y)
            {
                RawPrimitive sliceGeometry = null;

                lock (chunk.Data.SliceCache)
                {
                    var cachedSlice = chunk.Data.SliceCache[y];

                    if (chunk.Data.VoxelsPresentInSlice[y] == 0)
                    {
                        cache.Clear();

                        if (cachedSlice != null)
                        {
                            chunk.Data.SliceCache[y] = null;
                        }
                        continue;
                    }

                    if (cachedSlice != null)
                    {
                        cache.Clear();

                        sliceStack.Add(cachedSlice);

                        if (GameSettings.Default.GrassMotes)
                        {
                            chunk.RebuildMoteLayerIfNull(y);
                        }

                        continue;
                    }

                    sliceGeometry = new RawPrimitive
                    {
                        Vertices = new ExtendedVertex[128],
                        Indexes  = new short[128]
                    };

                    chunk.Data.SliceCache[y] = sliceGeometry;
                }

                if (GameSettings.Default.CalculateRamps)
                {
                    UpdateCornerRamps(chunk, y);
                    UpdateNeighborEdgeRamps(chunk, y);
                }

                if (GameSettings.Default.GrassMotes)
                {
                    chunk.RebuildMoteLayer(y);
                }

                BuildSliceGeometry(chunk, bedrockModel, cache, y, sliceGeometry);

                sliceStack.Add(sliceGeometry);
            }

            var combinedGeometry = RawPrimitive.Concat(sliceStack);

            Vertices    = combinedGeometry.Vertices;
            VertexCount = combinedGeometry.VertexCount;
            Indexes     = combinedGeometry.Indexes.Select(s => (ushort)s).ToArray();
            IndexCount  = combinedGeometry.IndexCount;

            chunk.PrimitiveMutex.WaitOne();
            chunk.NewPrimitive         = this;
            chunk.NewPrimitiveReceived = true;
            chunk.PrimitiveMutex.ReleaseMutex();
        }
Ejemplo n.º 14
0
        private static void BuildVoxelFaceGeometry(
            RawPrimitive Into,
            VoxelChunk Chunk,
            Cache Cache,
            BoxPrimitive Primitive,
            VoxelHandle V,
            Color Tint,
            BoxPrimitive.BoxTextureCoords UVs,
            Matrix VertexTransform,
            int i,
            bool ApplyLighting)
        {
            var face  = (BoxFace)i;
            var delta = FaceDeltas[i];

            var faceVoxel = new VoxelHandle(Chunk.Manager, V.Coordinate + GlobalVoxelOffset.FromVector3(delta));

            if (!IsFaceVisible(V, faceVoxel, face))
            {
                return;
            }

            var faceDescriptor = Primitive.GetFace(face);
            var indexOffset    = Into.VertexCount;

            for (int faceVertex = 0; faceVertex < faceDescriptor.VertexCount; faceVertex++)
            {
                var vertex      = Primitive.Vertices[faceDescriptor.VertexOffset + faceVertex];
                var voxelVertex = Primitive.Deltas[faceDescriptor.VertexOffset + faceVertex];
                var vertexColor = new VertexColorInfo
                {
                    SunColor     = 255,
                    AmbientColor = 255,
                    DynamicColor = 255,
                };

                if (ApplyLighting)
                {
                    var cacheKey = GetCacheKey(V, voxelVertex);

                    if (!Cache.LightCache.TryGetValue(cacheKey, out vertexColor))
                    {
                        vertexColor = CalculateVertexLight(V, voxelVertex, Chunk.Manager);
                        Cache.LightCache.Add(cacheKey, vertexColor);
                    }

                    Cache.AmbientValues[faceVertex] = vertexColor.AmbientColor;
                }

                var rampOffset = Vector3.Zero;
                if (V.IsExplored && V.Type.CanRamp && ShouldRamp(voxelVertex, V.RampType))
                {
                    rampOffset = new Vector3(0, -V.Type.RampSize, 0);
                }

                var baseWorldPosition = V.WorldPosition + vertex.Position + rampOffset;
                var noise             = VertexNoise.GetNoiseVectorFromRepeatingTexture(baseWorldPosition);
                var localPosition     = Vector3.Transform(vertex.Position + rampOffset + noise, VertexTransform);

                Into.AddVertex(new ExtendedVertex(
                                   V.WorldPosition + localPosition,
                                   vertexColor.AsColor(),
                                   Tint,
                                   UVs.Uvs[faceDescriptor.VertexOffset + faceVertex],
                                   UVs.Bounds[faceDescriptor.IndexOffset / 6]));
            }

            bool flippedQuad = ApplyLighting && (Cache.AmbientValues[0] + Cache.AmbientValues[2] >
                                                 Cache.AmbientValues[1] + Cache.AmbientValues[3]);

            for (int idx = faceDescriptor.IndexOffset; idx < faceDescriptor.IndexCount +
                 faceDescriptor.IndexOffset; idx++)
            {
                ushort offset  = flippedQuad ? Primitive.FlippedIndexes[idx] : Primitive.Indexes[idx];
                ushort offset0 = flippedQuad ? Primitive.FlippedIndexes[faceDescriptor.IndexOffset] : Primitive.Indexes[faceDescriptor.IndexOffset];
                Into.AddIndex((short)(indexOffset + offset - offset0));
            }
        }
Ejemplo n.º 15
0
 public void GetTopFace(BoxPrimitive.BoxTextureCoords uvs, out int idx, out int count)
 {
     idx = 12;
     count = 6;
 }
Ejemplo n.º 16
0
        private static void BuildVoxelTopFaceGeometry(
            RawPrimitive Into,
            VoxelChunk Chunk,
            Cache Cache,
            BoxPrimitive Primitive,
            VoxelHandle V,
            BoxPrimitive.BoxTextureCoords UVs,
            int i)
        {
            var face  = (BoxFace)i;
            var delta = FaceDeltas[i];

            var faceVoxel = new VoxelHandle(Chunk.Manager, V.Coordinate + GlobalVoxelOffset.FromVector3(delta));

            if (!IsFaceVisible(V, faceVoxel, face))
            {
                return;
            }

            var faceDescriptor = Primitive.GetFace(face);
            int exploredVerts  = 0;
            var vertexColors   = new VertexColorInfo[4];
            var vertexTint     = new Color[4];

            // Find all verticies to use for geometry later, and for the fringe
            var vertexPositions = new Vector3[4];

            for (int faceVertex = 0; faceVertex < faceDescriptor.VertexCount; faceVertex++)
            {
                var vertex      = Primitive.Vertices[faceDescriptor.VertexOffset + faceVertex];
                var voxelVertex = Primitive.Deltas[faceDescriptor.VertexOffset + faceVertex];

                var rampOffset = Vector3.Zero;
                if (V.IsExplored && V.Type.CanRamp && ShouldRamp(voxelVertex, V.RampType))
                {
                    rampOffset = new Vector3(0, -V.Type.RampSize, 0);
                }

                var worldPosition = V.WorldPosition + vertex.Position + rampOffset;
                //worldPosition += VertexNoise.GetNoiseVectorFromRepeatingTexture(worldPosition);

                vertexPositions[faceVertex] = worldPosition;
            }

            if (V.IsExplored)
            {
                exploredVerts = 4;
            }
            else
            {
                for (int faceVertex = 0; faceVertex < faceDescriptor.VertexCount; ++faceVertex)
                {
                    var  voxelVertex         = Primitive.Deltas[faceDescriptor.VertexOffset + faceVertex];
                    var  cacheKey            = GetCacheKey(V, voxelVertex);
                    bool anyNeighborExplored = true;

                    if (!Cache.ExploredCache.TryGetValue(cacheKey, out anyNeighborExplored))
                    {
                        anyNeighborExplored = VoxelHelpers.EnumerateVertexNeighbors2D(V.Coordinate, voxelVertex)
                                              .Select(c => new VoxelHandle(V.Chunk.Manager, c))
                                              .Any(n => n.IsValid && n.IsExplored);
                        Cache.ExploredCache.Add(cacheKey, anyNeighborExplored);
                    }


                    if (anyNeighborExplored)
                    {
                        exploredVerts += 1;
                    }
                }
            }

            for (int faceVertex = 0; faceVertex < faceDescriptor.VertexCount; ++faceVertex)
            {
                var voxelVertex = Primitive.Deltas[faceDescriptor.VertexOffset + faceVertex];
                var cacheKey    = GetCacheKey(V, voxelVertex);

                VertexColorInfo vertexColor;
                if (!Cache.LightCache.TryGetValue(cacheKey, out vertexColor))
                {
                    vertexColor = CalculateVertexLight(V, voxelVertex, Chunk.Manager);
                    Cache.LightCache.Add(cacheKey, vertexColor);
                }

                vertexColors[faceVertex] = vertexColor;

                vertexTint[faceVertex] = new Color(1.0f, 1.0f, 1.0f, 1.0f);
                if (exploredVerts != 4)
                {
                    bool anyNeighborExplored = true;
                    if (!Cache.ExploredCache.TryGetValue(cacheKey, out anyNeighborExplored))
                    {
                        throw new InvalidProgramException("Failed cache lookup");
                    }

                    if (!anyNeighborExplored)
                    {
                        vertexTint[faceVertex] = new Color(0.0f, 0.0f, 0.0f, 1.0f);
                    }
                }

                vertexTint[faceVertex] = new Color(vertexTint[faceVertex].ToVector4() * V.Type.Tint.ToVector4());
            }

            if (exploredVerts != 0)
            {
                var baseUVs = UVs.Uvs[11]; // EW

                var baseUVBounds = new Vector4(baseUVs.X + 0.001f, baseUVs.Y + 0.001f, baseUVs.X + (1.0f / 16.0f) - 0.001f, baseUVs.Y + (1.0f / 16.0f) - 0.001f);

                // Draw central top tile.
                AddTopFaceGeometry(Into,
                                   Cache.AmbientValues, Primitive,
                                   faceDescriptor,
                                   vertexPositions,
                                   vertexColors,
                                   vertexTint,
                                   Vector2.One,
                                   baseUVs, baseUVBounds);

                if (V.GrassType != 0)
                {
                    BuildGrassFringeGeometry(Into, Chunk, Cache, Primitive, V, vertexColors,
                                             vertexTint, vertexPositions, faceDescriptor, exploredVerts);
                }
            }
            else
            {
                if (!Debugger.Switches.HideSliceTop)
                {
                    var indexOffset = Into.VertexCount;

                    for (int faceVertex = 0; faceVertex < faceDescriptor.VertexCount; faceVertex++)
                    {
                        Into.AddVertex(new ExtendedVertex(
                                           vertexPositions[faceVertex] + VertexNoise.GetNoiseVectorFromRepeatingTexture(vertexPositions[faceVertex]),
                                           new Color(0, 0, 0, 255),
                                           new Color(0, 0, 0, 255),
                                           new Vector2(12.5f / 16.0f, 0.5f / 16.0f),
                                           new Vector4(12.0f / 16.0f, 0.0f, 13.0f / 16.0f, 1.0f / 16.0f)));
                    }

                    for (int idx = faceDescriptor.IndexOffset; idx < faceDescriptor.IndexCount +
                         faceDescriptor.IndexOffset; idx++)
                    {
                        ushort offset  = Primitive.Indexes[idx];
                        ushort offset0 = Primitive.Indexes[faceDescriptor.IndexOffset];
                        Into.AddIndex((short)(indexOffset + offset - offset0));
                    }
                }
            }
        }
Ejemplo n.º 17
0
 public void GetFace(BoxFace face, BoxPrimitive.BoxTextureCoords uvs, out int index, out int count, out int vertexOffset, out int vertexCount)
 {
     vertexCount = 4;
     count = 6;
     vertexOffset = 0;
     switch (face)
     {
         case BoxFace.Back:
             index = 6;
             vertexOffset = 4;
             return;
         case BoxFace.Front:
             index = 0;
             vertexOffset = 0;
             return;
         case BoxFace.Left:
             index = 24;
             vertexOffset = 16;
             return;
         case BoxFace.Right:
             index = 30;
             vertexOffset = 20;
             return;
         case BoxFace.Top:
             index = 12;
             vertexOffset = 8;
             return;
         case BoxFace.Bottom:
             index = 18;
             vertexOffset = 12;
             return;
     }
     index = 0;
     count = 0;
 }
Ejemplo n.º 18
0
 public static void RegisterType(VoxelType type, BoxPrimitive primitive)
 {
     PrimitiveMap[type] = primitive;
 }
Ejemplo n.º 19
0
        public static void InitializeDefaultLibrary(GraphicsDevice graphics, Texture2D cubeTexture)
        {
            if (PrimitiveMap.Count > 0)
            {
                return;
            }

            BoxPrimitive grassCube       = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(0, 0), new Point(2, 0), new Point(2, 0));
            BoxPrimitive dirtCube        = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(2, 0), new Point(2, 0), new Point(2, 0));
            BoxPrimitive stoneCube       = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(4, 2), new Point(1, 0), new Point(4, 2));
            BoxPrimitive sandCube        = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(1, 1), new Point(1, 1), new Point(1, 1));
            BoxPrimitive ironCube        = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(4, 1), new Point(1, 2), new Point(4, 1));
            BoxPrimitive goldCube        = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(3, 1), new Point(0, 2), new Point(3, 1));
            BoxPrimitive coalCube        = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(3, 2), new Point(2, 2), new Point(2, 2));
            BoxPrimitive manaCube        = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(7, 1), new Point(6, 1), new Point(7, 1));
            BoxPrimitive frostCube       = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(0, 1), new Point(2, 1), new Point(2, 0));
            BoxPrimitive snowCube        = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(3, 7), new Point(3, 7), new Point(3, 7));
            BoxPrimitive iceCube         = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(2, 7), new Point(2, 7), new Point(2, 7));
            BoxPrimitive scaffoldCube    = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(7, 0), new Point(7, 0), new Point(7, 0));
            BoxPrimitive plankCube       = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(4, 0), new Point(4, 0), new Point(4, 0));
            BoxPrimitive waterCube       = CreatePrimitive(graphics, cubeTexture, cubeTexture.Width, cubeTexture.Height, new Point(0, 0), new Point(0, 0), new Point(0, 0));
            BoxPrimitive cobblestoneCube = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(5, 2), new Point(5, 2), new Point(5, 2));
            BoxPrimitive magicCube       = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(0, 10), new Point(0, 10), new Point(0, 10));
            BoxPrimitive bedrockCube     = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(6, 2), new Point(6, 2), new Point(6, 2));
            BoxPrimitive brownTileCube   = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(5, 0), new Point(5, 0), new Point(5, 0));
            BoxPrimitive blueTileCube    = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(6, 0), new Point(6, 0), new Point(6, 0));
            BoxPrimitive tilledSoilCube  = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(5, 1), new Point(2, 0), new Point(2, 0));

            BoxPrimitive redGemCube    = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(0, 11), new Point(0, 12), new Point(0, 11));
            BoxPrimitive orangeGemCube = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(1, 11), new Point(1, 12), new Point(1, 11));
            BoxPrimitive yellowGemCube = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(2, 11), new Point(2, 12), new Point(2, 11));
            BoxPrimitive greenGemCube  = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(3, 11), new Point(3, 12), new Point(3, 11));
            BoxPrimitive blueGemCube   = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(4, 11), new Point(4, 12), new Point(4, 11));
            BoxPrimitive purpleGemCube = CreatePrimitive(graphics, cubeTexture, 32, 32, new Point(5, 11), new Point(5, 12), new Point(5, 11));

            emptyType = new VoxelType
            {
                Name             = "empty",
                ReleasesResource = false,
                IsBuildable      = false
            };

            VoxelType tilledSoil = new VoxelType
            {
                Name             = "TilledSoil",
                ReleasesResource = false,
                StartingHealth   = 20,
                CanRamp          = true,
                IsBuildable      = false,
                ParticleType     = "dirt_particle",
                IsSoil           = true,
                IsSurface        = true
            };

            RegisterType(tilledSoil, tilledSoilCube);

            VoxelType brownTileFloor = new VoxelType
            {
                Name             = "BrownTileFloor",
                ReleasesResource = false,
                StartingHealth   = 20,
                CanRamp          = false,
                IsBuildable      = false,
                ParticleType     = "stone_particle"
            };

            RegisterType(brownTileFloor, brownTileCube);

            VoxelType blueTileFloor = new VoxelType
            {
                Name             = "BlueTileFloor",
                ReleasesResource = false,
                StartingHealth   = 20,
                CanRamp          = false,
                IsBuildable      = false,
                ParticleType     = "stone_particle"
            };

            RegisterType(blueTileFloor, blueTileCube);

            VoxelType cobblestoneFloor = new VoxelType
            {
                Name                  = "CobblestoneFloor",
                ReleasesResource      = false,
                StartingHealth        = 20,
                CanRamp               = false,
                IsBuildable           = false,
                ParticleType          = "stone_particle",
                HasTransitionTextures = true
            };

            RegisterType(cobblestoneFloor, cobblestoneCube);
            CreateTransitionUVs(graphics, cubeTexture, 32, 32, new Point(0, 8), new Point(5, 2), new Point(5, 2), cobblestoneFloor.TransitionTextures);

            VoxelType stockpileType = new VoxelType
            {
                Name                  = "Stockpile",
                ReleasesResource      = false,
                StartingHealth        = 20,
                CanRamp               = false,
                IsBuildable           = false,
                ParticleType          = "stone_particle",
                HasTransitionTextures = true
            };

            RegisterType(stockpileType, plankCube);

            CreateTransitionUVs(graphics, cubeTexture, 32, 32, new Point(0, 9), new Point(4, 0), new Point(4, 0), stockpileType.TransitionTextures);

            VoxelType plankType = new VoxelType
            {
                Name = "Plank",
                ProbabilityOfRelease = 1.0f,
                ResourceToRelease    = ResourceLibrary.ResourceType.Wood,
                StartingHealth       = 20,
                ReleasesResource     = true,
                CanRamp               = true,
                RampSize              = 0.5f,
                IsBuildable           = true,
                ParticleType          = "stone_particle",
                HasTransitionTextures = true
            };


            CreateTransitionUVs(graphics, cubeTexture, 32, 32, new Point(0, 9), new Point(4, 0), new Point(4, 0), plankType.TransitionTextures);

            VoxelType magicType = new VoxelType
            {
                Name = "Magic",
                ProbabilityOfRelease = 0.0f,
                ResourceToRelease    = ResourceLibrary.ResourceType.Mana,
                StartingHealth       = 1,
                ReleasesResource     = true,
                CanRamp               = false,
                IsBuildable           = false,
                ParticleType          = "star_particle",
                ExplosionSound        = ContentPaths.Audio.wurp,
                HasTransitionTextures = false,
                EmitsLight            = true
            };


            CreateTransitionUVs(graphics, cubeTexture, 32, 32, new Point(0, 10), new Point(15, 10), new Point(15, 10), magicType.TransitionTextures);


            VoxelType scaffoldType = new VoxelType
            {
                Name                 = "Scaffold",
                StartingHealth       = 20,
                ProbabilityOfRelease = 1.0f,
                ResourceToRelease    = ResourceLibrary.ResourceType.Wood,
                ReleasesResource     = false,
                CanRamp              = false,
                RampSize             = 0.5f,
                IsBuildable          = true,
                ParticleType         = "stone_particle"
            };

            VoxelType grassType = new VoxelType
            {
                Name = "Grass",
                ProbabilityOfRelease = 0.1f,
                ResourceToRelease    = ResourceLibrary.ResourceType.Dirt,
                StartingHealth       = 10,
                ReleasesResource     = true,
                CanRamp               = true,
                RampSize              = 0.5f,
                IsBuildable           = false,
                ParticleType          = "dirt_particle",
                HasTransitionTextures = true,
                IsSoil    = true,
                IsSurface = true
            };

            CreateTransitionUVs(graphics, cubeTexture, 32, 32, new Point(0, 3), new Point(2, 0), new Point(2, 0), grassType.TransitionTextures);



            VoxelType frostType = new VoxelType
            {
                Name = "Frost",
                ProbabilityOfRelease = 0.1f,
                ResourceToRelease    = ResourceLibrary.ResourceType.Dirt,
                StartingHealth       = 10,
                ReleasesResource     = true,
                CanRamp               = true,
                RampSize              = 0.5f,
                IsBuildable           = false,
                ParticleType          = "dirt_particle",
                HasTransitionTextures = true,
                IsSurface             = true
            };

            CreateTransitionUVs(graphics, cubeTexture, 32, 32, new Point(0, 4), new Point(2, 0), new Point(2, 0), frostType.TransitionTextures);

            VoxelType snowType = new VoxelType
            {
                Name                  = "Snow",
                StartingHealth        = 1,
                ReleasesResource      = false,
                CanRamp               = true,
                RampSize              = 0.5f,
                IsBuildable           = false,
                ParticleType          = "snow_particle",
                HasTransitionTextures = false,
                IsSurface             = true,
                IsSoil                = false
            };

            RegisterType(snowType, snowCube);

            VoxelType iceType = new VoxelType
            {
                Name                  = "Ice",
                StartingHealth        = 1,
                ReleasesResource      = false,
                CanRamp               = false,
                IsBuildable           = false,
                ParticleType          = "snow_particle",
                HasTransitionTextures = false,
                IsSurface             = true,
                IsSoil                = false
            };

            RegisterType(iceType, iceCube);


            VoxelType desertGrass = new VoxelType
            {
                Name = "DesertGrass",
                ProbabilityOfRelease = 0.1f,
                ResourceToRelease    = ResourceLibrary.ResourceType.Sand,
                StartingHealth       = 20,
                ReleasesResource     = true,
                CanRamp               = true,
                RampSize              = 0.5f,
                IsBuildable           = false,
                ParticleType          = "sand_particle",
                HasTransitionTextures = true,
                IsSurface             = true,
                IsSoil = true
            };

            CreateTransitionUVs(graphics, cubeTexture, 32, 32, new Point(0, 6), new Point(1, 1), new Point(1, 1), desertGrass.TransitionTextures);

            VoxelType jungleGrass = new VoxelType
            {
                Name = "JungleGrass",
                ProbabilityOfRelease = 0.1f,
                ResourceToRelease    = ResourceLibrary.ResourceType.Dirt,
                StartingHealth       = 30,
                ReleasesResource     = true,
                CanRamp               = true,
                RampSize              = 0.5f,
                IsBuildable           = false,
                ParticleType          = "dirt_particle",
                HasTransitionTextures = true,
                IsSurface             = true,
                IsSoil = true
            };

            CreateTransitionUVs(graphics, cubeTexture, 32, 32, new Point(0, 5), new Point(2, 0), new Point(2, 0), jungleGrass.TransitionTextures);


            VoxelType caveFungus = new VoxelType
            {
                Name = "CaveFungus",
                ProbabilityOfRelease = 0.25f,
                ResourceToRelease    = ResourceLibrary.ResourceType.Stone,
                StartingHealth       = 30,
                ReleasesResource     = true,
                CanRamp               = false,
                RampSize              = 0.5f,
                IsBuildable           = false,
                ParticleType          = "stone_particle",
                HasTransitionTextures = true,
                IsSurface             = false,
                IsSoil = true
            };

            CreateTransitionUVs(graphics, cubeTexture, 32, 32, new Point(0, 13), new Point(1, 0), new Point(1, 0), caveFungus.TransitionTextures);


            VoxelType dirtType = new VoxelType
            {
                Name                 = "Dirt",
                ReleasesResource     = true,
                ResourceToRelease    = ResourceLibrary.ResourceType.Dirt,
                ProbabilityOfRelease = 0.3f,
                StartingHealth       = 10,
                RampSize             = 0.5f,
                CanRamp              = true,
                IsBuildable          = true,
                ParticleType         = "dirt_particle",
                IsSoil               = true
            };

            VoxelType stoneType = new VoxelType
            {
                Name = "Stone",
                ProbabilityOfRelease = 0.5f,
                ReleasesResource     = true,
                ResourceToRelease    = ResourceLibrary.ResourceType.Stone,
                StartingHealth       = 40,
                IsBuildable          = true,
                ParticleType         = "stone_particle"
            };

            VoxelType bedrockType = new VoxelType
            {
                Name           = "Bedrock",
                StartingHealth = 255,
                IsBuildable    = false,
                IsInvincible   = true
            };

            VoxelType waterType = new VoxelType
            {
                Name             = "water",
                ReleasesResource = false,
                IsBuildable      = false,
                StartingHealth   = 255
            };

            VoxelType sandType = new VoxelType
            {
                Name                 = "Sand",
                ReleasesResource     = true,
                StartingHealth       = 15,
                CanRamp              = true,
                RampSize             = 0.5f,
                IsBuildable          = false,
                ParticleType         = "sand_particle",
                IsSurface            = true,
                ResourceToRelease    = ResourceLibrary.ResourceType.Sand,
                ProbabilityOfRelease = 0.5f
            };

            VoxelType ironType = new VoxelType
            {
                Name = "Iron",
                ProbabilityOfRelease = 0.99f,
                ReleasesResource     = true,
                ResourceToRelease    = ResourceLibrary.ResourceType.Iron,
                StartingHealth       = 80,
                IsBuildable          = false,
                ParticleType         = "stone_particle",
                SpawnClusters        = true,
                ClusterSize          = 5,
                SpawnVeins           = true,
                VeinLength           = 10,
                Rarity           = 0.0f,
                MinSpawnHeight   = 8,
                MaxSpawnHeight   = 40,
                SpawnProbability = 0.99f
            };


            VoxelType coalType = new VoxelType
            {
                Name = "Coal",
                ProbabilityOfRelease = 0.99f,
                ReleasesResource     = true,
                ResourceToRelease    = ResourceLibrary.ResourceType.Coal,
                StartingHealth       = 75,
                IsBuildable          = false,
                ParticleType         = "stone_particle",
                SpawnClusters        = true,
                ClusterSize          = 5,
                MinSpawnHeight       = 15,
                MaxSpawnHeight       = 50,
                SpawnProbability     = 0.3f,
                Rarity         = 0.05f,
                SpawnOnSurface = true
            };


            VoxelType goldType = new VoxelType
            {
                Name = "Gold",
                ProbabilityOfRelease = 1.0f,
                ReleasesResource     = true,
                ResourceToRelease    = ResourceLibrary.ResourceType.Gold,
                StartingHealth       = 90,
                IsBuildable          = false,
                ParticleType         = "stone_particle",
                SpawnVeins           = true,
                VeinLength           = 20,
                Rarity           = 0.2f,
                MinSpawnHeight   = 0,
                MaxSpawnHeight   = 20,
                SpawnProbability = 0.99f
            };

            VoxelType greenGem = new VoxelType
            {
                Name = "Emerald",
                ProbabilityOfRelease = 1.0f,
                ReleasesResource     = true,
                ResourceToRelease    = "Emerald",
                StartingHealth       = 90,
                IsBuildable          = false,
                ParticleType         = "stone_particle",
                SpawnClusters        = true,
                ClusterSize          = 3,
                MinSpawnHeight       = 0,
                MaxSpawnHeight       = 18,
                SpawnProbability     = 0.8f,
                Rarity = 0.9f
            };

            VoxelType redGem = new VoxelType
            {
                Name = "Ruby",
                ProbabilityOfRelease = 1.0f,
                ReleasesResource     = true,
                ResourceToRelease    = "Ruby",
                StartingHealth       = 90,
                IsBuildable          = false,
                ParticleType         = "stone_particle",
                SpawnClusters        = true,
                ClusterSize          = 3,
                MinSpawnHeight       = 0,
                MaxSpawnHeight       = 18,
                SpawnProbability     = 0.8f,
                Rarity = 0.9f
            };


            VoxelType purpleGem = new VoxelType
            {
                Name = "Amethyst",
                ProbabilityOfRelease = 1.0f,
                ReleasesResource     = true,
                ResourceToRelease    = "Amethyst",
                StartingHealth       = 90,
                IsBuildable          = false,
                ParticleType         = "stone_particle",
                ClusterSize          = 3,
                SpawnClusters        = true,
                MinSpawnHeight       = 0,
                MaxSpawnHeight       = 18,
                SpawnProbability     = 0.8f,
                Rarity = 0.9f
            };

            VoxelType blueGem = new VoxelType
            {
                Name = "Sapphire",
                ProbabilityOfRelease = 1.0f,
                ReleasesResource     = true,
                ResourceToRelease    = "Sapphire",
                StartingHealth       = 90,
                IsBuildable          = false,
                ParticleType         = "stone_particle",
                SpawnClusters        = true,
                ClusterSize          = 3,
                MinSpawnHeight       = 0,
                MaxSpawnHeight       = 18,
                SpawnProbability     = 0.8f,
                Rarity = 0.9f
            };

            VoxelType yellowGem = new VoxelType
            {
                Name = "Citrine",
                ProbabilityOfRelease = 1.0f,
                ReleasesResource     = true,
                ResourceToRelease    = "Citrine",
                StartingHealth       = 90,
                IsBuildable          = false,
                ParticleType         = "stone_particle",
                SpawnClusters        = true,
                ClusterSize          = 3,
                MinSpawnHeight       = 0,
                MaxSpawnHeight       = 18,
                SpawnProbability     = 0.8f,
                Rarity = 0.9f
            };

            VoxelType orangeGem = new VoxelType
            {
                Name = "Garnet",
                ProbabilityOfRelease = 1.0f,
                ReleasesResource     = true,
                ResourceToRelease    = "Garnet",
                StartingHealth       = 90,
                IsBuildable          = false,
                ParticleType         = "stone_particle",
                SpawnClusters        = true,
                ClusterSize          = 3,
                MinSpawnHeight       = 0,
                MaxSpawnHeight       = 18,
                SpawnProbability     = 0.8f,
                Rarity = 0.9f
            };


            VoxelType manaType = new VoxelType
            {
                Name = "Mana",
                ProbabilityOfRelease = 1.0f,
                ReleasesResource     = true,
                ResourceToRelease    = ResourceLibrary.ResourceType.Mana,
                StartingHealth       = 200,
                IsBuildable          = false,
                ParticleType         = "stone_particle",
                SpawnVeins           = true,
                VeinLength           = 25,
                Rarity           = 0.1f,
                MinSpawnHeight   = 0,
                MaxSpawnHeight   = 14,
                SpawnProbability = 0.99f
            };

            RegisterType(greenGem, greenGemCube);
            RegisterType(redGem, redGemCube);
            RegisterType(purpleGem, purpleGemCube);
            RegisterType(blueGem, blueGemCube);
            RegisterType(orangeGem, orangeGemCube);
            RegisterType(yellowGem, yellowGemCube);

            RegisterType(grassType, grassCube);
            RegisterType(frostType, frostCube);
            RegisterType(desertGrass, grassCube);
            RegisterType(jungleGrass, grassCube);
            RegisterType(caveFungus, grassCube);
            RegisterType(emptyType, null);
            RegisterType(dirtType, dirtCube);
            RegisterType(stoneType, stoneCube);
            RegisterType(waterType, waterCube);
            RegisterType(sandType, sandCube);
            RegisterType(ironType, ironCube);
            RegisterType(goldType, goldCube);
            RegisterType(manaType, manaCube);
            RegisterType(plankType, plankCube);
            RegisterType(scaffoldType, scaffoldCube);
            RegisterType(bedrockType, bedrockCube);
            RegisterType(coalType, coalCube);
            RegisterType(magicType, magicCube);

            foreach (VoxelType type in VoxelType.TypeList)
            {
                Types[type.Name] = type;
            }
        }
Ejemplo n.º 20
0
        public static Texture2D RenderIcons(GraphicsDevice device, Microsoft.Xna.Framework.Content.ContentManager Content, Gui.JsonTileSheet Sheet)
        {
            InitializeDefaultLibrary(device);

            var shader = new Shader(Content.Load <Effect>(ContentPaths.Shaders.TexturedShaders), true);

            var sqrt   = (int)(Math.Ceiling(Math.Sqrt(PrimitiveMap.Count)));
            var width  = MathFunctions.NearestPowerOf2(sqrt * Sheet.TileWidth);
            var height = MathFunctions.NearestPowerOf2(sqrt * Sheet.TileWidth);

            RenderTarget2D toReturn = new RenderTarget2D(device, width, height, false, SurfaceFormat.Color, DepthFormat.Depth16, 16, RenderTargetUsage.PreserveContents);

            device.SetRenderTarget(toReturn);
            device.Clear(Color.Transparent);
            shader.SetIconTechnique();
            shader.MainTexture             = AssetManager.GetContentTexture(ContentPaths.Terrain.terrain_tiles);
            shader.SelfIlluminationEnabled = true;
            shader.SelfIlluminationTexture = AssetManager.GetContentTexture(ContentPaths.Terrain.terrain_illumination);
            shader.EnableShadows           = false;
            shader.EnableLighting          = false;
            shader.ClippingEnabled         = false;
            shader.CameraPosition          = new Vector3(-0.5f, 0.5f, 0.5f);
            shader.VertexColorTint         = Color.White;
            shader.LightRamp                = Color.White;
            shader.SunlightGradient         = AssetManager.GetContentTexture(ContentPaths.Gradients.sungradient);
            shader.AmbientOcclusionGradient = AssetManager.GetContentTexture(ContentPaths.Gradients.ambientgradient);
            shader.TorchlightGradient       = AssetManager.GetContentTexture(ContentPaths.Gradients.torchgradient);

            Viewport oldview = device.Viewport;
            int      rows    = height / Sheet.TileWidth;
            int      cols    = width / Sheet.TileWidth;

            device.ScissorRectangle  = new Rectangle(0, 0, Sheet.TileWidth, Sheet.TileWidth);
            device.RasterizerState   = RasterizerState.CullNone;
            device.DepthStencilState = DepthStencilState.Default;
            Vector3 half = Vector3.One * 0.5f;

            half = new Vector3(half.X, half.Y, half.Z);

            List <VoxelType> voxelsByType = Types.Select(type => type.Value).ToList();

            voxelsByType.Sort((a, b) => a.ID < b.ID ? -1 : 1);

            foreach (EffectPass pass in shader.CurrentTechnique.Passes)
            {
                foreach (var type in voxelsByType)
                {
                    int          row       = type.ID / cols;
                    int          col       = type.ID % cols;
                    BoxPrimitive primitive = GetPrimitive(type);
                    if (primitive == null)
                    {
                        continue;
                    }

                    if (type.HasTransitionTextures)
                    {
                        primitive = new BoxPrimitive(device, 1, 1, 1, type.TransitionTextures[new BoxTransition()]);
                    }

                    device.Viewport = new Viewport(col * Sheet.TileWidth, row * Sheet.TileWidth, Sheet.TileWidth, Sheet.TileWidth);
                    Matrix viewMatrix       = Matrix.CreateLookAt(new Vector3(-1.2f, 1.0f, -1.5f), Vector3.Zero, Vector3.Up);
                    Matrix projectionMatrix = Matrix.CreateOrthographic(1.5f, 1.5f, 0, 5);
                    shader.View            = viewMatrix;
                    shader.Projection      = projectionMatrix;
                    shader.World           = Matrix.CreateTranslation(-half);
                    shader.VertexColorTint = type.Tint;
                    pass.Apply();
                    primitive.Render(device);
                }
            }
            device.Viewport = oldview;
            device.SetRenderTarget(null);
            return((Texture2D)toReturn);
        }
Ejemplo n.º 21
0
        public void InitializeFromChunk(VoxelChunk chunk, GraphicsDevice graphics)
        {
            if (chunk == null)
            {
                return;
            }

            rebuildMutex.WaitOne();
            if (isRebuilding)
            {
                rebuildMutex.ReleaseMutex();
                return;
            }

            isRebuilding = true;
            rebuildMutex.ReleaseMutex();
            int[] ambientValues = new int[4];
            int   maxIndex      = 0;
            int   maxVertex     = 0;
            Voxel v             = chunk.MakeVoxel(0, 0, 0);
            Voxel voxelOnFace   = chunk.MakeVoxel(0, 0, 0);

            Voxel[]      manhattanNeighbors = new Voxel[4];
            BoxPrimitive bedrockModel       = VoxelLibrary.GetPrimitive("Bedrock");
            Voxel        worldVoxel         = new Voxel();

            if (Vertices == null)
            {
                Vertices = new ExtendedVertex[1024];
            }

            if (Indexes == null)
            {
                Indexes = new ushort[512];
            }

            for (int y = 0; y < Math.Min(chunk.Manager.ChunkData.MaxViewingLevel + 1, chunk.SizeY); y++)
            {
                for (int x = 0; x < chunk.SizeX; x++)
                {
                    for (int z = 0; z < chunk.SizeZ; z++)
                    {
                        v.GridPosition = new Vector3(x, y, z);


                        if ((v.IsExplored && v.IsEmpty) || !v.IsVisible)
                        {
                            continue;
                        }

                        BoxPrimitive primitive = VoxelLibrary.GetPrimitive(v.Type);
                        if (v.IsExplored && primitive == null)
                        {
                            continue;
                        }
                        if (!v.IsExplored)
                        {
                            primitive = bedrockModel;
                        }

                        Color tint = v.Type.Tint;
                        BoxPrimitive.BoxTextureCoords uvs = primitive.UVs;

                        if (v.Type.HasTransitionTextures && v.IsExplored)
                        {
                            uvs = v.ComputeTransitionTexture(manhattanNeighbors);
                        }

                        for (int i = 0; i < 6; i++)
                        {
                            BoxFace face  = (BoxFace)i;
                            Vector3 delta = FaceDeltas[(int)face];
                            faceExists[(int)face] = chunk.IsCellValid(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z);
                            drawFace[(int)face]   = true;

                            if (faceExists[(int)face])
                            {
                                voxelOnFace.GridPosition = new Vector3(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z);
                                drawFace[(int)face]      = (voxelOnFace.IsExplored && voxelOnFace.IsEmpty) || !voxelOnFace.IsVisible ||
                                                           (voxelOnFace.Type.CanRamp && voxelOnFace.RampType != RampType.None && IsSideFace(face) &&
                                                            ShouldDrawFace(face, voxelOnFace.RampType, v.RampType));
                            }
                            else
                            {
                                bool success = chunk.Manager.ChunkData.GetNonNullVoxelAtWorldLocation(new Vector3(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z) + chunk.Origin, ref worldVoxel);
                                drawFace[(int)face] = !success || (worldVoxel.IsExplored && worldVoxel.IsEmpty) || !worldVoxel.IsVisible ||
                                                      (worldVoxel.Type.CanRamp && worldVoxel.RampType != RampType.None &&
                                                       IsSideFace(face) &&
                                                       ShouldDrawFace(face, worldVoxel.RampType, v.RampType));
                            }
                        }


                        for (int i = 0; i < 6; i++)
                        {
                            BoxFace face = (BoxFace)i;
                            if (!drawFace[(int)face])
                            {
                                continue;
                            }


                            int faceIndex   = 0;
                            int faceCount   = 0;
                            int vertexIndex = 0;
                            int vertexCount = 0;
                            primitive.GetFace(face, uvs, out faceIndex, out faceCount, out vertexIndex, out vertexCount);
                            Vector2 texScale = uvs.Scales[i];

                            int indexOffset = maxVertex;
                            for (int vertOffset = 0; vertOffset < vertexCount; vertOffset++)
                            {
                                ExtendedVertex vert    = primitive.Vertices[vertOffset + vertexIndex];
                                VoxelVertex    bestKey = primitive.Deltas[vertOffset + vertexIndex];
                                Color          color   = v.Chunk.Data.GetColor(x, y, z, bestKey);
                                ambientValues[vertOffset] = color.G;
                                Vector3 offset    = Vector3.Zero;
                                Vector2 texOffset = Vector2.Zero;

                                if (v.Type.CanRamp && ShouldRamp(bestKey, v.RampType))
                                {
                                    offset = new Vector3(0, -v.Type.RampSize, 0);

                                    if (face != BoxFace.Top && face != BoxFace.Bottom)
                                    {
                                        texOffset = new Vector2(0, v.Type.RampSize * (texScale.Y));
                                    }
                                }

                                if (maxVertex >= Vertices.Length)
                                {
                                    ExtendedVertex[] newVertices = new ExtendedVertex[Vertices.Length * 2];
                                    Vertices.CopyTo(newVertices, 0);
                                    Vertices = newVertices;
                                }

                                Vertices[maxVertex] = new ExtendedVertex(vert.Position + v.Position +
                                                                         VertexNoise.GetNoiseVectorFromRepeatingTexture(
                                                                             vert.Position + v.Position) + offset,
                                                                         color,
                                                                         tint,
                                                                         uvs.Uvs[vertOffset + vertexIndex] + texOffset,
                                                                         uvs.Bounds[faceIndex / 6]);
                                maxVertex++;
                            }

                            bool flippedQuad = ambientValues[0] + ambientValues[2] >
                                               ambientValues[1] + ambientValues[3];
                            for (int idx = faceIndex; idx < faceCount + faceIndex; idx++)
                            {
                                if (maxIndex >= Indexes.Length)
                                {
                                    ushort[] indexes = new ushort[Indexes.Length * 2];
                                    Indexes.CopyTo(indexes, 0);
                                    Indexes = indexes;
                                }

                                ushort vertexOffset  = flippedQuad ? primitive.FlippedIndexes[idx] : primitive.Indexes[idx];
                                ushort vertexOffset0 = flippedQuad? primitive.FlippedIndexes[faceIndex] : primitive.Indexes[faceIndex];
                                Indexes[maxIndex] =
                                    (ushort)((int)indexOffset + (int)((int)vertexOffset - (int)vertexOffset0));
                                maxIndex++;
                            }
                        }
                    }
                }
            }
            MaxIndex  = maxIndex;
            MaxVertex = maxVertex;
            GenerateLightmap(chunk.Manager.ChunkData.Tilemap.Bounds);
            isRebuilding = false;

            //chunk.PrimitiveMutex.WaitOne();
            chunk.NewPrimitive         = this;
            chunk.NewPrimitiveReceived = true;
            //chunk.PrimitiveMutex.ReleaseMutex();
        }
Ejemplo n.º 22
0
        public void InitializeFromChunk(VoxelChunk chunk, GraphicsDevice graphics)
        {
            if (chunk == null)
            {
                return;
            }

            rebuildMutex.WaitOne();
            if (isRebuilding)
            {
                rebuildMutex.ReleaseMutex();
                return;
            }

            isRebuilding = true;
            rebuildMutex.ReleaseMutex();


            accumulatedVertices.Clear();
            accumulatedIndices.Clear();
            faceExists.Clear();
            drawFace.Clear();

            Voxel v           = chunk.MakeVoxel(0, 0, 0);
            Voxel voxelOnFace = chunk.MakeVoxel(0, 0, 0);

            Voxel[] manhattanNeighbors = new Voxel[4];
            for (int x = 0; x < chunk.SizeX; x++)
            {
                for (int y = 0; y < Math.Min(chunk.Manager.ChunkData.MaxViewingLevel + 1, chunk.SizeY); y++)
                {
                    for (int z = 0; z < chunk.SizeZ; z++)
                    {
                        v.GridPosition = new Vector3(x, y, z);


                        if (v.IsEmpty || !v.IsVisible)
                        {
                            continue;
                        }

                        BoxPrimitive primitive = VoxelLibrary.GetPrimitive(v.Type);

                        if (primitive == null)
                        {
                            continue;
                        }

                        BoxPrimitive.BoxTextureCoords uvs = primitive.UVs;

                        if (v.Type.HasTransitionTextures)
                        {
                            uvs = v.ComputeTransitionTexture(manhattanNeighbors);
                        }


                        Voxel worldVoxel = new Voxel();
                        for (int i = 0; i < 6; i++)
                        {
                            BoxFace face  = (BoxFace)i;
                            Vector3 delta = FaceDeltas[face];
                            faceExists[face] = chunk.IsCellValid(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z);
                            drawFace[face]   = true;

                            if (faceExists[face])
                            {
                                voxelOnFace.GridPosition = new Vector3(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z);
                                drawFace[face]           = voxelOnFace.IsEmpty || !voxelOnFace.IsVisible || (voxelOnFace.Type.CanRamp && voxelOnFace.RampType != RampType.None && IsSideFace(face) && ShouldDrawFace(face, voxelOnFace.RampType, v.RampType));
                            }
                            else
                            {
                                bool success = chunk.Manager.ChunkData.GetNonNullVoxelAtWorldLocation(new Vector3(x + (int)delta.X, y + (int)delta.Y, z + (int)delta.Z) + chunk.Origin, ref worldVoxel);
                                drawFace[face] = !success || worldVoxel.IsEmpty || !worldVoxel.IsVisible || (worldVoxel.Type.CanRamp && worldVoxel.RampType != RampType.None && IsSideFace(face) && ShouldDrawFace(face, worldVoxel.RampType, v.RampType));
                            }
                        }


                        for (int i = 0; i < 6; i++)
                        {
                            BoxFace face = (BoxFace)i;
                            if (!drawFace[face])
                            {
                                continue;
                            }
                            int faceIndex   = 0;
                            int faceCount   = 0;
                            int vertexIndex = 0;
                            int vertexCount = 0;
                            primitive.GetFace(face, uvs, out faceIndex, out faceCount, out vertexIndex, out vertexCount);
                            Vector2 texScale = uvs.Scales[i];

                            int indexOffset = accumulatedVertices.Count;
                            for (int vertOffset = 0; vertOffset < vertexCount; vertOffset++)
                            {
                                ExtendedVertex vert      = primitive.Vertices[vertOffset + vertexIndex];
                                VoxelVertex    bestKey   = VoxelChunk.GetNearestDelta(vert.Position);
                                Color          color     = v.Chunk.Data.GetColor(x, y, z, bestKey);
                                Vector3        offset    = Vector3.Zero;
                                Vector2        texOffset = Vector2.Zero;

                                if (v.Type.CanRamp && ShouldRamp(bestKey, v.RampType))
                                {
                                    offset = new Vector3(0, -v.Type.RampSize, 0);

                                    if (face != BoxFace.Top && face != BoxFace.Bottom)
                                    {
                                        texOffset = new Vector2(0, v.Type.RampSize * (texScale.Y));
                                    }
                                }


                                ExtendedVertex newVertex = new ExtendedVertex((vert.Position + v.Position + VertexNoise.GetNoiseVectorFromRepeatingTexture(vert.Position + v.Position) + offset),
                                                                              color,
                                                                              uvs.Uvs[vertOffset + vertexIndex] + texOffset, uvs.Bounds[faceIndex / 6]);
                                accumulatedVertices.Add(newVertex);
                            }

                            for (int idx = faceIndex; idx < faceCount + faceIndex; idx++)
                            {
                                int vertexOffset = primitive.Indices[idx];
                                accumulatedIndices.Add((short)(indexOffset + (vertexOffset - primitive.Indices[faceIndex])));
                            }
                        }
                    }
                }
            }


            Vertices = new ExtendedVertex[accumulatedVertices.Count];
            accumulatedVertices.CopyTo(Vertices);
            IndexBuffer = new IndexBuffer(graphics, typeof(short), accumulatedIndices.Count, BufferUsage.WriteOnly);
            IndexBuffer.SetData(accumulatedIndices.ToArray());

            ResetBuffer(graphics);
            isRebuilding = false;

            //chunk.PrimitiveMutex.WaitOne();
            chunk.NewPrimitive         = this;
            chunk.NewPrimitiveReceived = true;
            //chunk.PrimitiveMutex.ReleaseMutex();
        }
Ejemplo n.º 23
0
        private static void BuildVoxelFaceGeometry(
            RawPrimitive Into,
            VoxelChunk Chunk,
            Cache Cache,
            BoxPrimitive Primitive,
            VoxelHandle V,
            Color Tint,
            BoxPrimitive.BoxTextureCoords UVs,
            Matrix VertexTransform,
            BoxFace BoxFace,
            bool ApplyLighting)
        {
            if (!IsFaceVisible(V, BoxFace, Chunk.Manager, out var neighbor))
            {
                return;
            }

            var faceDescriptor = Primitive.GetFace(BoxFace);
            var indexOffset    = Into.VertexCount;

            for (int faceVertex = 0; faceVertex < faceDescriptor.VertexCount; faceVertex++)
            {
                var vertex      = Primitive.Vertices[faceDescriptor.VertexOffset + faceVertex];
                var voxelVertex = Primitive.VertexClassifications[faceDescriptor.VertexOffset + faceVertex];
                var vertexColor = new VertexColorInfo
                {
                    SunColor     = 255,
                    AmbientColor = 255,
                    DynamicColor = 255,
                };

                if (ApplyLighting)
                {
                    var cacheKey = GetCacheKey(V, voxelVertex);

                    if (!Cache.LightCache.TryGetValue(cacheKey, out vertexColor))
                    {
                        vertexColor = CalculateVertexLight(V, voxelVertex, Chunk.Manager);
                        Cache.LightCache.Add(cacheKey, vertexColor);
                    }

                    Cache.AmbientValues[faceVertex] = vertexColor.AmbientColor;

                    if (!V.IsExplored && !neighbor.IsValid) // Turns the outside of the world black when it's not explored.
                    {
                        Tint = new Color(0.0f, 0.0f, 0.0f, 1.0f);
                    }
                }

                var rampOffset = Vector3.Zero;
                if (V.IsExplored && V.Type.CanRamp && ShouldRamp(voxelVertex, V.RampType))
                {
                    rampOffset = new Vector3(0, -0.5f, 0);
                }

                var baseWorldPosition = V.WorldPosition + vertex.Position + rampOffset;
                var noise             = VertexNoise.GetNoiseVectorFromRepeatingTexture(baseWorldPosition);
                var localPosition     = Vector3.Transform(vertex.Position + rampOffset + noise, VertexTransform);

                Into.AddVertex(new ExtendedVertex(
                                   V.WorldPosition + localPosition,
                                   vertexColor.AsColor(),
                                   Tint,
                                   UVs.Uvs[faceDescriptor.VertexOffset + faceVertex],
                                   UVs.Bounds[faceDescriptor.IndexOffset / 6]));
            }

            // Sometimes flip the quad to smooth out lighting.
            bool flippedQuad = ApplyLighting && (Cache.AmbientValues[0] + Cache.AmbientValues[2] >
                                                 Cache.AmbientValues[1] + Cache.AmbientValues[3]);

            for (int idx = faceDescriptor.IndexOffset; idx < faceDescriptor.IndexCount +
                 faceDescriptor.IndexOffset; idx++)
            {
                ushort offset  = flippedQuad ? Primitive.FlippedIndexes[idx] : Primitive.Indexes[idx];
                ushort offset0 = flippedQuad ? Primitive.FlippedIndexes[faceDescriptor.IndexOffset] : Primitive.Indexes[faceDescriptor.IndexOffset];
                Into.AddIndex((short)(indexOffset + offset - offset0));
            }
        }