Skip to content

Commit

Permalink
Switch to new colored block model UV lock logic
Browse files Browse the repository at this point in the history
  • Loading branch information
KnightMiner committed Jan 19, 2023
1 parent 4a6ef95 commit 6979fbb
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 95 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import com.mojang.datafixers.util.Pair;
import com.mojang.math.Transformation;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.BlockElement;
Expand Down Expand Up @@ -38,11 +35,12 @@
import slimeknights.mantle.client.model.RetexturedModel;
import slimeknights.mantle.client.model.RetexturedModel.RetexturedConfiguration;
import slimeknights.mantle.client.model.util.ColoredBlockModel;
import slimeknights.mantle.client.model.util.ColoredBlockModel.ColorData;
import slimeknights.mantle.client.model.util.DynamicBakedWrapper;
import slimeknights.mantle.client.model.util.ModelHelper;
import slimeknights.mantle.client.model.util.SimpleBlockModel;
import slimeknights.mantle.item.RetexturedBlockItem;
import slimeknights.mantle.util.JsonHelper;
import slimeknights.mantle.util.LogicHelper;
import slimeknights.mantle.util.RetexturedHelper;
import slimeknights.tconstruct.TConstruct;
import slimeknights.tconstruct.smeltery.block.entity.tank.IDisplayFluidListener;
Expand All @@ -66,10 +64,9 @@
public class FluidTextureModel implements IModelGeometry<FluidTextureModel> {
public static final Loader LOADER = new Loader();

private final SimpleBlockModel model;
private final ColoredBlockModel model;
private final Set<String> fluids;
private final Set<String> retextured;
private final List<UvLock> uvLock;

@Override
public Collection<Material> getTextures(IModelConfiguration owner, Function<ResourceLocation,UnbakedModel> modelGetter, Set<Pair<String,String>> missingTextureErrors) {
Expand All @@ -87,29 +84,10 @@ private static String trimTextureName(String name) {
@Override
public BakedModel bake(IModelConfiguration owner, ModelBakery bakery, Function<Material,TextureAtlasSprite> spriteGetter, ModelState transform, ItemOverrides overrides, ResourceLocation modelLocation) {
// start by baking the model, handing UV lock
BakedModel baked;
if (!uvLock.isEmpty()) {
// TODO: move to colored block model method in mantle
TextureAtlasSprite particle = spriteGetter.apply(owner.resolveTexture("particle"));
SimpleBakedModel.Builder builder = new SimpleBakedModel.Builder(owner, overrides).particle(particle);
boolean defaultUvLock = transform.isUvLocked();
ModelState reversedUvLock = new ModelStateUvLockOverride(transform, !defaultUvLock);
List<BlockElement> elements = model.getElements();
for (int i = 0; i < elements.size(); i++) {
BlockElement part = elements.get(i);
ModelState elementTransform = transform;
if (i < uvLock.size() && uvLock.get(i).isUvLock(defaultUvLock) != defaultUvLock) {
elementTransform = reversedUvLock;
}
SimpleBlockModel.bakePart(builder, owner, part, elementTransform, spriteGetter, modelLocation);
}
baked = builder.build();
} else {
baked = model.bakeModel(owner, transform, overrides, spriteGetter, modelLocation);
}
BakedModel baked = model.bake(owner, bakery, spriteGetter, transform, overrides, modelLocation);

// determine which block parts are fluids
Set<String> fluidTextures = this.fluids.isEmpty() ? Collections.emptySet() : RetexturedModel.getAllRetextured(owner, model, this.fluids);
Set<String> fluidTextures = this.fluids.isEmpty() ? Collections.emptySet() : RetexturedModel.getAllRetextured(owner, model.getModel(), this.fluids);
List<BlockElement> elements = model.getElements();
int size = elements.size();
BitSet fluidParts = new BitSet(size);
Expand All @@ -129,8 +107,8 @@ public BakedModel bake(IModelConfiguration owner, ModelBakery bakery, Function<M
}
}
}
Set<String> retextured = this.retextured.isEmpty() ? Collections.emptySet() : RetexturedModel.getAllRetextured(owner, this.model, this.retextured);
return new Baked(baked, elements, owner, transform, fluidTextures, fluidParts, retextured, uvLock);
Set<String> retextured = this.retextured.isEmpty() ? Collections.emptySet() : RetexturedModel.getAllRetextured(owner, this.model.getModel(), this.retextured);
return new Baked(baked, elements, model.getColorData(), owner, transform, fluidTextures, fluidParts, retextured);
}

private record BakedCacheKey(FluidStack fluid, @Nullable ResourceLocation texture) {}
Expand All @@ -139,22 +117,22 @@ private record BakedCacheKey(FluidStack fluid, @Nullable ResourceLocation textur
private static class Baked extends DynamicBakedWrapper<BakedModel> {
private final Map<BakedCacheKey,BakedModel> cache = new ConcurrentHashMap<>();
private final List<BlockElement> elements;
private final List<ColorData> colorData;
private final IModelConfiguration owner;
private final ModelState transform;
private final Set<String> fluids;
private final BitSet fluidParts;
private final Set<String> retextured;
private final List<UvLock> uvLock;

protected Baked(BakedModel originalModel, List<BlockElement> elements, IModelConfiguration owner, ModelState transform, Set<String> fluids, BitSet fluidParts, Set<String> retextured, List<UvLock> uvLock) {
protected Baked(BakedModel originalModel, List<BlockElement> elements, List<ColorData> colorData, IModelConfiguration owner, ModelState transform, Set<String> fluids, BitSet fluidParts, Set<String> retextured) {
super(originalModel);
this.elements = elements;
this.colorData = colorData;
this.owner = owner;
this.transform = transform;
this.fluids = fluids;
this.fluidParts = fluidParts;
this.retextured = retextured;
this.uvLock = uvLock;
}

/** Retextures a model for the given fluid */
Expand Down Expand Up @@ -184,18 +162,14 @@ private BakedModel getRetexturedModel(BakedCacheKey key) {

// add in elements
boolean defaultUvLock = transform.isUvLocked();
ModelState invertedTransform = new ModelStateUvLockOverride(transform, !defaultUvLock);
int size = elements.size();
for (int i = 0; i < size; i++) {
BlockElement element = elements.get(i);
ModelState elementTransform = transform;
if (i < uvLock.size() && uvLock.get(i).isUvLock(defaultUvLock) != defaultUvLock) {
elementTransform = invertedTransform;
}
ColorData colors = LogicHelper.getOrDefault(colorData, i, ColorData.DEFAULT);
if (fluidParts.get(i)) {
ColoredBlockModel.bakePart(builder, textured, element, color, luminosity, elementTransform, spriteGetter, TankModel.BAKE_LOCATION);
ColoredBlockModel.bakePart(builder, textured, element, color, luminosity, transform.getRotation(), colors.isUvLock(defaultUvLock), spriteGetter, TankModel.BAKE_LOCATION);
} else {
SimpleBlockModel.bakePart(builder, textured, element, elementTransform, spriteGetter, TankModel.BAKE_LOCATION);
ColoredBlockModel.bakePart(builder, textured, element, colors.color(), colors.luminosity(), transform.getRotation(), colors.isUvLock(defaultUvLock), spriteGetter, TankModel.BAKE_LOCATION);
}
}
return builder.build();
Expand Down Expand Up @@ -227,38 +201,14 @@ public ItemOverrides getOverrides() {
}
}

/** UV lock state */
private enum UvLock {
DEFAULT {
@Override
public boolean isUvLock(boolean uvLock) {
return uvLock;
}
},
TRUE {
@Override
public boolean isUvLock(boolean uvLock) {
return true;
}
},
FALSE {
@Override
public boolean isUvLock(boolean uvLock) {
return false;
}
};

public abstract boolean isUvLock(boolean uvLock);
}

/** Model loader class */
private static class Loader implements IModelLoader<FluidTextureModel> {
@Override
public void onResourceManagerReload(ResourceManager resourceManager) {}

@Override
public FluidTextureModel read(JsonDeserializationContext context, JsonObject json) {
SimpleBlockModel model = SimpleBlockModel.deserialize(context, json);
ColoredBlockModel model = ColoredBlockModel.deserialize(context, json);
Set<String> fluids = Collections.emptySet();
if (json.has("fluids")) {
fluids = ImmutableSet.copyOf(JsonHelper.parseList(json, "fluids", GsonHelper::convertToString));
Expand All @@ -267,11 +217,7 @@ public FluidTextureModel read(JsonDeserializationContext context, JsonObject jso
if (json.has("retextured")) {
retextured = ImmutableSet.copyOf(JsonHelper.parseList(json, "retextured", GsonHelper::convertToString));
}
List<UvLock> uvLock = Collections.emptyList();
if (json.has("elements")) {
uvLock = JsonHelper.parseList(json, "elements", obj -> obj.has("uvlock") ? JsonHelper.getAsEnum(obj, "uvlock", UvLock.class) : UvLock.DEFAULT);
}
return new FluidTextureModel(model, fluids, retextured, uvLock);
return new FluidTextureModel(model, fluids, retextured);
}
}

Expand All @@ -296,22 +242,4 @@ public BakedModel resolve(BakedModel originalModel, ItemStack stack, @Nullable C
return ((Baked)originalModel).getCachedModel(new BakedCacheKey(FluidStack.EMPTY, ModelHelper.getParticleTexture(block)));
}
}

/** Wrapper to override model state UV lock */
@RequiredArgsConstructor
private static class ModelStateUvLockOverride implements ModelState {
private final ModelState internal;
@Getter
private final boolean uvLocked;

@Override
public Transformation getRotation() {
return internal.getRotation();
}

@Override
public Transformation getPartTransformation(Object part) {
return internal.getPartTransformation(part);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{
"loader": "tconstruct:fluid_texture",
"loader": "mantle:retextured",
"parent": "block/block",
"textures": {
"particle": "#side"
},
"colors": [{"uvlock": true}],
"retextured": ["bricks"],
"elements": [
{
"name": "brick",
"from": [0, 0, 0],
"to": [16, 16, 16],
"uvlock": true,
"faces": {
"north": {"uv": [0, 0, 16, 16], "texture": "#back", "cullface": "north" },
"east": {"uv": [0, 0, 16, 16], "texture": "#bricks", "cullface": "east" },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{
"loader": "tconstruct:fluid_texture",
"loader": "mantle:retextured",
"parent": "block/block",
"textures": {
"particle": "#front"
},
"colors": [{"uvlock": true}],
"retextured": ["bricks"],
"elements": [
{
"name": "brick",
"from": [0, 0, 0],
"to": [16, 16, 16],
"uvlock": true,
"faces": {
"north": {"uv": [0, 0, 16, 16], "texture": "#bricks", "cullface": "north" },
"east": {"uv": [0, 0, 16, 16], "texture": "#bricks", "cullface": "east" },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
"fluid": "tconstruct:block/black",
"particle": "#front"
},
"colors": [{"uvlock": true}],
"fluids": ["fluid"],
"retextured": ["bricks"],
"elements": [
{
"name": "brick",
"from": [0, 0, 0],
"to": [16, 16, 16],
"uvlock": true,
"faces": {
"north": {"uv": [0, 0, 16, 16], "texture": "#bricks", "cullface": "north" },
"east": {"uv": [0, 0, 16, 16], "texture": "#bricks", "cullface": "east" },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{
"loader": "tconstruct:fluid_texture",
"loader": "mantle:retextured",
"parent": "block/block",
"textures": {
"particle": "#drain"
},
"colors": [{"uvlock": true}],
"retextured": ["bricks"],
"elements": [
{
"name": "brick",
"from": [0, 0, 0],
"to": [16, 16, 16],
"uvlock": true,
"faces": {
"north": {"uv": [0, 0, 16, 16], "texture": "#back", "cullface": "north" },
"east": {"uv": [0, 0, 16, 16], "texture": "#bricks", "cullface": "east" },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
"fluid": "tconstruct:block/black",
"particle": "#drain"
},
"colors": [{"uvlock": true}],
"fluids": ["fluid"],
"retextured": ["bricks"],
"elements": [
{
"name": "brick",
"from": [0, 0, 0],
"to": [16, 16, 16],
"uvlock": true,
"faces": {
"north": {"uv": [0, 0, 16, 16], "texture": "#back", "cullface": "north" },
"east": {"uv": [0, 0, 16, 16], "texture": "#bricks", "cullface": "east" },
Expand Down

0 comments on commit 6979fbb

Please sign in to comment.