diff --git a/src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivityClient.kt b/src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivityClient.kt index 54f97dd..06c7f47 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivityClient.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivityClient.kt @@ -4,10 +4,13 @@ import net.fabricmc.api.ClientModInitializer import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry +import net.fabricmc.fabric.api.renderer.v1.RendererAccess +import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial import net.shadowfacts.phycon.block.inserter.InserterScreen import net.shadowfacts.phycon.block.redstone_emitter.RedstoneEmitterScreen import net.shadowfacts.phycon.init.PhyScreens import net.shadowfacts.phycon.block.terminal.TerminalScreen +import net.shadowfacts.phycon.client.PhyExtendedModelProvider import net.shadowfacts.phycon.client.PhyModelProvider import net.shadowfacts.phycon.networking.ClientReceiver import net.shadowfacts.phycon.networking.S2CTerminalUpdateDisplayedItems @@ -17,9 +20,22 @@ import net.shadowfacts.phycon.networking.S2CTerminalUpdateDisplayedItems */ object PhysicalConnectivityClient: ClientModInitializer { + var screenMaterial: RenderMaterial? = null + private set + override fun onInitializeClient() { ModelLoadingRegistry.INSTANCE.registerResourceProvider(::PhyModelProvider) + RendererAccess.INSTANCE.renderer?.also { renderer -> + screenMaterial = renderer.materialFinder() + .emissive(0, true) + .disableAo(0, true) + .disableDiffuse(0, true) + .find() + + ModelLoadingRegistry.INSTANCE.registerResourceProvider(::PhyExtendedModelProvider) + } + ScreenRegistry.register(PhyScreens.TERMINAL, ::TerminalScreen) ScreenRegistry.register(PhyScreens.INSERTER, ::InserterScreen) ScreenRegistry.register(PhyScreens.REDSTONE_EMITTER, ::RedstoneEmitterScreen) diff --git a/src/main/kotlin/net/shadowfacts/phycon/client/PhyExtendedModelProvider.kt b/src/main/kotlin/net/shadowfacts/phycon/client/PhyExtendedModelProvider.kt new file mode 100644 index 0000000..4fb662a --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/phycon/client/PhyExtendedModelProvider.kt @@ -0,0 +1,27 @@ +package net.shadowfacts.phycon.client + +import net.fabricmc.fabric.api.client.model.ModelProviderContext +import net.fabricmc.fabric.api.client.model.ModelResourceProvider +import net.minecraft.client.render.model.UnbakedModel +import net.minecraft.resource.ResourceManager +import net.minecraft.util.Identifier +import net.shadowfacts.phycon.PhysicalConnectivity +import net.shadowfacts.phycon.client.model.TerminalModel + +/** + * @author shadowfacts + */ +class PhyExtendedModelProvider(resourceManager: ResourceManager): ModelResourceProvider { + + companion object { + val TERMINAL = Identifier(PhysicalConnectivity.MODID, "block/terminal") + } + + override fun loadModelResource(resourceId: Identifier, context: ModelProviderContext): UnbakedModel? { + return when (resourceId) { + TERMINAL -> TerminalModel + else -> null + } + } + +} diff --git a/src/main/kotlin/net/shadowfacts/phycon/client/model/TerminalModel.kt b/src/main/kotlin/net/shadowfacts/phycon/client/model/TerminalModel.kt new file mode 100644 index 0000000..14e85fa --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/phycon/client/model/TerminalModel.kt @@ -0,0 +1,137 @@ +package net.shadowfacts.phycon.client.model + +import com.mojang.datafixers.util.Pair +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.MutableQuadView +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter +import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel +import net.fabricmc.fabric.api.renderer.v1.render.RenderContext +import net.minecraft.block.BlockState +import net.minecraft.client.render.model.* +import net.minecraft.client.texture.Sprite +import net.minecraft.client.texture.SpriteAtlasTexture +import net.minecraft.client.util.SpriteIdentifier +import net.minecraft.item.ItemStack +import net.minecraft.util.Identifier +import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Direction +import net.minecraft.world.BlockRenderView +import net.shadowfacts.phycon.PhysicalConnectivity +import net.shadowfacts.phycon.PhysicalConnectivityClient +import net.shadowfacts.phycon.block.terminal.TerminalBlock +import java.util.Random +import java.util.function.Function +import java.util.function.Supplier + +/** + * @author shadowfacts + */ +object TerminalModel: UnbakedModel, BakedModel, FabricBakedModel { + + private val TERMINAL = SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, Identifier(PhysicalConnectivity.MODID, "block/terminal")) + private val CASING = SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, Identifier(PhysicalConnectivity.MODID, "block/casing")) + + private lateinit var meshes: Array + private lateinit var terminalSprite: Sprite + + override fun getModelDependencies(): Collection { + return listOf() + } + + override fun getTextureDependencies( + unbakedModelGetter: Function, + unresolvedTextureDependencies: MutableSet> + ): Collection { + return listOf(TERMINAL, CASING) + } + + override fun bake( + loader: ModelLoader, + textureGetter: Function, + rotationContainer: ModelBakeSettings, + modelId: Identifier + ): BakedModel { + + terminalSprite = textureGetter.apply(TERMINAL) + val casingSprite = textureGetter.apply(CASING) + + val renderer = RendererAccess.INSTANCE.renderer!! + + meshes = Array(6) { i -> + val facing = Direction.values()[i] + + val builder = renderer.meshBuilder() + val emitter = builder.emitter + + for (dir in Direction.values()) { + if (dir == facing) { + emitter.square(facing, 0f, 0f, 1f, 1f, QuadEmitter.CULL_FACE_EPSILON * 10) + emitter.spriteBake(0, terminalSprite, MutableQuadView.BAKE_LOCK_UV) + emitter.spriteColor(0, -1, -1, -1, -1) + emitter.emit() + + emitter.material(PhysicalConnectivityClient.screenMaterial) + emitter.square(facing, 3/16f, 2/16f, 13/16f, 3/16f, 0f) + emitter.spriteBake(0, terminalSprite, MutableQuadView.BAKE_LOCK_UV) + emitter.spriteColor(0, -1, -1, -1, -1) + emitter.emit() + + emitter.material(PhysicalConnectivityClient.screenMaterial) + emitter.square(facing, 2/16f, 3/16f, 14/16f, 13/16f, 0f) + emitter.spriteBake(0, terminalSprite, MutableQuadView.BAKE_LOCK_UV) + emitter.spriteColor(0, -1, -1, -1, -1) + emitter.emit() + + emitter.material(PhysicalConnectivityClient.screenMaterial) + emitter.square(facing, 3/16f, 13/16f, 13/16f, 14/16f, 0f) + emitter.spriteBake(0, terminalSprite, MutableQuadView.BAKE_LOCK_UV) + emitter.spriteColor(0, -1, -1, -1, -1) + emitter.emit() + } else { + emitter.square(dir, 0f, 0f, 1f, 1f, 0f) + emitter.spriteBake(0, casingSprite, MutableQuadView.BAKE_LOCK_UV) + emitter.spriteColor(0, -1, -1, -1, -1) + emitter.emit() + } + } + + builder.build() + } + + + return this + } + + override fun isVanillaAdapter() = false + + override fun emitBlockQuads( + blockView: BlockRenderView, + state: BlockState, + pos: BlockPos, + randomSupplier: Supplier, + context: RenderContext + ) { + val mesh = meshes[state[TerminalBlock.FACING].ordinal] + context.meshConsumer().accept(mesh) + } + + override fun emitItemQuads(stack: ItemStack, randomSupplier: Supplier, context: RenderContext) { + } + + override fun getQuads(state: BlockState?, face: Direction?, random: Random) = null + + override fun useAmbientOcclusion() = true + + override fun hasDepth() = false + + override fun isSideLit() = false + + override fun isBuiltin() = false + + override fun getSprite() = terminalSprite + + override fun getTransformation() = null + + override fun getOverrides() = null +}