169 lines
7.8 KiB
Java
169 lines
7.8 KiB
Java
package net.minecraft.client.resources.model;
|
|
|
|
import com.mojang.logging.LogUtils;
|
|
import com.mojang.math.Transformation;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.function.UnaryOperator;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.IntStream;
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.minecraft.client.model.geom.EntityModelSet;
|
|
import net.minecraft.client.renderer.RenderType;
|
|
import net.minecraft.client.renderer.Sheets;
|
|
import net.minecraft.client.renderer.block.model.UnbakedBlockStateModel;
|
|
import net.minecraft.client.renderer.item.ClientItem;
|
|
import net.minecraft.client.renderer.item.ItemModel;
|
|
import net.minecraft.client.renderer.item.MissingItemModel;
|
|
import net.minecraft.client.renderer.texture.TextureAtlas;
|
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
|
import net.minecraft.client.resources.model.ModelBakery.TextureGetter.1;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import org.slf4j.Logger;
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class ModelBakery {
|
|
public static final Material FIRE_0 = new Material(TextureAtlas.LOCATION_BLOCKS, ResourceLocation.withDefaultNamespace("block/fire_0"));
|
|
public static final Material FIRE_1 = new Material(TextureAtlas.LOCATION_BLOCKS, ResourceLocation.withDefaultNamespace("block/fire_1"));
|
|
public static final Material LAVA_FLOW = new Material(TextureAtlas.LOCATION_BLOCKS, ResourceLocation.withDefaultNamespace("block/lava_flow"));
|
|
public static final Material WATER_FLOW = new Material(TextureAtlas.LOCATION_BLOCKS, ResourceLocation.withDefaultNamespace("block/water_flow"));
|
|
public static final Material WATER_OVERLAY = new Material(TextureAtlas.LOCATION_BLOCKS, ResourceLocation.withDefaultNamespace("block/water_overlay"));
|
|
public static final Material BANNER_BASE = new Material(Sheets.BANNER_SHEET, ResourceLocation.withDefaultNamespace("entity/banner_base"));
|
|
public static final Material SHIELD_BASE = new Material(Sheets.SHIELD_SHEET, ResourceLocation.withDefaultNamespace("entity/shield_base"));
|
|
public static final Material NO_PATTERN_SHIELD = new Material(Sheets.SHIELD_SHEET, ResourceLocation.withDefaultNamespace("entity/shield_base_nopattern"));
|
|
public static final int DESTROY_STAGE_COUNT = 10;
|
|
public static final List<ResourceLocation> DESTROY_STAGES = (List<ResourceLocation>)IntStream.range(0, 10)
|
|
.mapToObj(i -> ResourceLocation.withDefaultNamespace("block/destroy_stage_" + i))
|
|
.collect(Collectors.toList());
|
|
public static final List<ResourceLocation> BREAKING_LOCATIONS = (List<ResourceLocation>)DESTROY_STAGES.stream()
|
|
.map(resourceLocation -> resourceLocation.withPath((UnaryOperator<String>)(string -> "textures/" + string + ".png")))
|
|
.collect(Collectors.toList());
|
|
public static final List<RenderType> DESTROY_TYPES = (List<RenderType>)BREAKING_LOCATIONS.stream().map(RenderType::crumbling).collect(Collectors.toList());
|
|
static final Logger LOGGER = LogUtils.getLogger();
|
|
private final EntityModelSet entityModelSet;
|
|
final Map<ModelBakery.BakedCacheKey, BakedModel> bakedCache = new HashMap();
|
|
private final Map<ModelResourceLocation, UnbakedBlockStateModel> unbakedBlockStateModels;
|
|
private final Map<ResourceLocation, ClientItem> clientInfos;
|
|
final Map<ResourceLocation, UnbakedModel> unbakedPlainModels;
|
|
final UnbakedModel missingModel;
|
|
|
|
public ModelBakery(
|
|
EntityModelSet entityModelSet,
|
|
Map<ModelResourceLocation, UnbakedBlockStateModel> unbakedBlockStateModels,
|
|
Map<ResourceLocation, ClientItem> unbakedItemStackModels,
|
|
Map<ResourceLocation, UnbakedModel> unbakedPlainModels,
|
|
UnbakedModel missingModel
|
|
) {
|
|
this.entityModelSet = entityModelSet;
|
|
this.unbakedBlockStateModels = unbakedBlockStateModels;
|
|
this.clientInfos = unbakedItemStackModels;
|
|
this.unbakedPlainModels = unbakedPlainModels;
|
|
this.missingModel = missingModel;
|
|
}
|
|
|
|
public ModelBakery.BakingResult bakeModels(ModelBakery.TextureGetter textureGetter) {
|
|
BakedModel bakedModel = UnbakedModel.bakeWithTopModelValues(
|
|
this.missingModel, new ModelBakery.ModelBakerImpl(textureGetter, () -> "missing"), BlockModelRotation.X0_Y0
|
|
);
|
|
Map<ModelResourceLocation, BakedModel> map = new HashMap(this.unbakedBlockStateModels.size());
|
|
this.unbakedBlockStateModels.forEach((modelResourceLocation, unbakedBlockStateModel) -> {
|
|
try {
|
|
BakedModel bakedModelx = unbakedBlockStateModel.bake(new ModelBakery.ModelBakerImpl(textureGetter, modelResourceLocation::toString));
|
|
map.put(modelResourceLocation, bakedModelx);
|
|
} catch (Exception var6x) {
|
|
LOGGER.warn("Unable to bake model: '{}': {}", modelResourceLocation, var6x);
|
|
}
|
|
});
|
|
ItemModel itemModel = new MissingItemModel(bakedModel);
|
|
Map<ResourceLocation, ItemModel> map2 = new HashMap(this.clientInfos.size());
|
|
Map<ResourceLocation, ClientItem.Properties> map3 = new HashMap(this.clientInfos.size());
|
|
this.clientInfos.forEach((resourceLocation, clientItem) -> {
|
|
ModelDebugName modelDebugName = () -> resourceLocation + "#inventory";
|
|
ModelBakery.ModelBakerImpl modelBakerImpl = new ModelBakery.ModelBakerImpl(textureGetter, modelDebugName);
|
|
ItemModel.BakingContext bakingContext = new ItemModel.BakingContext(modelBakerImpl, this.entityModelSet, itemModel);
|
|
|
|
try {
|
|
ItemModel itemModel2 = clientItem.model().bake(bakingContext);
|
|
map2.put(resourceLocation, itemModel2);
|
|
if (!clientItem.properties().equals(ClientItem.Properties.DEFAULT)) {
|
|
map3.put(resourceLocation, clientItem.properties());
|
|
}
|
|
} catch (Exception var11) {
|
|
LOGGER.warn("Unable to bake item model: '{}'", resourceLocation, var11);
|
|
}
|
|
});
|
|
return new ModelBakery.BakingResult(bakedModel, map, itemModel, map2, map3);
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
record BakedCacheKey(ResourceLocation id, Transformation transformation, boolean isUvLocked) {
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public record BakingResult(
|
|
BakedModel missingModel,
|
|
Map<ModelResourceLocation, BakedModel> blockStateModels,
|
|
ItemModel missingItemModel,
|
|
Map<ResourceLocation, ItemModel> itemStackModels,
|
|
Map<ResourceLocation, ClientItem.Properties> itemProperties
|
|
) {
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
class ModelBakerImpl implements ModelBaker {
|
|
private final ModelDebugName rootName;
|
|
private final SpriteGetter modelTextureGetter;
|
|
|
|
ModelBakerImpl(final ModelBakery.TextureGetter textureGetter, final ModelDebugName rootName) {
|
|
this.modelTextureGetter = textureGetter.bind(rootName);
|
|
this.rootName = rootName;
|
|
}
|
|
|
|
@Override
|
|
public SpriteGetter sprites() {
|
|
return this.modelTextureGetter;
|
|
}
|
|
|
|
private UnbakedModel getModel(ResourceLocation name) {
|
|
UnbakedModel unbakedModel = (UnbakedModel)ModelBakery.this.unbakedPlainModels.get(name);
|
|
if (unbakedModel == null) {
|
|
ModelBakery.LOGGER.warn("Requested a model that was not discovered previously: {}", name);
|
|
return ModelBakery.this.missingModel;
|
|
} else {
|
|
return unbakedModel;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public BakedModel bake(ResourceLocation location, ModelState transform) {
|
|
ModelBakery.BakedCacheKey bakedCacheKey = new ModelBakery.BakedCacheKey(location, transform.getRotation(), transform.isUvLocked());
|
|
BakedModel bakedModel = (BakedModel)ModelBakery.this.bakedCache.get(bakedCacheKey);
|
|
if (bakedModel != null) {
|
|
return bakedModel;
|
|
} else {
|
|
UnbakedModel unbakedModel = this.getModel(location);
|
|
BakedModel bakedModel2 = UnbakedModel.bakeWithTopModelValues(unbakedModel, this, transform);
|
|
ModelBakery.this.bakedCache.put(bakedCacheKey, bakedModel2);
|
|
return bakedModel2;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public ModelDebugName rootName() {
|
|
return this.rootName;
|
|
}
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public interface TextureGetter {
|
|
TextureAtlasSprite get(ModelDebugName name, Material material);
|
|
|
|
TextureAtlasSprite reportMissingReference(ModelDebugName name, String reference);
|
|
|
|
default SpriteGetter bind(ModelDebugName name) {
|
|
return new 1(this, name);
|
|
}
|
|
}
|
|
}
|