From 0eee9f51631ea9d26a64444a3322ee9301ed8707 Mon Sep 17 00:00:00 2001 From: mewhenthe Date: Fri, 1 May 2026 00:27:09 +0200 Subject: [PATCH] robot model --- .../fabric/client/model/CableModel.java | 2 +- .../client/model/FabricModelWrapper.java | 55 ++++++++++ .../fabric/client/model/ModelLoader.java | 17 ++- .../org/neoflock/neocomputers/block/Blocks.kt | 1 + .../neocomputers/block/model/AbstractModel.kt | 103 ++++++++++++++++++ .../neocomputers/block/model/RobotModel.kt | 86 +++++++++++++++ .../neocomputers/blockstates/robot.json | 7 ++ .../neocomputers/textures/block/robot.png | Bin 0 -> 934 bytes 8 files changed, 261 insertions(+), 10 deletions(-) create mode 100644 src/main/java/org/neoflock/neocomputers/platforms/fabric/client/model/FabricModelWrapper.java create mode 100644 src/main/kotlin/org/neoflock/neocomputers/block/model/AbstractModel.kt create mode 100644 src/main/kotlin/org/neoflock/neocomputers/block/model/RobotModel.kt create mode 100644 src/main/resources/assets/neocomputers/blockstates/robot.json create mode 100644 src/main/resources/assets/neocomputers/textures/block/robot.png diff --git a/src/main/java/org/neoflock/neocomputers/platforms/fabric/client/model/CableModel.java b/src/main/java/org/neoflock/neocomputers/platforms/fabric/client/model/CableModel.java index b4e1d8f..cb8196a 100644 --- a/src/main/java/org/neoflock/neocomputers/platforms/fabric/client/model/CableModel.java +++ b/src/main/java/org/neoflock/neocomputers/platforms/fabric/client/model/CableModel.java @@ -32,7 +32,7 @@ // //// this totally could have been done with datagen, why do i do this //public class CableModel implements BakedModel, UnbakedModel, FabricBakedModel { -//// private TextureAtlasSprite sprite = Minecraft +// private TextureAtlasSprite sprite = Minecraft //// TextureAtlasSprite sprite = atlas.apply(new Material(TextureAtlas.LOCATION_BLOCKS, ResourceLocation.withDefaultNamespace("block/furnace_top"))); // // private float MIN = 6/16F; diff --git a/src/main/java/org/neoflock/neocomputers/platforms/fabric/client/model/FabricModelWrapper.java b/src/main/java/org/neoflock/neocomputers/platforms/fabric/client/model/FabricModelWrapper.java new file mode 100644 index 0000000..1a2b576 --- /dev/null +++ b/src/main/java/org/neoflock/neocomputers/platforms/fabric/client/model/FabricModelWrapper.java @@ -0,0 +1,55 @@ +package org.neoflock.neocomputers.platforms.fabric.client.model; + +import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel; +import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; +import net.fabricmc.fabric.impl.renderer.VanillaModelEncoder; +import net.minecraft.client.renderer.texture.TextureAtlas; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.model.*; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.RandomSource; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; +import org.neoflock.neocomputers.NeoComputers; +import org.neoflock.neocomputers.block.model.AbstractModel; + +import java.util.Collection; +import java.util.List; +import java.util.function.Function; +import java.util.function.Supplier; + +public class FabricModelWrapper implements FabricBakedModel, UnbakedModel { + private AbstractModel model; + + public FabricModelWrapper(AbstractModel model) { + this.model = model; + } + + @Override + public void emitBlockQuads(BlockAndTintGetter blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) { + VanillaModelEncoder.emitBlockQuads(model, state, randomSupplier, context); + } + + @Override + public void emitItemQuads(ItemStack stack, Supplier randomSupplier, RenderContext context) { + VanillaModelEncoder.emitItemQuads(model, null, randomSupplier, context); + } + + @Override + public Collection getDependencies() { + return List.of(); + } + + @Override + public void resolveParents(Function resolver) { + } + + @Override + public @Nullable BakedModel bake(ModelBaker baker, Function spriteGetter, ModelState state) { + model.bake(baker, spriteGetter, state); + return model; + } +} diff --git a/src/main/java/org/neoflock/neocomputers/platforms/fabric/client/model/ModelLoader.java b/src/main/java/org/neoflock/neocomputers/platforms/fabric/client/model/ModelLoader.java index 7cf46c9..fa06313 100644 --- a/src/main/java/org/neoflock/neocomputers/platforms/fabric/client/model/ModelLoader.java +++ b/src/main/java/org/neoflock/neocomputers/platforms/fabric/client/model/ModelLoader.java @@ -1,24 +1,23 @@ package org.neoflock.neocomputers.platforms.fabric.client.model; +import com.mojang.blaze3d.vertex.VertexConsumer; import net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.resources.ResourceLocation; import org.neoflock.neocomputers.NeoComputers; +import org.neoflock.neocomputers.block.model.RobotModel; public class ModelLoader implements ModelLoadingPlugin { - public static final ResourceLocation CABLE = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "cable"); + public static final ResourceLocation ROBOT = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "robot"); @Override public void onInitializeModelLoader(Context pluginContext) { pluginContext.modifyModelOnLoad().register((original, context) -> { -// final ModelResourceLocation id = context.topLevelId(); -////// if (id != null && id.id().getNamespace().equals(NeoComputers.MODID)) NeoComputers.INSTANCE.getLOGGER().info("{} {} {}", id.id().getNamespace(), id.id().getPath(), id.id().getPath().equals(CABLE.id().getPath())); -// if (id != null && id.id().equals(CABLE)) { -////// NeoComputers.INSTANCE.getLOGGER().error("DOING CABLEEEEEEE"); -// original. -// } else { -// return original; -// } + final ModelResourceLocation id = context.topLevelId(); + if (id != null && id.id().equals(ROBOT)) { +//// NeoComputers.INSTANCE.getLOGGER().error("DOING CABLEEEEEEE"); + return new FabricModelWrapper(new RobotModel()); + } return original; }); } diff --git a/src/main/kotlin/org/neoflock/neocomputers/block/Blocks.kt b/src/main/kotlin/org/neoflock/neocomputers/block/Blocks.kt index df8480f..df08650 100644 --- a/src/main/kotlin/org/neoflock/neocomputers/block/Blocks.kt +++ b/src/main/kotlin/org/neoflock/neocomputers/block/Blocks.kt @@ -35,6 +35,7 @@ object Blocks { val REDSTONEIO_BLOCK: RegistrySupplier = BaseBlock.register("redio") { RedstoneIOBlock() } val CABLE_BLOCK: RegistrySupplier = BaseBlock.register("cable") { CableBlock() } val RELAY_BLOCK: RegistrySupplier = BaseBlock.register("relay") { RelayBlock() } + val ROBOT_BLOCK: RegistrySupplier = BaseBlock.register("robot") { BaseBlock(BlockBehaviour.Properties.of().noOcclusion()) } fun registerBlockItems() { BLOCKS.forEach(Consumer { sup: RegistrySupplier -> diff --git a/src/main/kotlin/org/neoflock/neocomputers/block/model/AbstractModel.kt b/src/main/kotlin/org/neoflock/neocomputers/block/model/AbstractModel.kt new file mode 100644 index 0000000..cb96b61 --- /dev/null +++ b/src/main/kotlin/org/neoflock/neocomputers/block/model/AbstractModel.kt @@ -0,0 +1,103 @@ +package org.neoflock.neocomputers.block.model + +import com.mojang.blaze3d.vertex.VertexConsumer +import net.minecraft.client.Minecraft +import net.minecraft.client.model.geom.ModelPart +import net.minecraft.client.renderer.block.model.BakedQuad +import net.minecraft.client.renderer.block.model.ItemOverrides +import net.minecraft.client.renderer.block.model.ItemTransforms +import net.minecraft.client.renderer.texture.TextureAtlas +import net.minecraft.client.renderer.texture.TextureAtlasSprite +import net.minecraft.client.resources.model.BakedModel +import net.minecraft.client.resources.model.Material +import net.minecraft.client.resources.model.ModelBaker +import net.minecraft.client.resources.model.ModelState +import net.minecraft.client.resources.model.UnbakedModel +import net.minecraft.core.Direction +import net.minecraft.resources.ResourceLocation +import net.minecraft.util.RandomSource +import net.minecraft.world.level.block.state.BlockState +import java.util.function.Function + +abstract class AbstractModel : BakedModel, UnbakedModel { + val atlas = Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS) + var baker: ModelBaker? = null; + var mesh: Map> = mapOf( + Direction.UP to listOf(), + Direction.DOWN to listOf(), + Direction.EAST to listOf(), + Direction.WEST to listOf(), + Direction.SOUTH to listOf(), + Direction.NORTH to listOf(), + ); + + override fun getQuads(state: BlockState?, direction: Direction?, random: RandomSource): List? { // perf? what's that? + if (direction != null) { + return mesh[direction] + } else { + var allquads: MutableList = mutableListOf() + mesh.forEach { (_, quads) -> + allquads.addAll(quads) + } + return allquads + } + } + + override fun getParticleIcon(): TextureAtlasSprite? { + return atlas.apply(particle()) + } + +// abstract fun bake(atlas: (ResourceLocation) -> TextureAtlasSprite) + + abstract fun particle(): ResourceLocation + +} + +class SchizoConsumer { + var mesh: Map> = mapOf( + Direction.UP to mutableListOf(), + Direction.DOWN to mutableListOf(), + Direction.EAST to mutableListOf(), + Direction.WEST to mutableListOf(), + Direction.SOUTH to mutableListOf(), + Direction.NORTH to mutableListOf(), + ); + + var vertices: MutableList = mutableListOf(); + var sprite: TextureAtlasSprite? = null; + var normal: Direction? = null; + var tint_index = -1 + var shade = false + + fun startQuad(normal: Direction, sprite: TextureAtlasSprite, tint_index: Int = -1, shade: Boolean = false): SchizoConsumer { + this.sprite = sprite + this.normal = normal + this.tint_index = tint_index + this.shade = shade + return this + } + + fun vertex(x: Float, y: Float, z:Float, colorABGR: Int, u: Float, v: Float) { // uv are normalized + if (sprite == null || normal == null) { + throw Error("quad not started") + } + vertices.add(x.toBits()) + vertices.add(y.toBits()) + vertices.add(z.toBits()) + vertices.add(colorABGR) + vertices.add(sprite!!.getU(u).toBits()) + vertices.add(sprite!!.getV(v).toBits()) + vertices.add(0) + vertices.add(0) + + if (vertices.size == 4 * 8) { + var quad = BakedQuad(vertices.toIntArray(), tint_index, normal!!, sprite!!, shade) + mesh.get(normal)!!.add(quad) + normal = null + sprite = null + vertices.clear() + } + } // TODO: add stuff like squares + + +} \ No newline at end of file diff --git a/src/main/kotlin/org/neoflock/neocomputers/block/model/RobotModel.kt b/src/main/kotlin/org/neoflock/neocomputers/block/model/RobotModel.kt new file mode 100644 index 0000000..614f28f --- /dev/null +++ b/src/main/kotlin/org/neoflock/neocomputers/block/model/RobotModel.kt @@ -0,0 +1,86 @@ +package org.neoflock.neocomputers.block.model + +import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.block.model.BakedQuad +import net.minecraft.client.renderer.block.model.ItemOverrides +import net.minecraft.client.renderer.block.model.ItemTransforms +import net.minecraft.client.renderer.texture.TextureAtlas +import net.minecraft.client.renderer.texture.TextureAtlasSprite +import net.minecraft.client.resources.model.BakedModel +import net.minecraft.client.resources.model.Material +import net.minecraft.client.resources.model.ModelBaker +import net.minecraft.client.resources.model.ModelState +import net.minecraft.client.resources.model.UnbakedModel +import net.minecraft.core.Direction +import net.minecraft.resources.ResourceLocation +import net.minecraft.util.RandomSource +import net.minecraft.util.ResourceLocationPattern +import net.minecraft.world.level.block.state.BlockState +import org.neoflock.neocomputers.NeoComputers +import java.util.function.Function + +class RobotModel() : AbstractModel() { + val size = 0.4f + val l = 0.5f-size; + val h = 0.5f+size; + override fun getDependencies(): Collection = listOf() + + override fun resolveParents(resolver: Function) { } + + // override fun bake(atlas: (ResourceLocation) -> TextureAtlasSprite) { + override fun bake(baker: ModelBaker, atlas: Function, state: ModelState): BakedModel? { + NeoComputers.LOGGER.info("baking") + val sprite = atlas.apply(Material(TextureAtlas.LOCATION_BLOCKS, ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "block/robot")))!! + var verts: SchizoConsumer = SchizoConsumer() + + // top pyramid, enjoy reading this schizo mess + bakeTri(verts, Direction.WEST, sprite, l,l, l, h, 9f/16f,1F, 0f, 0f, 0f, 16f/32f) + bakeTri(verts, Direction.EAST, sprite, h, h, h, l, 9f/16f, 1F, 16/32f, 16/32f, 16/32f, 0f) + bakeTri(verts, Direction.SOUTH, sprite, l, h, h, h, 9f/16f, 1F, 0f, 16f/32f, 16f/32f, 16f/32f) + bakeTri(verts, Direction.NORTH, sprite, h, l, l,l, 9f/16f, 1F, 16/32f, 0f, 0f, 0f) + + verts.startQuad(Direction.DOWN, sprite) + verts.vertex(l, 9f/16F, h, 0xFFFFFFFF.toInt(), 16f/32f, 16/32F) + verts.vertex(l, 9f/16f, l, 0xFFFFFFFF.toInt(), 0F, 16/32F) + verts.vertex(h, 9f/16f, l, 0xFFFFFFFF.toInt(), 0F, 1F) + verts.vertex(h, 9f/16f, h, 0xFFFFFFFF.toInt(), 16/32F, 1F) + + // bottom + bakeTri(verts, Direction.WEST, sprite, l, h, l, l, 7f/16f, 0F, 0f, 0f, 0f, 16f/32f) + bakeTri(verts, Direction.EAST, sprite, h, l, h, h, 7f/16f, 0F, 0f, 0f, 0f, 16f/32f) + bakeTri(verts, Direction.SOUTH, sprite, h, h, l, h, 7f/16f, 0F, 0f, 0f, 0f, 16f/32f) + bakeTri(verts, Direction.NORTH, sprite, l, l, h,l, 7f/16f, 0F, 0f, 0f, 0f, 16f/32f) + + verts.startQuad(Direction.UP, sprite) + verts.vertex(h, 7f/16F, l, 0xFFFFFFFF.toInt(), 16/32F, 16/32F) + verts.vertex(l, 7f/16f, l, 0xFFFFFFFF.toInt(), 0F, 16/32F) + verts.vertex(l, 7f/16f, h, 0xFFFFFFFF.toInt(), 0F, 1F) + verts.vertex(h, 7f/16f, h, 0xFFFFFFFF.toInt(), 16/32F, 1F) + + + this.mesh = verts.mesh + return this + } + + fun bakeTri(verts: SchizoConsumer, normal: Direction, sprite: TextureAtlasSprite, lx: Float, lz: Float, rx: Float, rz: Float, dy: Float, uy: Float, lu: Float, lv: Float, ru: Float, rv: Float) { + verts.startQuad(normal, sprite) + verts.vertex(0.5F, uy, 0.5F, 0xFFFFFFFF.toInt(), 8F/32F, 8F/32F) + verts.vertex(0.5F, uy, 0.5F, 0xFFFFFFFF.toInt(), 8F/32F, 8F/32F) + verts.vertex(lx, dy, lz, 0xFFFFFFFF.toInt(), lu, lv) + verts.vertex(rx, dy, rz, 0xFFFFFFFF.toInt(), ru, rv) + } + + override fun particle(): ResourceLocation = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "block/teto") + + override fun useAmbientOcclusion(): Boolean = true + + override fun isGui3d(): Boolean = true + + override fun usesBlockLight(): Boolean = true + + override fun isCustomRenderer(): Boolean = false + + override fun getTransforms(): ItemTransforms? = ItemTransforms.NO_TRANSFORMS + + override fun getOverrides(): ItemOverrides? = ItemOverrides.EMPTY // TODO: item +} \ No newline at end of file diff --git a/src/main/resources/assets/neocomputers/blockstates/robot.json b/src/main/resources/assets/neocomputers/blockstates/robot.json new file mode 100644 index 0000000..c387762 --- /dev/null +++ b/src/main/resources/assets/neocomputers/blockstates/robot.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "neocomputers:block/robot" + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/neocomputers/textures/block/robot.png b/src/main/resources/assets/neocomputers/textures/block/robot.png new file mode 100644 index 0000000000000000000000000000000000000000..d417bf93c861e14b571e204774fa2f16f1294d23 GIT binary patch literal 934 zcmV;X16lluP)uIyyT$J3Kr*Jv}`?KR-Y~ zKte)7LqkJFMMXzPM@UFWN=iyhOiWEpO;1lxQBhG+Qc_e@R9;?QUteEiV`F4wWM*b& zXlQ6@X=!U~Yi(_9ZfLl?uCA`Lv$MLo zy1>A|!NI}A#KhRx*xA|H@9*#b|NjB0ke2`e00Cl4M??UK1szBL000SaNLh0L01FcU z01FcV0GgZ_00007bV*G`2j2k!4F)jMJ5Kfh00KfuL_t(I%UzRUU)nGb#!pif=&3*_ zG);3G1%bFJLZ(9*YR#NF<@`IizrJXC|6ZTx?h0tEtLxgiTlf3d!er#5&{Av4 ziAsV&X6!doB|kQoqmvOK28Qx8Dh`_jv-6JmF|0;rFt+B{%m|@@B(#qc0?_NBtaAjU`i#pCwDz%rFNW6ubf-S zKA`}SBnc!btAxj=`<0z$rs^2GymyW=!bETl*iVpj4iD>k{qu6r=??A9jeBr?Vjsyq zFw#Ia3v2gy>ulA{Cf2Q8y=3!8CuI2#C&2$NRV?%qpa6D>@FO@gJZI+fUL{(&%EW9zcy{$Mk0 z9Wv7>HC%jc8^LJ~CMruUNKsMI3#A$wOnYKs7vD{Ls1dc|25Fw3#1=uD`~Uv(^8Whz z_s?oR%yjuh`GJ$Bo>Y>6?{Yq5g-E*(*Cah91*a6n|Mcw$B?T>V0e&zH^od)l{ffmz(8vSP zrQ|=7G{l6T1NVZX$9Z0{n9zmXs-Tk5QbA1Qw38V^Q8ew%f75|>>C^T&LI3~&07*qo IM6N<$g0fqgxBvhE literal 0 HcmV?d00001