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.screen.PlayerScreenHandler 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.AbstractTerminalBlock import java.util.Random import java.util.function.Function import java.util.function.Supplier /** * @author shadowfacts */ class ScreenDeviceModel( screenTexture: Identifier, ): UnbakedModel, BakedModel, FabricBakedModel { companion object { private val CASING = SpriteIdentifier(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, Identifier(PhysicalConnectivity.MODID, "block/casing")) } private val screenTexture = SpriteIdentifier(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, screenTexture) private lateinit var meshes: Array private lateinit var screenSprite: Sprite override fun getModelDependencies(): Collection { return listOf() } override fun getTextureDependencies( unbakedModelGetter: Function, unresolvedTextureDependencies: MutableSet> ): Collection { return listOf(screenTexture, CASING) } override fun bake( loader: ModelLoader, textureGetter: Function, rotationContainer: ModelBakeSettings, modelId: Identifier ): BakedModel { screenSprite = textureGetter.apply(screenTexture) 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) { // screen border emitter.square(facing, 0f, 0f, 3/16f, 3/16f, 0f) emitter.spriteBake(0, screenSprite, MutableQuadView.BAKE_LOCK_UV) emitter.spriteColor(0, -1, -1, -1, -1) emitter.emit() emitter.square(facing, 13/16f, 0f, 1f, 3/16f, 0f) emitter.spriteBake(0, screenSprite, MutableQuadView.BAKE_LOCK_UV) emitter.spriteColor(0, -1, -1, -1, -1) emitter.emit() emitter.square(facing, 13/16f, 13/16f, 1f, 1f, 0f) emitter.spriteBake(0, screenSprite, MutableQuadView.BAKE_LOCK_UV) emitter.spriteColor(0, -1, -1, -1, -1) emitter.emit() emitter.square(facing, 0f, 13/16f, 3/16f, 1f, 0f) emitter.spriteBake(0, screenSprite, MutableQuadView.BAKE_LOCK_UV) emitter.spriteColor(0, -1, -1, -1, -1) emitter.emit() emitter.square(facing, 3/16f, 0f, 13/16f, 2/16f, 0f) emitter.spriteBake(0, screenSprite, MutableQuadView.BAKE_LOCK_UV) emitter.spriteColor(0, -1, -1, -1, -1) emitter.emit() emitter.square(facing, 3/16f, 14/16f, 13/16f, 1f, 0f) emitter.spriteBake(0, screenSprite, MutableQuadView.BAKE_LOCK_UV) emitter.spriteColor(0, -1, -1, -1, -1) emitter.emit() emitter.square(facing, 0f, 3/16f, 2/16f, 13/16f, 0f) emitter.spriteBake(0, screenSprite, MutableQuadView.BAKE_LOCK_UV) emitter.spriteColor(0, -1, -1, -1, -1) emitter.emit() emitter.square(facing, 14/16f, 3/16f, 1f, 13/16f, 0f) emitter.spriteBake(0, screenSprite, MutableQuadView.BAKE_LOCK_UV) emitter.spriteColor(0, -1, -1, -1, -1) emitter.emit() // screen emitter.material(PhysicalConnectivityClient.screenMaterial) emitter.square(facing, 3/16f, 2/16f, 13/16f, 3/16f, 0f) emitter.spriteBake(0, screenSprite, 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, screenSprite, 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, screenSprite, 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[AbstractTerminalBlock.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 getParticleSprite() = screenSprite override fun getTransformation() = null override fun getOverrides() = null }