diff --git a/README.md b/README.md index f62afdf..e6daa6b 100644 --- a/README.md +++ b/README.md @@ -74,4 +74,6 @@ Templates's slope blocks use this model, because it's otherwise impossible to ma 3. Create a blockstate json for your block, and point it at the ID you decided for your special model in 1). * You may use the `x`, `y`, and `uvlock` properties as normal. +Ambient occlusion now defaults to "on" (since 2.1.1). If this looks bad on your model, you can reset it with a `.disableAo()` call on your UnbakedModel. + You may create a regular item model, or use ours by calling `TemplatesClient.provider.assignItemModel`, passing the ID of the special model & the items you want to assign it to. (The reason you have to do this instead of simply creating a regular item model and setting its `parent`, is that `JsonUnbakedModel`s can't have non-`JsonUnbakedModel`s as their `parent`, and even a trivial item model with only the `parent` field set counts as a `JsonUnbakedModel`. This isn't a problem for block models because blockstates are a layer of indirection before model loading.) \ No newline at end of file diff --git a/build.gradle b/build.gradle index c16acd1..5de077a 100755 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ if(rootProject.file("private.gradle").exists()) { //Publishing details archivesBaseName = "templates" group = "io.github.cottonmc" -version = "2.1.0+1.20.1" +version = "2.1.1+1.20.1" repositories { mavenCentral() diff --git a/src/main/java/io/github/cottonmc/templates/TemplatesClient.java b/src/main/java/io/github/cottonmc/templates/TemplatesClient.java index 3d52ef6..3d75250 100644 --- a/src/main/java/io/github/cottonmc/templates/TemplatesClient.java +++ b/src/main/java/io/github/cottonmc/templates/TemplatesClient.java @@ -128,10 +128,10 @@ public class TemplatesClient implements ClientModInitializer { provider.addTemplateModel(Templates.id("wall_side_tall_special") , new UnbakedJsonRetexturedModel(Templates.id("block/wall_side_tall"))); //mesh models - provider.addTemplateModel(Templates.id("slope_special") , new UnbakedMeshRetexturedModel(Templates.id("block/slope_base"), SlopeBaseMesh::makeUpright)); - provider.addTemplateModel(Templates.id("slope_side_special") , new UnbakedMeshRetexturedModel(Templates.id("block/slope_base"), SlopeBaseMesh::makeSide)); - provider.addTemplateModel(Templates.id("tiny_slope_special") , new UnbakedMeshRetexturedModel(Templates.id("block/tiny_slope_base"), SlopeBaseMesh::makeTinyUpright)); - provider.addTemplateModel(Templates.id("tiny_slope_side_special") , new UnbakedMeshRetexturedModel(Templates.id("block/tiny_slope_base"), SlopeBaseMesh::makeTinySide)); + provider.addTemplateModel(Templates.id("slope_special") , new UnbakedMeshRetexturedModel(Templates.id("block/slope_base"), SlopeBaseMesh::makeUpright).disableAo()); + provider.addTemplateModel(Templates.id("slope_side_special") , new UnbakedMeshRetexturedModel(Templates.id("block/slope_base"), SlopeBaseMesh::makeSide).disableAo()); + provider.addTemplateModel(Templates.id("tiny_slope_special") , new UnbakedMeshRetexturedModel(Templates.id("block/tiny_slope_base"), SlopeBaseMesh::makeTinyUpright).disableAo()); + provider.addTemplateModel(Templates.id("tiny_slope_side_special") , new UnbakedMeshRetexturedModel(Templates.id("block/tiny_slope_base"), SlopeBaseMesh::makeTinySide).disableAo()); //item only models provider.addTemplateModel(Templates.id("button_inventory_special") , new UnbakedAutoRetexturedModel(new Identifier("block/button_inventory"))); diff --git a/src/main/java/io/github/cottonmc/templates/model/RetexturingBakedModel.java b/src/main/java/io/github/cottonmc/templates/model/RetexturingBakedModel.java index 20445a8..c55a8c2 100644 --- a/src/main/java/io/github/cottonmc/templates/model/RetexturingBakedModel.java +++ b/src/main/java/io/github/cottonmc/templates/model/RetexturingBakedModel.java @@ -27,19 +27,26 @@ import java.util.concurrent.ConcurrentMap; import java.util.function.Supplier; public abstract class RetexturingBakedModel extends ForwardingBakedModel { + @Deprecated(forRemoval = true) //binary-compat from before there was an AO boolean public RetexturingBakedModel(BakedModel baseModel, TemplateAppearanceManager tam, ModelBakeSettings settings, BlockState itemModelState) { + this(baseModel, tam, settings, itemModelState, true); + } + + public RetexturingBakedModel(BakedModel baseModel, TemplateAppearanceManager tam, ModelBakeSettings settings, BlockState itemModelState, boolean ao) { this.wrapped = baseModel; this.tam = tam; this.facePermutation = MeshTransformUtil.facePermutation(settings); this.uvlock = settings.isUvLocked(); this.itemModelState = itemModelState; + this.ao = ao; } protected final TemplateAppearanceManager tam; protected final Map facePermutation; //immutable protected final boolean uvlock; protected final BlockState itemModelState; + protected final boolean ao; private static record CacheKey(BlockState state, TemplateAppearance appearance) {} private final ConcurrentMap retexturedMeshes = new ConcurrentHashMap<>(); //mutable, append-only cache @@ -132,7 +139,7 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel { @Override public boolean transform(MutableQuadView quad) { - quad.material(ta.getRenderMaterial()); + quad.material(ta.getRenderMaterial(ao)); int tag = quad.tag(); if(tag == 0) return true; //Pass the quad through unmodified. diff --git a/src/main/java/io/github/cottonmc/templates/model/TemplateAppearance.java b/src/main/java/io/github/cottonmc/templates/model/TemplateAppearance.java index 526b452..aa150f6 100644 --- a/src/main/java/io/github/cottonmc/templates/model/TemplateAppearance.java +++ b/src/main/java/io/github/cottonmc/templates/model/TemplateAppearance.java @@ -8,8 +8,14 @@ import org.jetbrains.annotations.NotNull; public interface TemplateAppearance { @NotNull Sprite getParticleSprite(); //TODO: plug this in (particle mixins don't use it atm) - @NotNull RenderMaterial getRenderMaterial(); + @NotNull RenderMaterial getRenderMaterial(boolean ao); @NotNull Sprite getSprite(Direction dir); int getBakeFlags(Direction dir); boolean hasColor(Direction dir); + + //binary-compat + @Deprecated(forRemoval = true) + default @NotNull RenderMaterial getRenderMaterial() { + return getRenderMaterial(false); + } } diff --git a/src/main/java/io/github/cottonmc/templates/model/TemplateAppearanceManager.java b/src/main/java/io/github/cottonmc/templates/model/TemplateAppearanceManager.java index f1df69d..6a1d8f0 100644 --- a/src/main/java/io/github/cottonmc/templates/model/TemplateAppearanceManager.java +++ b/src/main/java/io/github/cottonmc/templates/model/TemplateAppearanceManager.java @@ -26,6 +26,7 @@ import org.jetbrains.annotations.NotNull; import java.util.Arrays; import java.util.EnumMap; import java.util.List; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; @@ -34,16 +35,19 @@ public class TemplateAppearanceManager { public TemplateAppearanceManager(Function spriteLookup) { MaterialFinder finder = TemplatesClient.getFabricRenderer().materialFinder(); for(BlendMode blend : BlendMode.values()) { - blockMaterials.put(blend, finder.clear().disableDiffuse(false).ambientOcclusion(TriState.FALSE).blendMode(blend).find()); + finder.clear().disableDiffuse(false).blendMode(blend); + + materialsWithoutAo.put(blend, finder.ambientOcclusion(TriState.FALSE).find()); + materialsWithAo.put(blend, finder.ambientOcclusion(TriState.DEFAULT).find()); //not "true" since that *forces* AO, i just want to *allow* AO } Sprite defaultSprite = spriteLookup.apply(DEFAULT_SPRITE_ID); if(defaultSprite == null) throw new IllegalStateException("Couldn't locate " + DEFAULT_SPRITE_ID + " !"); - this.defaultAppearance = new SingleSpriteAppearance(defaultSprite, blockMaterials.get(BlendMode.CUTOUT), serialNumber.getAndIncrement()); + this.defaultAppearance = new SingleSpriteAppearance(defaultSprite, materialsWithoutAo.get(BlendMode.CUTOUT), serialNumber.getAndIncrement()); Sprite barrier = spriteLookup.apply(BARRIER_SPRITE_ID); if(barrier == null) barrier = defaultSprite; //eh - this.barrierItemAppearance = new SingleSpriteAppearance(barrier, blockMaterials.get(BlendMode.CUTOUT), serialNumber.getAndIncrement()); + this.barrierItemAppearance = new SingleSpriteAppearance(barrier, materialsWithoutAo.get(BlendMode.CUTOUT), serialNumber.getAndIncrement()); } @ApiStatus.Internal //shouldn't have made this public, just maintaining abi compat @@ -55,7 +59,9 @@ public class TemplateAppearanceManager { private final ConcurrentHashMap appearanceCache = new ConcurrentHashMap<>(); //Mutable, append-only cache private final AtomicInteger serialNumber = new AtomicInteger(0); //Mutable - private final EnumMap blockMaterials = new EnumMap<>(BlendMode.class); //Immutable contents + + private final EnumMap materialsWithAo = new EnumMap<>(BlendMode.class); + private final EnumMap materialsWithoutAo = new EnumMap<>(BlendMode.class); //Immutable contents public TemplateAppearance getDefaultAppearance() { return defaultAppearance; @@ -65,8 +71,9 @@ public class TemplateAppearanceManager { return appearanceCache.computeIfAbsent(state, this::computeAppearance); } - public RenderMaterial getCachedMaterial(BlockState state) { - return blockMaterials.get(BlendMode.fromRenderLayer(RenderLayers.getBlockLayer(state))); + public RenderMaterial getCachedMaterial(BlockState state, boolean ao) { + Map m = ao ? materialsWithAo : materialsWithoutAo; + return m.get(BlendMode.fromRenderLayer(RenderLayers.getBlockLayer(state))); } //I'm pretty sure ConcurrentHashMap semantics allow for this function to be called multiple times on the same key, on different threads. @@ -152,25 +159,28 @@ public class TemplateAppearanceManager { sprites, bakeFlags, hasColorMask, - getCachedMaterial(state), + getCachedMaterial(state, true), + getCachedMaterial(state, false), serialNumber.getAndIncrement() ); } - @SuppressWarnings("ClassCanBeRecord") private static final class ComputedApperance implements TemplateAppearance { private final Sprite @NotNull[] sprites; private final int @NotNull[] bakeFlags; private final byte hasColorMask; - private final RenderMaterial mat; private final int id; + private final RenderMaterial matWithAo; + private final RenderMaterial matWithoutAo; - private ComputedApperance(@NotNull Sprite @NotNull[] sprites, int @NotNull[] bakeFlags, byte hasColorMask, RenderMaterial mat, int id) { + private ComputedApperance(@NotNull Sprite @NotNull[] sprites, int @NotNull[] bakeFlags, byte hasColorMask, RenderMaterial withAo, RenderMaterial withoutAo, int id) { this.sprites = sprites; this.bakeFlags = bakeFlags; this.hasColorMask = hasColorMask; - this.mat = mat; this.id = id; + + this.matWithAo = withAo; + this.matWithoutAo = withoutAo; } @Override @@ -179,8 +189,8 @@ public class TemplateAppearanceManager { } @Override - public @NotNull RenderMaterial getRenderMaterial() { - return mat; + public @NotNull RenderMaterial getRenderMaterial(boolean ao) { + return ao ? matWithAo : matWithoutAo; } @Override @@ -213,7 +223,7 @@ public class TemplateAppearanceManager { @Override public String toString() { - return "ComputedApperance{sprites=%s, bakeFlags=%s, hasColorMask=%s, mat=%s, id=%d}".formatted(Arrays.toString(sprites), Arrays.toString(bakeFlags), hasColorMask, mat, id); + return "ComputedApperance{sprites=%s, bakeFlags=%s, hasColorMask=%s, matWithoutAo=%s, matWithAo=%s, id=%d}".formatted(Arrays.toString(sprites), Arrays.toString(bakeFlags), hasColorMask, matWithoutAo, matWithAo, id); } } @@ -235,7 +245,7 @@ public class TemplateAppearanceManager { } @Override - public @NotNull RenderMaterial getRenderMaterial() { + public @NotNull RenderMaterial getRenderMaterial(boolean ao) { return mat; } diff --git a/src/main/java/io/github/cottonmc/templates/model/UnbakedAutoRetexturedModel.java b/src/main/java/io/github/cottonmc/templates/model/UnbakedAutoRetexturedModel.java index 36432cb..5d42691 100644 --- a/src/main/java/io/github/cottonmc/templates/model/UnbakedAutoRetexturedModel.java +++ b/src/main/java/io/github/cottonmc/templates/model/UnbakedAutoRetexturedModel.java @@ -39,6 +39,12 @@ public class UnbakedAutoRetexturedModel implements UnbakedModel { protected final Identifier parent; protected final BlockState itemModelState; + protected boolean ao = true; + public UnbakedAutoRetexturedModel disableAo() { + ao = false; + return this; + } + @Override public Collection getModelDependencies() { return Collections.singletonList(parent); @@ -58,7 +64,8 @@ public class UnbakedAutoRetexturedModel implements UnbakedModel { baker.bake(parent, modelBakeSettings), TemplatesClient.provider.getOrCreateTemplateApperanceManager(spriteLookup), modelBakeSettings, - itemModelState + itemModelState, + ao ) { @Override protected Mesh getBaseMesh(BlockState state) { @@ -70,7 +77,7 @@ public class UnbakedAutoRetexturedModel implements UnbakedModel { Renderer r = TemplatesClient.getFabricRenderer(); MeshBuilder builder = r.meshBuilder(); QuadEmitter emitter = builder.getEmitter(); - RenderMaterial mat = tam.getCachedMaterial(state); + RenderMaterial mat = tam.getCachedMaterial(state, false); Random rand = Random.create(42); diff --git a/src/main/java/io/github/cottonmc/templates/model/UnbakedJsonRetexturedModel.java b/src/main/java/io/github/cottonmc/templates/model/UnbakedJsonRetexturedModel.java index d3ad6ac..dd0c782 100644 --- a/src/main/java/io/github/cottonmc/templates/model/UnbakedJsonRetexturedModel.java +++ b/src/main/java/io/github/cottonmc/templates/model/UnbakedJsonRetexturedModel.java @@ -42,6 +42,12 @@ public class UnbakedJsonRetexturedModel implements UnbakedModel { protected final Identifier parent; protected final BlockState itemModelState; + protected boolean ao = true; + public UnbakedJsonRetexturedModel disableAo() { + ao = false; + return this; + } + @Override public Collection getModelDependencies() { return Collections.singletonList(parent); @@ -69,7 +75,8 @@ public class UnbakedJsonRetexturedModel implements UnbakedModel { baker.bake(parent, modelBakeSettings), TemplatesClient.provider.getOrCreateTemplateApperanceManager(spriteLookup), modelBakeSettings, - itemModelState + itemModelState, + ao ) { @Override protected Mesh getBaseMesh(BlockState state) { @@ -81,7 +88,7 @@ public class UnbakedJsonRetexturedModel implements UnbakedModel { Renderer r = TemplatesClient.getFabricRenderer(); MeshBuilder builder = r.meshBuilder(); QuadEmitter emitter = builder.getEmitter(); - RenderMaterial mat = tam.getCachedMaterial(state); + RenderMaterial mat = tam.getCachedMaterial(state, false); Random rand = Random.create(42); diff --git a/src/main/java/io/github/cottonmc/templates/model/UnbakedMeshRetexturedModel.java b/src/main/java/io/github/cottonmc/templates/model/UnbakedMeshRetexturedModel.java index 7a46452..df0fc48 100644 --- a/src/main/java/io/github/cottonmc/templates/model/UnbakedMeshRetexturedModel.java +++ b/src/main/java/io/github/cottonmc/templates/model/UnbakedMeshRetexturedModel.java @@ -30,6 +30,12 @@ public class UnbakedMeshRetexturedModel implements UnbakedModel { protected final Identifier parent; protected final Function, Mesh> baseMeshFactory; + protected boolean ao = true; + public UnbakedMeshRetexturedModel disableAo() { + ao = false; + return this; + } + @Override public Collection getModelDependencies() { return Collections.singletonList(parent); @@ -48,7 +54,8 @@ public class UnbakedMeshRetexturedModel implements UnbakedModel { baker.bake(parent, modelBakeSettings), TemplatesClient.provider.getOrCreateTemplateApperanceManager(spriteLookup), modelBakeSettings, - Blocks.AIR.getDefaultState() + Blocks.AIR.getDefaultState(), + ao ) { @Override protected Mesh getBaseMesh(BlockState state) {