Exemple #1
0
        private static bool IsTransparent(BlockCoordinates blockCoordinates, ChunkSection section)
        {
            if (section == null)
            {
                return(true);
            }

            int bx = blockCoordinates.X & 0x0f;
            int by = blockCoordinates.Y & 0xff;
            int bz = blockCoordinates.Z & 0x0f;

            var state = section.Get(bx, by - 16 * (by >> 4), bz);

            return(state.Block is Air || state.Block.Transparent);
            //	return bid == 0 || BlockFactory.TransparentBlocks[bid] == 1;
        }
Exemple #2
0
        public static int GetDiffuseLevel(BlockCoordinates blockCoordinates, ChunkSection section)
        {
            //TODO: Figure out if this is really correct. Perhaps should be zero.
            if (section == null)
            {
                return(15);
            }

            int bx = blockCoordinates.X & 0x0f;
            int by = blockCoordinates.Y & 0xff;
            int bz = blockCoordinates.Z & 0x0f;

            var state = section.Get(bx, by - 16 * (by >> 4), bz);

            return(state.Block.LightOpacity);
            //return bid == 8 || bid == 9 ? 3 : bid == 18 || bid == 161 || bid == 30 ? 2 : 1;
        }
Exemple #3
0
        private ChunkMesh GenerateSectionMesh(IWorld world, ScheduleType scheduled, Vector3 chunkPosition,
                                              ref ChunkSection section, int yIndex)
        {
            var force = section.New || section.MeshCache == null || section.MeshPositions == null;

            var cached        = section.MeshCache;
            var positionCache = section.MeshPositions;

            Dictionary <Vector3, ChunkMesh.EntryPosition> positions = new Dictionary <Vector3, ChunkMesh.EntryPosition>();

            List <VertexPositionNormalTextureColor> solidVertices = new List <VertexPositionNormalTextureColor>();

            List <int> animatedIndexes    = new List <int>();
            List <int> transparentIndexes = new List <int>();
            List <int> solidIndexes       = new List <int>();

            Dictionary <int, int> processedIndices = new Dictionary <int, int>();

            for (var y = 0; y < 16; y++)
            {
                for (var x = 0; x < ChunkColumn.ChunkWidth; x++)
                {
                    for (var z = 0; z < ChunkColumn.ChunkDepth; z++)
                    {
                        var blockPosition = new Vector3(x, y + (yIndex << 4), z) + chunkPosition;

                        bool isScheduled        = section.IsScheduled(x, y, z);
                        var  neighborsScheduled = HasScheduledNeighbors(world, blockPosition);
                        // bool isLightingScheduled = section.IsLightingScheduled(x, y, z);

                        var isBorderBlock = (scheduled == ScheduleType.Border && (x == 0 || x == 15) || (z == 0 || z == 15));

                        var blockState = section.Get(x, y, z);

                        if (((blockState == null || !blockState.Block.Renderable) ||
                             (!section.New &&
                              !neighborsScheduled)) && !force && !isBorderBlock)
                        {
                            continue;
                        }

                        var shouldRebuildVertices = (force || isScheduled || neighborsScheduled || isBorderBlock);

                        var model = blockState.Model;

                        if (blockState != null && shouldRebuildVertices && blockState.Block.RequiresUpdate)
                        {
                            blockState = blockState.Block.BlockPlaced(world, blockState, blockPosition);
                            section.Set(x, y, z, blockState);

                            model = blockState.Model;
                        }

                        if (blockState is BlockState state && state.IsMultiPart && shouldRebuildVertices)
                        {
                            model = new CachedResourcePackModel(Game.Resources,
                                                                MultiPartModels.GetBlockStateModels(world, blockPosition, state, state.MultiPartHelper));
                            // blockState.Block.Update(world, blockPosition);
                        }

                        if (!shouldRebuildVertices && positionCache.TryGetValue(new Vector3(x, y, z), out var pos))
                        {
                            var indices = pos.Animated
                                                ? cached.AnimatedIndexes
                                                : (pos.Transparent ? cached.TransparentIndexes : cached.SolidIndexes);

                            var indiceIndex = pos.Animated
                                                ? animatedIndexes.Count
                                                : (pos.Transparent ? transparentIndexes.Count : solidIndexes.Count);
                            for (int index = 0; index < pos.Length; index++)
                            {
                                var indice = indices[pos.Index + index];
                                if (!processedIndices.TryGetValue(indice, out var newIndex))
                                {
                                    newIndex = solidVertices.Count;
                                    var vertice = cached.Vertices[indice];
                                    solidVertices.Add(vertice);

                                    processedIndices.Add(indice, newIndex);
                                }

                                if (pos.Animated)
                                {
                                    animatedIndexes.Add(newIndex);
                                }
                                else if (pos.Transparent)
                                {
                                    transparentIndexes.Add(newIndex);
                                }
                                else
                                {
                                    solidIndexes.Add(newIndex);
                                }
                            }

                            positions.TryAdd(new Vector3(x, y, z),
                                             new ChunkMesh.EntryPosition(pos.Transparent, pos.Animated, indiceIndex, pos.Length));
                        }
                        else if (shouldRebuildVertices)
                        {
                            var data = model.GetVertices(world, blockPosition, blockState.Block);

                            if (data.vertices.Length == 0 ||
                                data.indexes.Length == 0)
                            {
                                section.SetRendered(x, y, z, false);
                            }

                            if (data.vertices == null || data.indexes == null || data.vertices.Length == 0 ||
                                data.indexes.Length == 0)
                            {
                                //section.SetRendered(x, y, z, false);
                                if (isScheduled)
                                {
                                    section.SetScheduled(x, y, z, false);
                                }

                                continue;
                            }

                            bool transparent = blockState.Block.Transparent;
                            bool animated    = blockState.Block.Animated;

                            if (data.vertices.Length > 0 && data.indexes.Length > 0)
                            {
                                section.SetRendered(x, y, z, true);

                                int startVerticeIndex = solidVertices.Count;
                                foreach (var vert in data.vertices)
                                {
                                    solidVertices.Add(vert);
                                }

                                int startIndex = animated ? animatedIndexes.Count : (transparent ? transparentIndexes.Count : solidIndexes.Count);
                                for (int i = 0; i < data.indexes.Length; i++)
                                {
                                    var a = data.indexes[i];

                                    if (animated)
                                    {
                                        animatedIndexes.Add(startVerticeIndex + a);
                                    }
                                    else if (transparent)
                                    {
                                        transparentIndexes.Add(startVerticeIndex + a);
                                    }
                                    else
                                    {
                                        solidIndexes.Add(startVerticeIndex + a);
                                    }
                                }

                                positions.TryAdd(new Vector3(x, y, z),
                                                 new ChunkMesh.EntryPosition(transparent, animated, startIndex, data.indexes.Length));
                            }
                        }

                        //if (isLightingScheduled)
                        //    section.SetLightingScheduled(x, y, z, false);
                    }
                }
            }

            section.New = false;

            var mesh = new ChunkMesh(solidVertices.ToArray(), solidIndexes.ToArray(),
                                     transparentIndexes.ToArray(), animatedIndexes.ToArray());

            section.MeshCache     = mesh;
            section.MeshPositions = positions;

            return(mesh);
        }