Skip to content

Commit

Permalink
Port to 1.21 and make it so the normal check can't throw a NPE (Chise…
Browse files Browse the repository at this point in the history
  • Loading branch information
pupnewfster committed Jun 12, 2024
1 parent 35f47c5 commit f7e75ee
Show file tree
Hide file tree
Showing 14 changed files with 100 additions and 89 deletions.
8 changes: 8 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ tasks.named('jar', Jar).configure { Jar jar ->

repositories {
mavenLocal()
maven {
name 'Maven for PR #1076' // https://github.com/neoforged/NeoForge/pull/1076
url 'https://prmaven.neoforged.net/NeoForge/pr1076'
content {
includeModule('net.neoforged', 'testframework')
includeModule('net.neoforged', 'neoforge')
}
}
}

dependencies {
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod_version=1.1.11
minecraft_version=1.20.6
forge_version=20.6.113-beta
minecraft_version=1.21
forge_version=21.0.0-alpha.1.21-rc1.20240611.222608

curse_type=beta
projectId=267602
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/team/chisel/ctm/CTM.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public CTM(ModContainer modContainer, IEventBus modBus) {
}

private void modelRegistry(ModelEvent.RegisterGeometryLoaders event) {
event.register(new ResourceLocation(MOD_ID, "ctm"), ModelLoaderCTM.INSTANCE);
event.register(ResourceLocation.fromNamespaceAndPath(MOD_ID, "ctm"), ModelLoaderCTM.INSTANCE);
}

private void imc(InterModEnqueueEvent event) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public Overrides() {
@SneakyThrows
public BakedModel resolve(BakedModel originalModel, ItemStack stack, ClientLevel world, LivingEntity entity, int unknown) {
ModelResourceLocation mrl = ModelUtil.getMesh(stack);
if (mrl == ModelBakery.MISSING_MODEL_LOCATION) {
if (mrl == ModelBakery.MISSING_MODEL_VARIANT) {
// this must be a missing/invalid model
return Minecraft.getInstance().getBlockRenderer().getBlockModelShaper().getModelManager().getMissingModel();
}
Expand Down
18 changes: 9 additions & 9 deletions src/main/java/team/chisel/ctm/client/model/ModelCTM.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public ModelCTM(BlockModel modelinfo, Int2ObjectMap<JsonElement> overrides) thro
for (Int2ObjectMap.Entry<JsonElement> e : this.overrides.int2ObjectEntrySet()) {
IMetadataSectionCTM meta = null;
if (e.getValue().isJsonPrimitive() && e.getValue().getAsJsonPrimitive().isString()) {
ResourceLocation rl = new ResourceLocation(e.getValue().getAsString());
ResourceLocation rl = ResourceLocation.parse(e.getValue().getAsString());
meta = ResourceUtil.getMetadata(ResourceUtil.spriteToAbsolute(rl)).orElse(null); // TODO lazy null
textureDependencies.add(rl);
} else if (e.getValue().isJsonObject()) {
Expand All @@ -106,20 +106,20 @@ public ModelCTM(BlockModel modelinfo, Int2ObjectMap<JsonElement> overrides) thro
}

@Override
public BakedModel bake(IGeometryBakingContext context, ModelBaker bakery, Function<Material, TextureAtlasSprite> spriteGetter, ModelState modelState, ItemOverrides overrides, ResourceLocation modelLocation) {
return bake(bakery, spriteGetter, modelState, modelLocation);
public BakedModel bake(IGeometryBakingContext context, ModelBaker bakery, Function<Material, TextureAtlasSprite> spriteGetter, ModelState modelState, ItemOverrides overrides) {
return bake(bakery, spriteGetter, modelState);
}

private static final ItemModelGenerator ITEM_MODEL_GENERATOR = new ItemModelGenerator();

public BakedModel bake(ModelBaker bakery, Function<Material, TextureAtlasSprite> spriteGetter, ModelState modelTransform, ResourceLocation modelLocation) {
public BakedModel bake(ModelBaker bakery, Function<Material, TextureAtlasSprite> spriteGetter, ModelState modelTransform) {
BakedModel parent;
if (modelinfo != null && modelinfo.getRootModel() == ModelBakery.GENERATION_MARKER) { // Apply same special case that ModelBakery does
return ITEM_MODEL_GENERATOR.generateBlockModel(spriteGetter, modelinfo).bake(bakery, modelinfo, spriteGetter, modelTransform, modelLocation, false);
return ITEM_MODEL_GENERATOR.generateBlockModel(spriteGetter, modelinfo).bake(bakery, modelinfo, spriteGetter, modelTransform, false);
} else {
initializeOverrides(spriteGetter);
this.textureDependencies.forEach(t -> initializeTexture(new Material(TextureAtlas.LOCATION_BLOCKS, t), spriteGetter));
parent = vanillamodel.bake(bakery, mat -> initializeTexture(mat, spriteGetter), modelTransform, modelLocation);
parent = vanillamodel.bake(bakery, mat -> initializeTexture(mat, spriteGetter), modelTransform);
if (!isInitialized()) {
this.spriteOverrides = new Int2ObjectOpenHashMap<>();
this.textureOverrides = new HashMap<>();
Expand Down Expand Up @@ -157,18 +157,18 @@ private void initializeOverrides(Function<Material, TextureAtlasSprite> spriteGe
// Convert all primitive values into sprites
for (Int2ObjectMap.Entry<JsonElement> e : overrides.int2ObjectEntrySet()) {
if (e.getValue().isJsonPrimitive() && e.getValue().getAsJsonPrimitive().isString()) {
TextureAtlasSprite override = spriteGetter.apply(new Material(TextureAtlas.LOCATION_BLOCKS, new ResourceLocation(e.getValue().getAsString())));
TextureAtlasSprite override = spriteGetter.apply(new Material(TextureAtlas.LOCATION_BLOCKS, ResourceLocation.parse(e.getValue().getAsString())));
spriteOverrides.put(e.getIntKey(), override);
}
}
}
if (textureOverrides == null) {
textureOverrides = new HashMap<>();
for (Int2ObjectMap.Entry<IMetadataSectionCTM> e : metaOverrides.int2ObjectEntrySet()) {
List<BlockElementFace> matches = modelinfo.getElements().stream().flatMap(b -> b.faces.values().stream()).filter(b -> b.tintIndex == e.getIntKey()).toList();
List<BlockElementFace> matches = modelinfo.getElements().stream().flatMap(b -> b.faces.values().stream()).filter(b -> b.tintIndex() == e.getIntKey()).toList();
Multimap<Material, BlockElementFace> bySprite = HashMultimap.create();
// TODO 1.15 this isn't right
matches.forEach(part -> bySprite.put(modelinfo.textureMap.getOrDefault(part.texture.substring(1), Either.right(part.texture)).left().get(), part));
matches.forEach(part -> bySprite.put(modelinfo.textureMap.getOrDefault(part.texture().substring(1), Either.right(part.texture())).left().get(), part));
for (var e2 : bySprite.asMap().entrySet()) {
ResourceLocation texLoc = e2.getKey().sprite().contents().name();
TextureAtlasSprite override = getOverrideSprite(e.getIntKey());
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/team/chisel/ctm/client/model/ModelUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static ModelResourceLocation getMesh(ItemStack stack) {
if (shaper instanceof RegistryAwareItemModelShaper registryAwareShaper) {
return registryAwareShaper.getLocation(stack);
}
return ModelBakery.MISSING_MODEL_LOCATION;
return ModelBakery.MISSING_MODEL_VARIANT;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ default ICTMTexture<?> makeTexture(TextureAtlasSprite sprite, Function<Material,
IMetadataSectionCTM meta = this;
boolean hasProxy = getProxy() != null;
if (hasProxy) {
TextureAtlasSprite proxySprite = bakedTextureGetter.apply(new Material(TextureAtlas.LOCATION_BLOCKS, new ResourceLocation(getProxy())));
TextureAtlasSprite proxySprite = bakedTextureGetter.apply(new Material(TextureAtlas.LOCATION_BLOCKS, ResourceLocation.parse(getProxy())));
try {
meta = ResourceUtil.getMetadata(proxySprite).orElse(new V1());
sprite = proxySprite;
Expand Down Expand Up @@ -132,7 +132,7 @@ public static IMetadataSectionCTM fromJson(JsonObject obj) throws JsonParseExcep
for (int i = 0; i < texturesArr.size(); i++) {
JsonElement e = texturesArr.get(i);
if (e.isJsonPrimitive() && e.getAsJsonPrimitive().isString()) {
ret.additionalTextures[i] = new ResourceLocation(e.getAsString());
ret.additionalTextures[i] = ResourceLocation.parse(e.getAsString());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ static class PredicateDeserializer implements JsonDeserializer<Predicate<BlockSt
public Predicate<BlockState> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (json.isJsonObject()) {
JsonObject obj = json.getAsJsonObject();
Block block = BuiltInRegistries.BLOCK.get(new ResourceLocation(GsonHelper.getAsString(obj, "block")));
Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(GsonHelper.getAsString(obj, "block")));
if (block == Blocks.AIR) {
return EMPTY;
}
Expand Down
75 changes: 33 additions & 42 deletions src/main/java/team/chisel/ctm/client/util/Quad.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.client.model.pipeline.QuadBakingVertexConsumer;
import team.chisel.ctm.api.texture.ISubmap;

Expand Down Expand Up @@ -297,7 +296,7 @@ public Quad subsect(ISubmap submap) {
}
}

Vec3[] positions = new Vec3[vertices.length];
Vector3f[] positions = new Vector3f[vertices.length];
float[][] uvs = new float[vertices.length][];
for (int i = 0; i < vertices.length; i++) {
int idx = (firstIndex + i) % vertices.length;
Expand All @@ -307,14 +306,15 @@ public Quad subsect(ISubmap submap) {
}

var origin = positions[0];
var n1 = positions[1].subtract(origin);
var n2 = positions[2].subtract(origin);
var normalVec = n1.cross(n2).normalize();
Direction normal = Direction.fromDelta((int) normalVec.x, (int) normalVec.y, (int) normalVec.z);
var n1 = positions[1].sub(origin, new Vector3f());
var n2 = positions[2].sub(origin, new Vector3f());
var normalVec = n1.cross(n2, new Vector3f()).normalize();

Direction normal = Direction.getNearest(normalVec.x, normalVec.y, normalVec.z);
TextureAtlasSprite sprite = getUvs().getSprite();

var xy = new double[positions.length][2];
var newXy = new double[positions.length][2];
var xy = new float[positions.length][2];
var newXy = new float[positions.length][2];
for (int i = 0; i < positions.length; i++) {
switch (normal.getAxis()) {
case Y -> {
Expand Down Expand Up @@ -455,7 +455,7 @@ public Quad setLight(int blockLight, int skyLight) {

@SuppressWarnings("null")
public BakedQuad rebake() {
var builder = new QuadBakingVertexConsumer.Buffered();
var builder = new QuadBakingVertexConsumer();
builder.setDirection(this.builder.quadOrientation);
builder.setTintIndex(this.builder.quadTint);
builder.setShade(this.builder.applyDiffuseLighting);
Expand All @@ -465,7 +465,7 @@ public BakedQuad rebake() {
vertex.write(builder);
}

return builder.getQuad();
return builder.bakeQuad();
}

public Quad transformUVs(TextureAtlasSprite sprite) {
Expand Down Expand Up @@ -533,7 +533,7 @@ public static class Builder implements VertexConsumer {
private boolean applyAmbientOcclusion;

private final VertexData[] vertices = new VertexData[4];
private VertexData vertex = new VertexData();
private boolean building = false;
private int vertexIndex = 0;

public void copyFrom(BakedQuad baked) {
Expand All @@ -545,72 +545,63 @@ public void copyFrom(BakedQuad baked) {
}

public Quad build() {
if (!building || ++vertexIndex != 4) {
throw new IllegalStateException("Not enough vertices available. Vertices in buffer: " + vertexIndex);
}
return new Quad(vertices, this, getSprite());
}

@NotNull
@Override
public VertexConsumer vertex(double x, double y, double z) {
vertex.pos(x, y, z);
public VertexConsumer addVertex(float x, float y, float z) {
if (building) {
if (++vertexIndex > 4) {
throw new IllegalStateException("Expected quad export after fourth vertex");
}
}
building = true;
vertices[vertexIndex] = new VertexData().pos(x, y, z);
return this;
}

@NotNull
@Override
public VertexConsumer color(int red, int green, int blue, int alpha) {
vertex.color(red, green, blue, alpha);
public VertexConsumer setColor(int red, int green, int blue, int alpha) {
vertices[vertexIndex].color(red, green, blue, alpha);
return this;
}

@NotNull
@Override
public VertexConsumer uv(float u, float v) {
vertex.texRaw(u, v);
public VertexConsumer setUv(float u, float v) {
vertices[vertexIndex].texRaw(u, v);
return this;
}

@NotNull
@Override
public VertexConsumer overlayCoords(int u, int v) {
vertex.overlay(u, v);
public VertexConsumer setUv1(int u, int v) {
vertices[vertexIndex].overlay(u, v);
return this;
}

@NotNull
@Override
public VertexConsumer uv2(int u, int v) {
vertex.lightRaw(u, v);
public VertexConsumer setUv2(int u, int v) {
vertices[vertexIndex].lightRaw(u, v);
return this;
}

@NotNull
@Override
public VertexConsumer normal(float x, float y, float z) {
vertex.normal(x, y, z);
public VertexConsumer setNormal(float x, float y, float z) {
vertices[vertexIndex].normal(x, y, z);
return this;
}

@Override
public void endVertex() {
if (vertexIndex < vertices.length) {
vertices[vertexIndex++] = vertex;
vertex = new VertexData();
}
}

@Override
public void defaultColor(int red, int green, int blue, int alpha) {
//We don't support having a default color
}

@Override
public void unsetDefaultColor() {
//We don't support having a default color
}

@Override
public VertexConsumer misc(VertexFormatElement element, int... rawData) {
vertex.misc(element, Arrays.copyOf(rawData, rawData.length));
vertices[vertexIndex].misc(element, Arrays.copyOf(rawData, rawData.length));
return this;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.Map;
import java.util.Set;

import net.minecraft.client.resources.model.ModelResourceLocation;
import org.apache.logging.log4j.message.ParameterizedMessage;

import com.google.common.collect.HashMultimap;
Expand Down Expand Up @@ -35,7 +36,7 @@ public enum TextureMetadataHandler {

INSTANCE;

private final Object2BooleanMap<ResourceLocation> wrappedModels = new Object2BooleanLinkedOpenHashMap<>();
private final Object2BooleanMap<ModelResourceLocation> wrappedModels = new Object2BooleanLinkedOpenHashMap<>();
private final Multimap<ResourceLocation, Material> scrapedTextures = HashMultimap.create();

public void textureScraped(ResourceLocation modelLocation, Material material) {
Expand Down Expand Up @@ -108,11 +109,21 @@ public void textureScraped(ResourceLocation modelLocation, Material material) {
@SubscribeEvent(priority = EventPriority.LOWEST) // low priority to capture all event-registered models
@SneakyThrows
public void onModelBake(ModelEvent.ModifyBakingResult event) {
Map<ResourceLocation, UnbakedModel> stateModels = ObfuscationReflectionHelper.getPrivateValue(ModelBakery.class, event.getModelBakery(), "unbakedCache");
Map<ResourceLocation, BakedModel> models = event.getModels();
for (Map.Entry<ResourceLocation, BakedModel> entry : models.entrySet()) {
ResourceLocation rl = entry.getKey();
UnbakedModel rootModel = stateModels.get(rl);
ModelBakery modelBakery = event.getModelBakery();
Map<ModelResourceLocation, UnbakedModel> topLevelModels = ObfuscationReflectionHelper.getPrivateValue(ModelBakery.class, modelBakery, "topLevelModels");
Map<ResourceLocation, UnbakedModel> unbakedCache = ObfuscationReflectionHelper.getPrivateValue(ModelBakery.class, modelBakery, "unbakedCache");
Map<ModelResourceLocation, BakedModel> models = event.getModels();
for (Map.Entry<ModelResourceLocation, BakedModel> entry : models.entrySet()) {
ModelResourceLocation mrl = entry.getKey();
ResourceLocation rl = mrl.id();
UnbakedModel rootModel = topLevelModels.get(mrl);
if (rootModel == null) {
rootModel = unbakedCache.get(rl);
if (rootModel != null) {
//TODO - 1.21: Remove this after testing against more complex models to validate if we need to do this or not
CTM.logger.info("Modify baking unbaked cache has an element top level doesn't: {}, {}", rl, mrl);
}
}
if (rootModel != null) {
BakedModel baked = entry.getValue();
if (baked instanceof AbstractCTMBakedModel) {
Expand All @@ -125,13 +136,14 @@ public void onModelBake(ModelEvent.ModifyBakingResult event) {
Set<ResourceLocation> seenModels = new HashSet<>();
dependencies.push(rl);
seenModels.add(rl);
boolean shouldWrap = wrappedModels.getOrDefault(rl, false);
boolean shouldWrap = wrappedModels.getOrDefault(mrl, false);
// Breadth-first loop through dependencies, exiting as soon as a CTM texture is found, and skipping duplicates/cycles
while (!shouldWrap && !dependencies.isEmpty()) {
ResourceLocation dep = dependencies.pop();
UnbakedModel model;
try {
model = dep == rl ? rootModel : event.getModelBakery().getModel(dep);
//TODO - 1.21: Evaluate if this should be using getModel or something that will get the dep as a root model?
model = dep == rl ? rootModel : modelBakery.getModel(dep);
} catch (Exception e) {
continue;
}
Expand Down Expand Up @@ -159,7 +171,7 @@ public void onModelBake(ModelEvent.ModifyBakingResult event) {
CTM.logger.error(new ParameterizedMessage("Error loading model dependency {} for model {}. Skipping...", dep, rl), e);
}
}
wrappedModels.put(rl, shouldWrap);
wrappedModels.put(mrl, shouldWrap);
if (shouldWrap) {
try {
entry.setValue(wrap(rootModel, baked));
Expand Down Expand Up @@ -187,7 +199,7 @@ public void onModelBake(ModelEvent.BakingCompleted event) {
baked.getModel() instanceof ModelCTM ctmModel &&
!ctmModel.isInitialized()) {
var baker = event.getModelBakery().new ModelBakerImpl((rl, m) -> m.sprite(), e.getKey());
ctmModel.bake(baker, Material::sprite, BlockModelRotation.X0_Y0, e.getKey());
ctmModel.bake(baker, Material::sprite, BlockModelRotation.X0_Y0);
//Note: We have to clear the cache after baking each model to ensure that we can initialize and capture any textures
// that might be done by parent models
cache.clear();
Expand Down
Loading

0 comments on commit f7e75ee

Please sign in to comment.