private static BlockModel GetOrCacheModel(ResourceManager resources, McResourcePack resourcePack, BlockState state, uint id, bool rebuild) { BlockModel result = null; if (ModelCache.TryGetValue(id, out result) && !rebuild) { return(result); } else { var r = ResolveModel(resources, resourcePack, state); if (r == null) { return(result); } result = r; if (!ModelCache.TryAdd(id, result)) { if (rebuild) { ModelCache[id] = result; } else { Log.Warn($"Could not register model in cache! {state.Name} - {state.ID}"); } } return(result); } }
private void CalculateModel(IBlockAccess world, BlockCoordinates blockCoordinates, ChunkData chunkBuilder, Vector3 position, Block baseBlock, BlockStateModel blockStateModel, ResourcePackModelBase model, Biome biome) { //bsModel.Y = Math.Abs(180 - bsModel.Y); //if (Resources.BlockModelRegistry.TryGet(blockStateModel.ModelName, out var registryEntry)) { //var model = registryEntry.Value; var baseColor = baseBlock.BlockMaterial.TintColor; for (var index = 0; index < model.Elements.Length; index++) { var element = model.Elements[index]; element.To *= Scale; element.From *= Scale; foreach (var face in element.Faces) { var facing = face.Key; var cullFace = face.Value.CullFace ?? face.Key; if (blockStateModel.X > 0f) { var offset = blockStateModel.X / 90; cullFace = RotateDirection(cullFace, offset, FACE_ROTATION_X, INVALID_FACE_ROTATION_X); facing = RotateDirection(facing, offset, FACE_ROTATION_X, INVALID_FACE_ROTATION_X); } if (blockStateModel.Y > 0f) { var offset = blockStateModel.Y / 90; cullFace = RotateDirection(cullFace, offset, FACE_ROTATION, INVALID_FACE_ROTATION); facing = RotateDirection(facing, offset, FACE_ROTATION, INVALID_FACE_ROTATION); } if (!ShouldRenderFace(world, facing, position, baseBlock)) { continue; } var positionOffset = baseBlock.GetOffset(NoiseGenerator, position); var uv = face.Value.UV; float x1 = 0, x2 = 0, y1 = 0, y2 = 0; if (uv == null) { switch (face.Key) { case BlockFace.North: case BlockFace.South: x1 = element.From.X; x2 = element.To.X; y1 = 16f - element.To.Y; y2 = 16f - element.From.Y; break; case BlockFace.West: case BlockFace.East: x1 = element.From.Z; x2 = element.To.Z; y1 = 16f - element.To.Y; y2 = 16f - element.From.Y; break; case BlockFace.Down: case BlockFace.Up: x1 = element.From.X; x2 = element.To.X; y1 = 16f - element.To.Z; y2 = 16f - element.From.Z; break; } } else { x1 = uv.X1; x2 = uv.X2; y1 = uv.Y1; y2 = uv.Y2; } var faceColor = baseColor; bool hasTint = (face.Value.TintIndex.HasValue && face.Value.TintIndex == 0); if (hasTint) { switch (baseBlock.BlockMaterial.TintType) { case TintType.Default: faceColor = Color.White; break; case TintType.Color: faceColor = baseBlock.BlockMaterial.TintColor; break; case TintType.Grass: if (SmoothLighting) { var bx = (int)position.X; var y = (int)position.Y; var bz = (int)position.Z; faceColor = CombineColors( GetGrassBiomeColor(world, bx, y, bz), GetGrassBiomeColor(world, bx - 1, y, bz), GetGrassBiomeColor(world, bx, y, bz - 1), GetGrassBiomeColor(world, bx + 1, y, bz), GetGrassBiomeColor(world, bx, y, bz + 1), GetGrassBiomeColor(world, bx + 1, y, bz - 1)); } else { faceColor = Resources.ResourcePack.GetGrassColor( biome.Temperature, biome.Downfall, (int)position.Y); } break; case TintType.Foliage: if (face.Value.TintIndex.HasValue && face.Value.TintIndex == 0) { faceColor = Resources.ResourcePack.GetFoliageColor( biome.Temperature, biome.Downfall, (int)position.Y); } break; default: throw new ArgumentOutOfRangeException(); } } faceColor = AdjustColor(faceColor, facing, element.Shade); var uvMap = GetTextureUVMap( Resources, ResolveTexture(model, face.Value.Texture), x1, x2, y1, y2, face.Value.Rotation, faceColor); var vertices = GetFaceVertices(face.Key, element.From, element.To, uvMap); vertices = ProcessVertices(vertices, blockStateModel, element, uvMap, facing, face.Value); RenderStage targetState = RenderStage.OpaqueFullCube; if (baseBlock.BlockMaterial.IsLiquid) { targetState = RenderStage.Liquid; } else if (uvMap.IsAnimated) { targetState = RenderStage.Animated; } else if (baseBlock.Transparent) { if (baseBlock.BlockMaterial.IsOpaque) { if (!Block.FancyGraphics && baseBlock.IsFullCube) { targetState = RenderStage.OpaqueFullCube; } else { targetState = RenderStage.Transparent; } } else { targetState = RenderStage.Translucent; } } else if (!baseBlock.IsFullCube) { targetState = RenderStage.Opaque; } for (int i = 0; i < vertices.Length; i++) { var vertex = vertices[i]; BlockModel.GetLight( world, vertex.Position + position + vertex.Face.GetVector3(), out var blockLight, out var skyLight, true); chunkBuilder.AddVertex( blockCoordinates, vertex.Position + position + positionOffset, vertex.TexCoords, vertex.Color, blockLight, skyLight, targetState); } } } } }