diff --git a/src/main/java/io/github/cottonmc/templates/TemplatesClient.java b/src/main/java/io/github/cottonmc/templates/TemplatesClient.java index c6e68db..a5ed8cd 100644 --- a/src/main/java/io/github/cottonmc/templates/TemplatesClient.java +++ b/src/main/java/io/github/cottonmc/templates/TemplatesClient.java @@ -1,7 +1,6 @@ package io.github.cottonmc.templates; import io.github.cottonmc.templates.model.SlopeUnbakedModel; -import io.github.cottonmc.templates.model.TemplateModelVariantProvider; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry; @@ -20,7 +19,7 @@ import org.jetbrains.annotations.NotNull; import java.util.Objects; public class TemplatesClient implements ClientModInitializer { - public static TemplateModelVariantProvider provider = new TemplateModelVariantProvider(); + public static TemplatesModelProvider provider = new TemplatesModelProvider(); public static @NotNull Renderer getFabricRenderer() { return Objects.requireNonNull(RendererAccess.INSTANCE.getRenderer(), "A Fabric Rendering API implementation is required to use Templates!"); diff --git a/src/main/java/io/github/cottonmc/templates/model/TemplateModelVariantProvider.java b/src/main/java/io/github/cottonmc/templates/TemplatesModelProvider.java similarity index 95% rename from src/main/java/io/github/cottonmc/templates/model/TemplateModelVariantProvider.java rename to src/main/java/io/github/cottonmc/templates/TemplatesModelProvider.java index 6d05675..d9ca0a3 100644 --- a/src/main/java/io/github/cottonmc/templates/model/TemplateModelVariantProvider.java +++ b/src/main/java/io/github/cottonmc/templates/TemplatesModelProvider.java @@ -1,4 +1,4 @@ -package io.github.cottonmc.templates.model; +package io.github.cottonmc.templates; import net.fabricmc.fabric.api.client.model.ModelProviderContext; import net.fabricmc.fabric.api.client.model.ModelProviderException; @@ -15,7 +15,7 @@ import java.util.HashMap; import java.util.Map; import java.util.function.Supplier; -public class TemplateModelVariantProvider implements ModelResourceProvider, ModelVariantProvider { +public class TemplatesModelProvider implements ModelResourceProvider, ModelVariantProvider { private final Map> factories = new HashMap<>(); private final Map itemAssignments = new HashMap<>(); diff --git a/src/main/java/io/github/cottonmc/templates/model/AffineQuadTransformer.java b/src/main/java/io/github/cottonmc/templates/model/AffineQuadTransformer.java index 56cb952..816e604 100644 --- a/src/main/java/io/github/cottonmc/templates/model/AffineQuadTransformer.java +++ b/src/main/java/io/github/cottonmc/templates/model/AffineQuadTransformer.java @@ -3,8 +3,6 @@ package io.github.cottonmc.templates.model; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; 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.Vector3f; import org.joml.Vector4f; @@ -14,8 +12,6 @@ public record AffineQuadTransformer(Matrix4f affineMatrix) implements RenderCont this(aff.getMatrix()); } - public static final AffineQuadTransformer EAST = new AffineQuadTransformer(AffineTransformations.DIRECTION_ROTATIONS.get(Direction.EAST)); - @Override public boolean transform(MutableQuadView quad) { Vector3f pos3 = new Vector3f(); diff --git a/src/main/java/io/github/cottonmc/templates/model/SlopeBakedModel.java b/src/main/java/io/github/cottonmc/templates/model/SlopeBakedModel.java deleted file mode 100644 index 961b799..0000000 --- a/src/main/java/io/github/cottonmc/templates/model/SlopeBakedModel.java +++ /dev/null @@ -1,53 +0,0 @@ -package io.github.cottonmc.templates.model; - -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.render.RenderContext; -import net.minecraft.block.BlockState; -import net.minecraft.client.render.model.BakedModel; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.AffineTransformation; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.random.Random; -import net.minecraft.world.BlockRenderView; - -import java.util.function.Supplier; - -public final class SlopeBakedModel extends ForwardingBakedModel { - public SlopeBakedModel(BakedModel baseModel, TemplateAppearanceManager tam, AffineTransformation aff) { - this.wrapped = baseModel; - - this.preparer = new SlopeQuadTransformFactory(tam); - this.blockAffineTransformer = new AffineQuadTransformer(aff); - this.itemAffineTransformer = AffineQuadTransformer.EAST; //Makes items point the same way as stairs. Kinda clunky - this.baseMesh = SlopeBaseMesh.make(); - } - - private final TemplateQuadTransformFactory preparer; - private final AffineQuadTransformer blockAffineTransformer; - private final AffineQuadTransformer itemAffineTransformer; - private final Mesh baseMesh; - - @Override - public boolean isVanillaAdapter() { - return false; - } - - @Override - public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) { - context.pushTransform(blockAffineTransformer); - context.pushTransform(preparer.blockTransformer(blockView, state, pos, randomSupplier)); - context.meshConsumer().accept(baseMesh); - context.popTransform(); - context.popTransform(); - } - - @Override - public void emitItemQuads(ItemStack stack, Supplier randomSupplier, RenderContext context) { - context.pushTransform(itemAffineTransformer); - context.pushTransform(preparer.itemTransformer(stack, randomSupplier)); - context.meshConsumer().accept(baseMesh); - context.popTransform(); - context.popTransform(); - } -} diff --git a/src/main/java/io/github/cottonmc/templates/model/SlopeBaseMesh.java b/src/main/java/io/github/cottonmc/templates/model/SlopeBaseMesh.java index 89693ba..16b7a16 100644 --- a/src/main/java/io/github/cottonmc/templates/model/SlopeBaseMesh.java +++ b/src/main/java/io/github/cottonmc/templates/model/SlopeBaseMesh.java @@ -2,7 +2,6 @@ package io.github.cottonmc.templates.model; import io.github.cottonmc.templates.TemplatesClient; import net.fabricmc.fabric.api.renderer.v1.Renderer; -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.MeshBuilder; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; @@ -10,7 +9,7 @@ import net.minecraft.util.math.Direction; public class SlopeBaseMesh { /** - * @see SlopeQuadTransformFactory.Transformer for why these values were chosen + * @see TemplateBakedModel.RetexturingTransformer for why these values were chosen */ public static final int TAG_SLOPE = Direction.UP.ordinal(); public static final int TAG_LEFT = Direction.EAST.ordinal(); diff --git a/src/main/java/io/github/cottonmc/templates/model/SlopeQuadTransformFactory.java b/src/main/java/io/github/cottonmc/templates/model/SlopeQuadTransformFactory.java deleted file mode 100644 index fd3671d..0000000 --- a/src/main/java/io/github/cottonmc/templates/model/SlopeQuadTransformFactory.java +++ /dev/null @@ -1,73 +0,0 @@ -package io.github.cottonmc.templates.model; - -import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry; -import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; -import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; -import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachedBlockView; -import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; -import net.minecraft.client.color.block.BlockColorProvider; -import net.minecraft.client.texture.Sprite; -import net.minecraft.item.BlockItem; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtHelper; -import net.minecraft.registry.Registries; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.random.Random; -import net.minecraft.world.BlockRenderView; -import org.jetbrains.annotations.NotNull; - -import java.util.function.Supplier; - -@SuppressWarnings("ClassCanBeRecord") -public class SlopeQuadTransformFactory implements TemplateQuadTransformFactory { - public SlopeQuadTransformFactory(TemplateAppearanceManager tam) { - this.tam = tam; - } - - private final TemplateAppearanceManager tam; - - @Override - public @NotNull RenderContext.QuadTransform blockTransformer(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier) { - BlockState template = (((RenderAttachedBlockView) blockView).getBlockEntityRenderAttachment(pos) instanceof BlockState s) ? s : null; - if(template == null || template.isAir()) return new Transformer(tam.getDefaultAppearance(), 0xFFFFFFFF); - - BlockColorProvider prov = ColorProviderRegistry.BLOCK.get(template.getBlock()); - int globalTint = prov != null ? prov.getColor(state, blockView, pos, 1) : 0xFFFFFFFF; - return new Transformer(tam.getAppearance(template), globalTint); - } - - @Override - public @NotNull RenderContext.QuadTransform itemTransformer(ItemStack stack, Supplier randomSupplier) { - //cheeky: if the item has NBT data, pluck out the blockstate from it - NbtCompound tag = BlockItem.getBlockEntityNbt(stack); - if(tag != null && tag.contains("BlockState")) { - BlockState state = NbtHelper.toBlockState(Registries.BLOCK.getReadOnlyWrapper(), tag.getCompound("BlockState")); - if(!state.isAir()) return new Transformer(tam.getAppearance(state), 0xFFFFFFFF); - } - - return new Transformer(tam.getDefaultAppearance(), 0xFFFFFFFF); - } - - public static record Transformer(TemplateAppearance appearance, int color) implements RenderContext.QuadTransform { - private static final Direction[] DIRECTIONS = Direction.values(); - - @Override - public boolean transform(MutableQuadView quad) { - quad.material(appearance.getRenderMaterial()); - - //The quad tag numbers were selected so this magic trick works: - Direction dir = DIRECTIONS[quad.tag()]; - - //TODO: this newly-simplified direction passing to hasColor is almost certainly incorrect - // I think hasColor was kinda incorrect in the first place tho - if(appearance.hasColor(dir)) quad.color(color, color, color, color); - Sprite sprite = appearance.getSprite(dir); - - quad.spriteBake(sprite, MutableQuadView.BAKE_NORMALIZED); - return true; - } - } -} diff --git a/src/main/java/io/github/cottonmc/templates/model/SlopeUnbakedModel.java b/src/main/java/io/github/cottonmc/templates/model/SlopeUnbakedModel.java index f20862f..b66c7f2 100644 --- a/src/main/java/io/github/cottonmc/templates/model/SlopeUnbakedModel.java +++ b/src/main/java/io/github/cottonmc/templates/model/SlopeUnbakedModel.java @@ -27,12 +27,14 @@ public class SlopeUnbakedModel implements UnbakedModel { @Override public BakedModel bake(Baker baker, Function spriteLookup, ModelBakeSettings modelBakeSettings, Identifier identifier) { - //TODO: this is weird, should use my own model instead - BakedModel baseModel = baker.bake(BlockModels.getModelId(Blocks.SANDSTONE_STAIRS.getDefaultState()), modelBakeSettings); + //TODO: this is weird, should use my own model instead. + // I should also adjust the item frame/first-person rotations (previously I used SANDSTONE_STAIRS, which has models/block/stairs.json as a parent, + // and that one brings some extra custom rotations along for the ride + BakedModel baseModel = baker.bake(BlockModels.getModelId(Blocks.SANDSTONE.getDefaultState()), modelBakeSettings); - //TODO: push this up (it's just a cache of data sourced from blockmodels, and can be cached until resource-reload) + //TODO: push this up (it's just a cache of data sourced from blockmodels, and can be shared among *all* templates/cached until resource-reload) TemplateAppearanceManager tam = new TemplateAppearanceManager(spriteLookup); - return new SlopeBakedModel(baseModel, tam, modelBakeSettings.getRotation()); + return new TemplateBakedModel(baseModel, tam, modelBakeSettings.getRotation(), SlopeBaseMesh.make()); } } diff --git a/src/main/java/io/github/cottonmc/templates/model/TemplateBakedModel.java b/src/main/java/io/github/cottonmc/templates/model/TemplateBakedModel.java new file mode 100644 index 0000000..bbb7dc3 --- /dev/null +++ b/src/main/java/io/github/cottonmc/templates/model/TemplateBakedModel.java @@ -0,0 +1,108 @@ +package io.github.cottonmc.templates.model; + +import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry; +import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh; +import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; +import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; +import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; +import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachedBlockView; +import net.minecraft.block.BlockState; +import net.minecraft.client.color.block.BlockColorProvider; +import net.minecraft.client.render.model.BakedModel; +import net.minecraft.client.texture.Sprite; +import net.minecraft.item.BlockItem; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtHelper; +import net.minecraft.registry.Registries; +import net.minecraft.util.math.AffineTransformation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.random.Random; +import net.minecraft.world.BlockRenderView; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Supplier; + +public final class TemplateBakedModel extends ForwardingBakedModel { + public TemplateBakedModel(BakedModel baseModel, TemplateAppearanceManager tam, AffineTransformation aff, Mesh baseMesh) { + this.wrapped = baseModel; + + this.tam = tam; + this.affineTransformer = new AffineQuadTransformer(aff); + this.baseMesh = baseMesh; + } + + private final TemplateAppearanceManager tam; + private final AffineQuadTransformer affineTransformer; + private final Mesh baseMesh; + + @Override + public boolean isVanillaAdapter() { + return false; + } + + @Override + public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) { + context.pushTransform(affineTransformer); + context.pushTransform(retexturingBlockTransformer(blockView, state, pos, randomSupplier)); + context.meshConsumer().accept(baseMesh); + context.popTransform(); + context.popTransform(); + } + + @Override + public void emitItemQuads(ItemStack stack, Supplier randomSupplier, RenderContext context) { + context.pushTransform(affineTransformer); + context.pushTransform(retexturingItemTransformer(stack, randomSupplier)); + context.meshConsumer().accept(baseMesh); + context.popTransform(); + context.popTransform(); + } + + @Override + public boolean isSideLit() { + //Makes item models look less bad. TODO: possibly a weird spot to put this. corresponds to `gui_light: front` in the json + return false; + } + + public @NotNull RenderContext.QuadTransform retexturingBlockTransformer(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier) { + BlockState template = (((RenderAttachedBlockView) blockView).getBlockEntityRenderAttachment(pos) instanceof BlockState s) ? s : null; + if(template == null || template.isAir()) return new RetexturingTransformer(tam.getDefaultAppearance(), 0xFFFFFFFF); + + BlockColorProvider prov = ColorProviderRegistry.BLOCK.get(template.getBlock()); + int globalTint = prov != null ? prov.getColor(state, blockView, pos, 1) : 0xFFFFFFFF; + return new RetexturingTransformer(tam.getAppearance(template), globalTint); + } + + public @NotNull RenderContext.QuadTransform retexturingItemTransformer(ItemStack stack, Supplier randomSupplier) { + //cheeky: if the item has NBT data, pluck out the blockstate from it + NbtCompound tag = BlockItem.getBlockEntityNbt(stack); + if(tag != null && tag.contains("BlockState")) { + BlockState state = NbtHelper.toBlockState(Registries.BLOCK.getReadOnlyWrapper(), tag.getCompound("BlockState")); + if(!state.isAir()) return new RetexturingTransformer(tam.getAppearance(state), 0xFFFFFFFF); + } + + return new RetexturingTransformer(tam.getDefaultAppearance(), 0xFFFFFFFF); + } + + public static record RetexturingTransformer(TemplateAppearance appearance, int color) implements RenderContext.QuadTransform { + private static final Direction[] DIRECTIONS = Direction.values(); + + @Override + public boolean transform(MutableQuadView quad) { + quad.material(appearance.getRenderMaterial()); + + //The quad tag numbers were selected so this magic trick works: + Direction dir = DIRECTIONS[quad.tag()]; + + //TODO: this newly-simplified direction passing to hasColor is almost certainly incorrect + // I think hasColor was kinda incorrect in the first place tho + if(appearance.hasColor(dir)) quad.color(color, color, color, color); + Sprite sprite = appearance.getSprite(dir); + + quad.spriteBake(sprite, MutableQuadView.BAKE_NORMALIZED); + return true; + } + } +} diff --git a/src/main/java/io/github/cottonmc/templates/model/TemplateQuadTransformFactory.java b/src/main/java/io/github/cottonmc/templates/model/TemplateQuadTransformFactory.java deleted file mode 100644 index f586d7d..0000000 --- a/src/main/java/io/github/cottonmc/templates/model/TemplateQuadTransformFactory.java +++ /dev/null @@ -1,19 +0,0 @@ -package io.github.cottonmc.templates.model; - -import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; -import net.minecraft.block.BlockState; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.random.Random; -import net.minecraft.world.BlockRenderView; -import org.jetbrains.annotations.NotNull; - -import java.util.function.Supplier; - -/** - * Please keep thread-safety in mind - `getQuads`/`emitBlockQuads` can be called concurrently from multiple worker threads. - */ -public interface TemplateQuadTransformFactory { - @NotNull RenderContext.QuadTransform blockTransformer(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier); - @NotNull RenderContext.QuadTransform itemTransformer(ItemStack stack, Supplier randomSupplier); -}