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; }
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; }
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); }