Enable AO on all blocks except the slopes
This commit is contained in:
parent
93e385a856
commit
78e3e82bbe
@ -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.)
|
@ -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()
|
||||
|
@ -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")));
|
||||
|
@ -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<Direction, Direction> 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<CacheKey, Mesh> 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.
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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<SpriteIdentifier, Sprite> 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<BlockState, TemplateAppearance> appearanceCache = new ConcurrentHashMap<>(); //Mutable, append-only cache
|
||||
private final AtomicInteger serialNumber = new AtomicInteger(0); //Mutable
|
||||
private final EnumMap<BlendMode, RenderMaterial> blockMaterials = new EnumMap<>(BlendMode.class); //Immutable contents
|
||||
|
||||
private final EnumMap<BlendMode, RenderMaterial> materialsWithAo = new EnumMap<>(BlendMode.class);
|
||||
private final EnumMap<BlendMode, RenderMaterial> 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<BlendMode, RenderMaterial> 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;
|
||||
}
|
||||
|
||||
|
@ -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<Identifier> 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);
|
||||
|
||||
|
@ -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<Identifier> 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);
|
||||
|
||||
|
@ -30,6 +30,12 @@ public class UnbakedMeshRetexturedModel implements UnbakedModel {
|
||||
protected final Identifier parent;
|
||||
protected final Function<Function<SpriteIdentifier, Sprite>, Mesh> baseMeshFactory;
|
||||
|
||||
protected boolean ao = true;
|
||||
public UnbakedMeshRetexturedModel disableAo() {
|
||||
ao = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Identifier> 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) {
|
||||
|
Loading…
Reference in New Issue
Block a user