Clunkily fix the item model
This commit is contained in:
parent
24c8c97f00
commit
b257241b5e
@ -16,8 +16,6 @@ Template blocks can be placed in the world, then right-clicked with a full-size
|
|||||||
|
|
||||||
## Todo
|
## Todo
|
||||||
|
|
||||||
* The conceit used in SlopeBakedModel (update mutable state, then bake the mesh) might be inherently flawed - it's not threadsafe
|
|
||||||
* Fix the item model lol, broke it with the new system (might need a ModelLoadingRegistry registerVariantProvider as a last resort)
|
|
||||||
* Re-generalize the model system (I removed a layer of indirection while rewriting it, so it's just slopes now)
|
* Re-generalize the model system (I removed a layer of indirection while rewriting it, so it's just slopes now)
|
||||||
* Upside-down slopes would be nice...
|
* Upside-down slopes would be nice...
|
||||||
* Pass UVs as part of the mesh and retexture them at runtime too
|
* Pass UVs as part of the mesh and retexture them at runtime too
|
||||||
|
@ -41,10 +41,12 @@ public class TemplatesClient implements ClientModInitializer {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ModelLoadingRegistry.INSTANCE.registerResourceProvider(rm -> provider);
|
ModelLoadingRegistry.INSTANCE.registerResourceProvider(rm -> provider); //block models
|
||||||
|
ModelLoadingRegistry.INSTANCE.registerVariantProvider(rm -> provider); //item models
|
||||||
|
|
||||||
BlockRenderLayerMap.INSTANCE.putBlock(Templates.SLOPE, RenderLayer.getCutout());
|
BlockRenderLayerMap.INSTANCE.putBlock(Templates.SLOPE, RenderLayer.getCutout());
|
||||||
|
|
||||||
provider.addTemplateModel(Templates.id("slope_special"), SlopeUnbakedModel::new);
|
provider.addTemplateModel(Templates.id("slope_special"), SlopeUnbakedModel::new);
|
||||||
|
provider.assignItemModel(Templates.id("slope_special"), Templates.SLOPE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ package io.github.cottonmc.templates.model;
|
|||||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
|
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
|
||||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||||
import net.minecraft.util.math.AffineTransformation;
|
import net.minecraft.util.math.AffineTransformation;
|
||||||
|
import net.minecraft.util.math.AffineTransformations;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.joml.Vector4f;
|
import org.joml.Vector4f;
|
||||||
@ -12,6 +14,8 @@ public record AffineQuadTransformer(Matrix4f affineMatrix) implements RenderCont
|
|||||||
this(aff.getMatrix());
|
this(aff.getMatrix());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final AffineQuadTransformer EAST = new AffineQuadTransformer(AffineTransformations.DIRECTION_ROTATIONS.get(Direction.EAST));
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean transform(MutableQuadView quad) {
|
public boolean transform(MutableQuadView quad) {
|
||||||
Vector3f pos3 = new Vector3f();
|
Vector3f pos3 = new Vector3f();
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package io.github.cottonmc.templates.model;
|
package io.github.cottonmc.templates.model;
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.renderer.v1.RendererAccess;
|
|
||||||
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
|
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
|
||||||
import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
|
import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
|
||||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||||
@ -19,12 +18,14 @@ public final class SlopeBakedModel extends ForwardingBakedModel {
|
|||||||
this.wrapped = baseModel;
|
this.wrapped = baseModel;
|
||||||
|
|
||||||
this.preparer = new SlopeQuadTransformFactory(tam);
|
this.preparer = new SlopeQuadTransformFactory(tam);
|
||||||
this.affineTransformer = new AffineQuadTransformer(aff);
|
this.blockAffineTransformer = new AffineQuadTransformer(aff);
|
||||||
|
this.itemAffineTransformer = AffineQuadTransformer.EAST; //Makes items point the same way as stairs. Kinda clunky
|
||||||
this.baseMesh = SlopeBaseMesh.make();
|
this.baseMesh = SlopeBaseMesh.make();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final TemplateQuadTransformFactory preparer;
|
private final TemplateQuadTransformFactory preparer;
|
||||||
private final RenderContext.QuadTransform affineTransformer;
|
private final AffineQuadTransformer blockAffineTransformer;
|
||||||
|
private final AffineQuadTransformer itemAffineTransformer;
|
||||||
private final Mesh baseMesh;
|
private final Mesh baseMesh;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -34,7 +35,7 @@ public final class SlopeBakedModel extends ForwardingBakedModel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
|
public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
|
||||||
context.pushTransform(affineTransformer);
|
context.pushTransform(blockAffineTransformer);
|
||||||
context.pushTransform(preparer.blockTransformer(blockView, state, pos, randomSupplier));
|
context.pushTransform(preparer.blockTransformer(blockView, state, pos, randomSupplier));
|
||||||
context.meshConsumer().accept(baseMesh);
|
context.meshConsumer().accept(baseMesh);
|
||||||
context.popTransform();
|
context.popTransform();
|
||||||
@ -43,7 +44,7 @@ public final class SlopeBakedModel extends ForwardingBakedModel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) {
|
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) {
|
||||||
context.pushTransform(affineTransformer);
|
context.pushTransform(itemAffineTransformer);
|
||||||
context.pushTransform(preparer.itemTransformer(stack, randomSupplier));
|
context.pushTransform(preparer.itemTransformer(stack, randomSupplier));
|
||||||
context.meshConsumer().accept(baseMesh);
|
context.meshConsumer().accept(baseMesh);
|
||||||
context.popTransform();
|
context.popTransform();
|
||||||
|
@ -3,7 +3,11 @@ package io.github.cottonmc.templates.model;
|
|||||||
import net.fabricmc.fabric.api.client.model.ModelProviderContext;
|
import net.fabricmc.fabric.api.client.model.ModelProviderContext;
|
||||||
import net.fabricmc.fabric.api.client.model.ModelProviderException;
|
import net.fabricmc.fabric.api.client.model.ModelProviderException;
|
||||||
import net.fabricmc.fabric.api.client.model.ModelResourceProvider;
|
import net.fabricmc.fabric.api.client.model.ModelResourceProvider;
|
||||||
|
import net.fabricmc.fabric.api.client.model.ModelVariantProvider;
|
||||||
import net.minecraft.client.render.model.UnbakedModel;
|
import net.minecraft.client.render.model.UnbakedModel;
|
||||||
|
import net.minecraft.client.util.ModelIdentifier;
|
||||||
|
import net.minecraft.item.ItemConvertible;
|
||||||
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@ -11,8 +15,10 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class TemplateModelVariantProvider implements ModelResourceProvider {
|
public class TemplateModelVariantProvider implements ModelResourceProvider, ModelVariantProvider {
|
||||||
private final Map<Identifier, Supplier<UnbakedModel>> factories = new HashMap<>();
|
private final Map<Identifier, Supplier<UnbakedModel>> factories = new HashMap<>();
|
||||||
|
private final Map<ModelIdentifier, Identifier> itemAssignments = new HashMap<>();
|
||||||
|
|
||||||
private final Map<Identifier, UnbakedModel> cache = new HashMap<>();
|
private final Map<Identifier, UnbakedModel> cache = new HashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -32,10 +38,36 @@ public class TemplateModelVariantProvider implements ModelResourceProvider {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//For blocks, you can point the game directly at the custom model in the blockstate json file.
|
||||||
|
//Item models don't have that layer of indirection; it always wants to load the hardcoded "item:id#inventory" model.
|
||||||
|
//You *would* be able to create a model json for it and set the "parent" field to the custom model,
|
||||||
|
//but json models are never allowed to have non-json models as a parent, and template unbaked models are not json models. Ah well.
|
||||||
|
//So, instead, we use a ModelVariantProvider to clunkily redirect the item:id#inventory model to the blockmodel.
|
||||||
|
//Not my favorite solution (for one, it precludes setting custom rotations in the item model) but we'll live.
|
||||||
|
@Override
|
||||||
|
public @Nullable UnbakedModel loadModelVariant(ModelIdentifier modelId, ModelProviderContext context) throws ModelProviderException {
|
||||||
|
Identifier customModelId = itemAssignments.get(modelId);
|
||||||
|
return customModelId == null ? null : loadModelResource(customModelId, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// "public api"
|
||||||
|
|
||||||
public void addTemplateModel(Identifier id, Supplier<UnbakedModel> modelFactory) {
|
public void addTemplateModel(Identifier id, Supplier<UnbakedModel> modelFactory) {
|
||||||
factories.put(id, modelFactory);
|
factories.put(id, modelFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void assignItemModel(Identifier templateModelId, ModelIdentifier... modelIds) {
|
||||||
|
for(ModelIdentifier modelId : modelIds) itemAssignments.put(modelId, templateModelId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assignItemModel(Identifier templateModelId, Identifier... itemIds) {
|
||||||
|
for(Identifier itemId : itemIds) itemAssignments.put(new ModelIdentifier(itemId, "inventory"), templateModelId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assignItemModel(Identifier templateModelId, ItemConvertible... itemConvs) {
|
||||||
|
for(ItemConvertible itemConv : itemConvs) assignItemModel(templateModelId, Registries.ITEM.getId(itemConv.asItem()));
|
||||||
|
}
|
||||||
|
|
||||||
public void dumpCache() {
|
public void dumpCache() {
|
||||||
cache.clear();
|
cache.clear();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user