Пример #1
0
        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);
            }
        }
Пример #2
0
        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);
                        }
                    }
                }
            }
        }