From 095add7c7639630b1058f5b78f08dcb59ebf1985 Mon Sep 17 00:00:00 2001 From: yuxuanchiadm Date: Thu, 29 Feb 2024 16:33:17 +0800 Subject: [PATCH] Block model rendering --- build.gradle | 10 +- .../easecation/bedrockloader/BedrockLoader.kt | 2 +- .../bedrockloader/BedrockLoaderClient.kt | 2 + .../bedrockloader/block/BlockDataDriven.kt | 3 +- .../loader/BedrockResourcePackLoader.kt | 169 ++++++++++-------- .../render/BedrockGeometryModel.kt | 29 +-- .../render/BedrockModelProvider.kt | 14 +- .../bedrockloader/render/BedrockRenderUtil.kt | 12 +- .../render/BedrockVariantProvider.kt | 26 +++ .../render/MeshBuilderVertexConsumer.kt | 100 +++-------- .../render/VertexIndexedVertexConsumer.kt | 2 + .../bedrockloader/render/model/ModelPart.kt | 3 + 12 files changed, 200 insertions(+), 172 deletions(-) create mode 100644 src/main/kotlin/net/easecation/bedrockloader/render/BedrockVariantProvider.kt diff --git a/build.gradle b/build.gradle index c31090f..3ecdb45 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,8 @@ plugins { id 'fabric-loom' version '1.5-SNAPSHOT' id 'maven-publish' - id "org.jetbrains.kotlin.jvm" version "1.9.22" + id "org.jetbrains.kotlin.jvm" version "1.9.22" + id 'idea' } version = project.mod_version @@ -11,6 +12,13 @@ base { archivesName = project.archives_base_name } +idea { + module { + downloadJavadoc = false + downloadSources = true + } +} + repositories { // Add repositories to retrieve artifacts from in here. // You should only use this when depending on other mods because diff --git a/src/main/kotlin/net/easecation/bedrockloader/BedrockLoader.kt b/src/main/kotlin/net/easecation/bedrockloader/BedrockLoader.kt index 34d2b79..7280342 100644 --- a/src/main/kotlin/net/easecation/bedrockloader/BedrockLoader.kt +++ b/src/main/kotlin/net/easecation/bedrockloader/BedrockLoader.kt @@ -18,7 +18,7 @@ object BedrockLoader : ModInitializer { val logger: Logger = LoggerFactory.getLogger("bedrock-loader") - private const val NAMESPACE: String = "bedrock-loader" + const val NAMESPACE: String = "bedrock-loader" val BEDROCK_LOADER_MOD: ModContainer = FabricLoader.getInstance().getModContainer(NAMESPACE).orElseThrow() override fun onInitialize() { diff --git a/src/main/kotlin/net/easecation/bedrockloader/BedrockLoaderClient.kt b/src/main/kotlin/net/easecation/bedrockloader/BedrockLoaderClient.kt index c25f39a..87f00a7 100644 --- a/src/main/kotlin/net/easecation/bedrockloader/BedrockLoaderClient.kt +++ b/src/main/kotlin/net/easecation/bedrockloader/BedrockLoaderClient.kt @@ -1,6 +1,7 @@ package net.easecation.bedrockloader import net.easecation.bedrockloader.render.BedrockModelProvider +import net.easecation.bedrockloader.render.BedrockVariantProvider import net.fabricmc.api.ClientModInitializer import net.fabricmc.api.EnvType import net.fabricmc.api.Environment @@ -11,6 +12,7 @@ object BedrockLoaderClient : ClientModInitializer { override fun onInitializeClient() { ModelLoadingRegistry.INSTANCE.registerResourceProvider { rm -> BedrockModelProvider } + ModelLoadingRegistry.INSTANCE.registerVariantProvider() { rm -> BedrockVariantProvider } } } \ No newline at end of file diff --git a/src/main/kotlin/net/easecation/bedrockloader/block/BlockDataDriven.kt b/src/main/kotlin/net/easecation/bedrockloader/block/BlockDataDriven.kt index 304f9f5..361a600 100644 --- a/src/main/kotlin/net/easecation/bedrockloader/block/BlockDataDriven.kt +++ b/src/main/kotlin/net/easecation/bedrockloader/block/BlockDataDriven.kt @@ -23,7 +23,7 @@ class BlockDataDriven private constructor(val identifier: Identifier, val compon } private fun calculateSettings(components: BlockComponents): Settings { - val settings = FabricBlockSettings.of(Material.METAL).hardness(4.0f) // TODO hardness + val settings = FabricBlockSettings.of(Material.METAL).hardness(4.0f).nonOpaque() // TODO hardness components.minecraftCollisionBox?.let { when (it) { is ComponentCollisionBox.ComponentCollisionBoxBoolean -> { @@ -66,5 +66,4 @@ class BlockDataDriven private constructor(val identifier: Identifier, val compon return super.getOutlineShape(state, view, pos, context) } } - } \ No newline at end of file diff --git a/src/main/kotlin/net/easecation/bedrockloader/loader/BedrockResourcePackLoader.kt b/src/main/kotlin/net/easecation/bedrockloader/loader/BedrockResourcePackLoader.kt index 9cc35ba..5be392f 100644 --- a/src/main/kotlin/net/easecation/bedrockloader/loader/BedrockResourcePackLoader.kt +++ b/src/main/kotlin/net/easecation/bedrockloader/loader/BedrockResourcePackLoader.kt @@ -17,6 +17,8 @@ import net.easecation.bedrockloader.util.GsonUtil import net.fabricmc.api.EnvType import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry import net.fabricmc.loader.api.FabricLoader +import net.minecraft.client.texture.SpriteAtlasTexture +import net.minecraft.client.util.SpriteIdentifier import net.minecraft.entity.EntityType import net.minecraft.util.Identifier import java.io.File @@ -41,7 +43,7 @@ class BedrockResourcePackLoader( for (block in context.resource.blocks) { val identifier = block.key val dir = namespaceDir(identifier.namespace) - createBlockTextures(identifier, block.value.textures) + createBlockTextures(identifier, block.value.textures, context.behavior.blocks[identifier]?.components?.minecraftMaterialInstances) createBlockModel( dir.resolve("models/block/${identifier.path}.json"), identifier, @@ -51,10 +53,11 @@ class BedrockResourcePackLoader( ) createItemModel(dir.resolve("models/item/${identifier.path}.json"), identifier) createBlockState( - dir.resolve("blockstates/${identifier.path}.json"), - identifier, - context.behavior.blocks[identifier]?.components?.minecraftGeometry, - context.behavior.blocks[identifier]?.components?.minecraftMaterialInstances) + dir.resolve("blockstates/${identifier.path}.json"), + identifier, + context.behavior.blocks[identifier]?.components?.minecraftGeometry, + context.behavior.blocks[identifier]?.components?.minecraftMaterialInstances + ) } // Entity for (entity in context.resource.entities) { @@ -134,6 +137,10 @@ class BedrockResourcePackLoader( if (!texturesBlock.exists()) { texturesBlock.mkdirs() } + val texturesBlocks = textures.resolve("blocks") + if (!texturesBlocks.exists()) { + texturesBlocks.mkdirs() + } val texturesEntity = textures.resolve("entity") if (!texturesEntity.exists()) { texturesEntity.mkdirs() @@ -147,20 +154,20 @@ class BedrockResourcePackLoader( * 创建一个方块状态文件,内部包含model路径(附带命名空间) * 如果方块带模型,则详见createBlockModel,在创建的方块模型中,继承与自定义基岩版geometry模型,从而调用自定义渲染器和烘焙器来渲染基岩版模型 */ - private fun createBlockState(file: File, identifier: Identifier, geometry: ComponentGeometry?, materialInstances: ComponentMaterialInstances?) { + private fun createBlockState( + file: File, + identifier: Identifier, + geometry: ComponentGeometry?, + materialInstances: ComponentMaterialInstances? + ) { // TODO block state - var model = "${identifier.namespace}:block/${identifier.path}" // 带有模型的方块情况:通过行为包定义模型和贴图 - when (geometry) { - is ComponentGeometry.ComponentGeometrySimple -> { - model = geometry.identifier - } - is ComponentGeometry.ComponentGeometryFull -> { - model = geometry.identifier - // TODO bone_visibility - } - else -> {} - } +// val model = when (geometry) { +// is ComponentGeometry.ComponentGeometrySimple -> geometry.identifier +// is ComponentGeometry.ComponentGeometryFull -> geometry.identifier +// null -> "${identifier.namespace}:block/${identifier.path}" +// } + val model = "${identifier.namespace}:block/${identifier.path}" val blockState = JavaBlockStatesDefinition( variants = mapOf( "" to JavaBlockStatesDefinition.Variant(model) @@ -174,7 +181,11 @@ class BedrockResourcePackLoader( /** * 根据方块材质包中的定义,创建一个方块贴图文件(附带命名空间) */ - private fun createBlockTextures(identifier: Identifier, textures: BlockResourceDefinition.Textures?) { + private fun createBlockTextures( + identifier: Identifier, + textures: BlockResourceDefinition.Textures?, + materialInstances: ComponentMaterialInstances? + ) { val namespaceDir = this.namespaceDir(identifier.namespace) when (textures) { is BlockResourceDefinition.Textures.TexturesAllFace -> { @@ -223,91 +234,101 @@ class BedrockResourcePackLoader( } else -> {} } + materialInstances?.forEach { name, instance -> + val texture = context.resource.terrainTexture[instance.texture]?.textures + if (texture == null || !texture.contains("textures/")) { + BedrockLoader.logger.warn("[BedrockResourcePackLoader] Material instance texture not found: ${instance.texture}") + return@forEach + } + val bedrockTexture = context.resource.textureImages[texture] + if (bedrockTexture == null) { + BedrockLoader.logger.warn("[BedrockResourcePackLoader] Material instance texture not found: ${instance.texture}") + return@forEach + } + val file = namespaceDir.resolve(texture + "." + bedrockTexture.type.getExtension()) + bedrockTexture.image.let { image -> + ImageIO.write(image, file.extension, file) + } + + } } /** * 根据方块材质包和行为包中的定义,创建一个方块模型文件(如果设定了模型,则应用模型;否则应用正常方块模型) */ private fun createBlockModel(file: File, identifier: Identifier, textures: BlockResourceDefinition.Textures?, geometry: ComponentGeometry?, materialInstances: ComponentMaterialInstances?) { - val model = JavaModelDefinition() - if (geometry != null) { - return - } - // 带有模型的方块情况:通过行为包定义模型和贴图 - when (geometry) { - is ComponentGeometry.ComponentGeometrySimple -> { - model.parent = geometry.identifier + // 带有模型的方块情况:通过行为包定义模型和贴图 + val geometryIdentifier = when (geometry) { + is ComponentGeometry.ComponentGeometrySimple -> geometry.identifier + is ComponentGeometry.ComponentGeometryFull -> geometry.identifier } - is ComponentGeometry.ComponentGeometryFull -> { - model.parent = geometry.identifier - // TODO bone_visibility - } - else -> { - when (textures) { - is BlockResourceDefinition.Textures.TexturesAllFace -> { - model.parent = "block/cube_all" - } - is BlockResourceDefinition.Textures.TexturesMultiFace -> { - model.parent = "block/cube" + val bedrockModel = BedrockAddonsRegistry.models[geometryIdentifier] ?: return + val textureKey = materialInstances?.get("*")?.texture ?: return + val terrainTexture = context.resource.terrainTexture[textureKey]?.textures ?: return + val texture = if (terrainTexture.startsWith("textures/", ignoreCase = true)) terrainTexture.substring("textures/".length) else terrainTexture + val spriteId = SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, Identifier(identifier.namespace, texture)) + bedrockModel.addSprite(spriteId) + } else { + val model = JavaModelDefinition() + model.parent = "block/cube_all" + + // 通过行为包定义了贴图 + materialInstances?.forEach { (key, value) -> + if (key == "*") { + value.texture?.let { texture -> + val javaTexture = context.resource.terrainTextureToJava(texture, identifier.namespace) + if (javaTexture != null) { + model.textures = mapOf("all" to javaTexture) // TODO 不确定是什么key... + } } - else -> {} + } else { + BedrockLoader.logger.info("[BedrockResourcePackLoader] Material instance $key -> $value is not supported yet.") } } - } - // 通过行为包定义了贴图 - materialInstances?.forEach { (key, value) -> - if (key == "*") { - value.texture?.let { texture -> - val javaTexture = context.resource.terrainTextureToJava(texture, identifier.namespace) - if (javaTexture != null) { - model.textures = mapOf("all" to javaTexture) // TODO 不确定是什么key... + // 普通方块情况:通过材质包的blocks.json定义贴图 + when (textures) { + is BlockResourceDefinition.Textures.TexturesAllFace -> { + val texture = context.resource.terrainTexture[textures.all]?.textures + if (texture == null || !texture.contains("textures/")) { + BedrockLoader.logger.warn("[BedrockResourcePackLoader] Block texture not found: ${textures.all}") + return } + context.resource.terrainTextureToJava(textures.all, identifier.namespace) + ?.let { model.textures = mapOf("all" to it) } } - } else { - BedrockLoader.logger.info("[BedrockResourcePackLoader] Material instance $key -> $value is not supported yet.") - } - } - // 普通方块情况:通过材质包的blocks.json定义贴图 - when (textures) { - is BlockResourceDefinition.Textures.TexturesAllFace -> { - val texture = context.resource.terrainTexture[textures.all]?.textures - if (texture == null || !texture.contains("textures/")) { - BedrockLoader.logger.warn("[BedrockResourcePackLoader] Block texture not found: ${textures.all}") - return - } - context.resource.terrainTextureToJava(textures.all, identifier.namespace)?.let { model.textures = mapOf("all" to it) } - } - is BlockResourceDefinition.Textures.TexturesMultiFace -> { - val texturesMap = mutableMapOf() + is BlockResourceDefinition.Textures.TexturesMultiFace -> { + val texturesMap = mutableMapOf() - val directions = mapOf( + val directions = mapOf( "up" to textures.up, "down" to textures.down, "north" to textures.north, "south" to textures.south, "east" to textures.east, "west" to textures.west - ) + ) - for ((direction, textureKey) in directions) { - textureKey?.let { - val texture = context.resource.terrainTextureToJava(it, identifier.namespace) - if (texture != null) { - texturesMap[direction] = texture + for ((direction, textureKey) in directions) { + textureKey?.let { + val texture = context.resource.terrainTextureToJava(it, identifier.namespace) + if (texture != null) { + texturesMap[direction] = texture + } } } + + model.textures = texturesMap } - model.textures = texturesMap + else -> {} } - else -> {} - } - FileWriter(file).use { writer -> - GsonUtil.GSON.toJson(model, writer) + FileWriter(file).use { writer -> + GsonUtil.GSON.toJson(model, writer) + } } } diff --git a/src/main/kotlin/net/easecation/bedrockloader/render/BedrockGeometryModel.kt b/src/main/kotlin/net/easecation/bedrockloader/render/BedrockGeometryModel.kt index b85986a..8062e87 100644 --- a/src/main/kotlin/net/easecation/bedrockloader/render/BedrockGeometryModel.kt +++ b/src/main/kotlin/net/easecation/bedrockloader/render/BedrockGeometryModel.kt @@ -17,7 +17,6 @@ import net.minecraft.client.render.model.json.JsonUnbakedModel import net.minecraft.client.render.model.json.ModelOverrideList import net.minecraft.client.render.model.json.ModelTransformation import net.minecraft.client.texture.Sprite -import net.minecraft.client.texture.SpriteAtlasTexture import net.minecraft.client.util.SpriteIdentifier import net.minecraft.client.util.math.MatrixStack import net.minecraft.item.ItemStack @@ -27,6 +26,7 @@ import net.minecraft.util.math.Direction import net.minecraft.world.BlockRenderView import java.util.* import java.util.function.Supplier +import kotlin.collections.ArrayList @Environment(EnvType.CLIENT) @@ -34,11 +34,9 @@ class BedrockGeometryModel( private val bedrockModel: GeometryDefinition.Model, ) : EntityModel(), UnbakedModel, BakedModel, FabricBakedModel { - private val DEFAULT_BLOCK_MODEL = Identifier("minecraft:block/block") - private val SPRITE_IDS = arrayOf(SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, Identifier("minecraft:block/furnace_front_on")), - SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, Identifier("minecraft:block/furnace_top")) - ) - private val SPRITES = arrayOfNulls(2) + private val defaultBlockModel = Identifier("minecraft:block/block") + private val spriteIds: ArrayList = ArrayList() + private val sprites: ArrayList = ArrayList() private var transformation: ModelTransformation? = null private val modelPart: ModelPart = getTexturedModelData().createModel() @@ -52,14 +50,18 @@ class BedrockGeometryModel( } } + fun addSprite(spriteId: SpriteIdentifier) { + spriteIds.add(spriteId) + } + override fun getModelDependencies(): Collection { return emptyList() // 模型不依赖于其他模型。 } override fun getTextureDependencies(unbakedModelGetter: java.util.function.Function?, unresolvedTextureReferences: MutableSet>?): MutableList { val map = mutableListOf() - for (i in 0..1) { - map.add(SPRITE_IDS[i]) + spriteIds.forEach { + map.add(it) } return map // 本模型(以及其模型依赖,依赖的依赖,等)依赖的纹理。 TODO } @@ -67,14 +69,14 @@ class BedrockGeometryModel( override fun bake(loader: ModelLoader, textureGetter: java.util.function.Function, rotationContainer: ModelBakeSettings?, modelId: Identifier?): BakedModel { BedrockLoader.logger.info("Baking model... $modelId ${bedrockModel.description.identifier}") // 加载默认方块模型 - val defaultBlockModel = loader.getOrLoadModel(DEFAULT_BLOCK_MODEL) as JsonUnbakedModel + val defaultBlockModel = loader.getOrLoadModel(defaultBlockModel) as JsonUnbakedModel // 获取 ModelTransformation transformation = defaultBlockModel.transformations // 获得sprites - for (i in 0..1) { - SPRITES[i] = textureGetter.apply(SPRITE_IDS[i]) + spriteIds.forEach { + sprites.add(textureGetter.apply(it)) } - mesh = BedrockRenderUtil.bakeModelPartToMesh(modelPart) + mesh = BedrockRenderUtil.bakeModelPartToMesh(modelPart, sprites[0]) return this } @@ -99,7 +101,7 @@ class BedrockGeometryModel( } override fun getParticleSprite(): Sprite { - return SPRITES[1]!! // 方块被破坏时产生的颗粒,使用furnace_top + return sprites[0] // 方块被破坏时产生的颗粒,使用furnace_top } override fun isVanillaAdapter(): Boolean { @@ -125,6 +127,7 @@ class BedrockGeometryModel( // EntityModel methods override fun render(matrices: MatrixStack, vertices: VertexConsumer, light: Int, overlay: Int, red: Float, green: Float, blue: Float, alpha: Float) { + matrices.translate(0.0, 1.5, 0.0) modelPart.render(matrices, vertices, light, overlay, red, green, blue, alpha) } diff --git a/src/main/kotlin/net/easecation/bedrockloader/render/BedrockModelProvider.kt b/src/main/kotlin/net/easecation/bedrockloader/render/BedrockModelProvider.kt index 44e4739..a721efa 100644 --- a/src/main/kotlin/net/easecation/bedrockloader/render/BedrockModelProvider.kt +++ b/src/main/kotlin/net/easecation/bedrockloader/render/BedrockModelProvider.kt @@ -1,5 +1,7 @@ package net.easecation.bedrockloader.render +import net.easecation.bedrockloader.bedrock.block.component.ComponentGeometry +import net.easecation.bedrockloader.loader.BedrockAddonsLoader import net.easecation.bedrockloader.loader.BedrockAddonsRegistry import net.fabricmc.fabric.api.client.model.ModelProviderContext import net.fabricmc.fabric.api.client.model.ModelResourceProvider @@ -9,7 +11,17 @@ import net.minecraft.util.Identifier object BedrockModelProvider : ModelResourceProvider { override fun loadModelResource(resourceId: Identifier, context: ModelProviderContext): UnbakedModel? { - return BedrockAddonsRegistry.models[resourceId.path]?.let { return it } + if (resourceId.path.startsWith("block/")) { + val identifier = Identifier(resourceId.namespace, resourceId.path.substring("block/".length)) + val geometry = BedrockAddonsLoader.context.behavior.blocks[identifier]?.components?.minecraftGeometry ?: return null + val geometryIdentifier = when (geometry) { + is ComponentGeometry.ComponentGeometrySimple -> geometry.identifier + is ComponentGeometry.ComponentGeometryFull -> geometry.identifier + } + return BedrockAddonsRegistry.models[geometryIdentifier] + } else { + return null + } } } \ No newline at end of file diff --git a/src/main/kotlin/net/easecation/bedrockloader/render/BedrockRenderUtil.kt b/src/main/kotlin/net/easecation/bedrockloader/render/BedrockRenderUtil.kt index eb4cac9..8c193c9 100644 --- a/src/main/kotlin/net/easecation/bedrockloader/render/BedrockRenderUtil.kt +++ b/src/main/kotlin/net/easecation/bedrockloader/render/BedrockRenderUtil.kt @@ -3,7 +3,10 @@ package net.easecation.bedrockloader.render import net.easecation.bedrockloader.bedrock.definition.GeometryDefinition import net.easecation.bedrockloader.render.model.* import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh +import net.minecraft.client.texture.Sprite import net.minecraft.client.util.math.MatrixStack +import net.minecraft.util.math.Quaternion +import net.minecraft.util.math.Vec3f object BedrockRenderUtil { @@ -70,10 +73,9 @@ object BedrockRenderUtil { } val modelData = ModelData() - val rootPartData = modelData.root.addChild("offset", ModelPartBuilder.create(), ModelTransform.pivot(0f, 24f, 0f)) for (bone in bones) { if (bone.parent == null) { - addBoneToModelData(bone, rootPartData) + addBoneToModelData(bone, modelData.root) } } return modelData @@ -84,9 +86,11 @@ object BedrockRenderUtil { * @param modelPart The ModelPart to convert. * @return The created Mesh. */ - fun bakeModelPartToMesh(modelPart: ModelPart): Mesh { + fun bakeModelPartToMesh(modelPart: ModelPart, sprite: Sprite): Mesh { val matrixStack = MatrixStack() - val vertices = MeshBuilderVertexConsumer() + matrixStack.translate(0.5, 0.0, 0.5) + matrixStack.multiply(Vec3f.POSITIVE_X.getDegreesQuaternion(180f)) + val vertices = MeshBuilderVertexConsumer(sprite) modelPart.render(matrixStack, vertices, 1, 1) return vertices.build() } diff --git a/src/main/kotlin/net/easecation/bedrockloader/render/BedrockVariantProvider.kt b/src/main/kotlin/net/easecation/bedrockloader/render/BedrockVariantProvider.kt new file mode 100644 index 0000000..6ef8215 --- /dev/null +++ b/src/main/kotlin/net/easecation/bedrockloader/render/BedrockVariantProvider.kt @@ -0,0 +1,26 @@ +package net.easecation.bedrockloader.render + +import net.easecation.bedrockloader.bedrock.block.component.ComponentGeometry +import net.easecation.bedrockloader.loader.BedrockAddonsLoader +import net.easecation.bedrockloader.loader.BedrockAddonsRegistry +import net.fabricmc.fabric.api.client.model.ModelProviderContext +import net.fabricmc.fabric.api.client.model.ModelVariantProvider +import net.minecraft.client.render.model.UnbakedModel +import net.minecraft.client.util.ModelIdentifier +import net.minecraft.util.Identifier + +object BedrockVariantProvider : ModelVariantProvider { + override fun loadModelVariant(modelId: ModelIdentifier, context: ModelProviderContext): UnbakedModel? { + if (modelId.variant.equals("inventory")) { + val identifier = Identifier(modelId.namespace, modelId.path) + val geometry = BedrockAddonsLoader.context.behavior.blocks[identifier]?.components?.minecraftGeometry ?: return null + val geometryIdentifier = when (geometry) { + is ComponentGeometry.ComponentGeometrySimple -> geometry.identifier + is ComponentGeometry.ComponentGeometryFull -> geometry.identifier + } + return BedrockAddonsRegistry.models[geometryIdentifier] + } else { + return null + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/net/easecation/bedrockloader/render/MeshBuilderVertexConsumer.kt b/src/main/kotlin/net/easecation/bedrockloader/render/MeshBuilderVertexConsumer.kt index 21646f9..c86b2ec 100644 --- a/src/main/kotlin/net/easecation/bedrockloader/render/MeshBuilderVertexConsumer.kt +++ b/src/main/kotlin/net/easecation/bedrockloader/render/MeshBuilderVertexConsumer.kt @@ -1,19 +1,14 @@ package net.easecation.bedrockloader.render -import net.easecation.bedrockloader.BedrockLoader 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.MutableQuadView import net.minecraft.client.render.VertexConsumer -import net.minecraft.client.render.VertexFormats -import net.minecraft.client.render.model.BakedQuad -import net.minecraft.client.util.math.MatrixStack -import net.minecraft.util.math.Vec3f -import net.minecraft.util.math.Vector4f -import org.lwjgl.system.MemoryStack +import net.minecraft.client.texture.Sprite -class MeshBuilderVertexConsumer : VertexIndexedVertexConsumer { +class MeshBuilderVertexConsumer(private val sprite: Sprite) : VertexIndexedVertexConsumer { private val renderer: Renderer = RendererAccess.INSTANCE.renderer!! private val meshBuilder: MeshBuilder = renderer.meshBuilder() @@ -21,122 +16,75 @@ class MeshBuilderVertexConsumer : VertexIndexedVertexConsumer { private var vertexIndex = 0 - override fun quad(matrixEntry: MatrixStack.Entry, quad: BakedQuad, brightnesses: FloatArray, red: Float, green: Float, blue: Float, lights: IntArray, overlay: Int, useQuadColorData: Boolean) { - val fs = floatArrayOf(brightnesses[0], brightnesses[1], brightnesses[2], brightnesses[3]) - val `is` = intArrayOf(lights[0], lights[1], lights[2], lights[3]) - val js = quad.vertexData - val vec3i = quad.face.vector - val vec3f = Vec3f(vec3i.x.toFloat(), vec3i.y.toFloat(), vec3i.z.toFloat()) - val matrix4f = matrixEntry.positionMatrix - vec3f.transform(matrixEntry.normalMatrix) - val i = 8 - val j = js.size / 8 - MemoryStack.stackPush().use { memoryStack -> - val byteBuffer = memoryStack.malloc(VertexFormats.POSITION_COLOR_TEXTURE_LIGHT_NORMAL.vertexSize) - val intBuffer = byteBuffer.asIntBuffer() - for (k in 0 until j) { - var q: Float - var p: Float - var o: Float - var n: Float - var m: Float - intBuffer.clear() - intBuffer.put(js, k * 8, 8) - val f = byteBuffer.getFloat(0) - val g = byteBuffer.getFloat(4) - val h = byteBuffer.getFloat(8) - if (useQuadColorData) { - val l = (byteBuffer[12].toInt() and 0xFF).toFloat() / 255.0f - m = (byteBuffer[13].toInt() and 0xFF).toFloat() / 255.0f - n = (byteBuffer[14].toInt() and 0xFF).toFloat() / 255.0f - o = l * fs[k] * red - p = m * fs[k] * green - q = n * fs[k] * blue - } else { - o = fs[k] * red - p = fs[k] * green - q = fs[k] * blue - } - val r = `is`[k] - m = byteBuffer.getFloat(16) - n = byteBuffer.getFloat(20) - val vector4f = Vector4f(f, g, h, 1.0f) - vector4f.transform(matrix4f) - emitter.pos(k, vector4f.x, vector4f.y, vector4f.z) - // emitter.spriteBake(k, ) // TODO texture - emitter.spriteColor(k, -1, -1, -1, -1) - emitter.spriteColor(k, (o * 255).toInt(), (p * 255).toInt(), (q * 255).toInt(), 255) - emitter.normal(k, vec3f) - emitter.lightmap(k, r) - this.vertex(vector4f.x, vector4f.y, vector4f.z, o, p, q, 1.0f, m, n, overlay, r, vec3f.x, vec3f.y, vec3f.z) - emitter.emit() - } - } - } - override fun vertex(x: Double, y: Double, z: Double): VertexConsumer { - BedrockLoader.logger.info("MeshBuilderVertexConsumer.vertex($x, $y, $z)") + // BedrockLoader.logger.info("MeshBuilderVertexConsumer.vertex($x, $y, $z)") emitter.pos(vertexIndex, x.toFloat(), y.toFloat(), z.toFloat()) return this } override fun color(red: Int, green: Int, blue: Int, alpha: Int): VertexConsumer { - BedrockLoader.logger.info("MeshBuilderVertexConsumer.color($red, $green, $blue, $alpha)") - emitter.spriteColor(0, red, green, blue, alpha) + // BedrockLoader.logger.info("MeshBuilderVertexConsumer.color($red, $green, $blue, $alpha)") + emitter.spriteColor(vertexIndex, 0, (red and 0xFF) or ((green and 0xFF) shl 8) or ((blue and 0xFF) shl 16) or ((alpha and 0xFF) shl 24)) return this } override fun texture(u: Float, v: Float): VertexConsumer { - BedrockLoader.logger.info("MeshBuilderVertexConsumer.texture($u, $v)") + // BedrockLoader.logger.info("MeshBuilderVertexConsumer.texture($u, $v)") emitter.sprite(vertexIndex, 0, u, v) return this } override fun overlay(u: Int, v: Int): VertexConsumer { - BedrockLoader.logger.info("MeshBuilderVertexConsumer.overlay($u, $v)") + // BedrockLoader.logger.info("MeshBuilderVertexConsumer.overlay($u, $v)") return this } override fun overlay(overlay: Int): VertexConsumer { - BedrockLoader.logger.info("MeshBuilderVertexConsumer.overlay($overlay)") + // BedrockLoader.logger.info("MeshBuilderVertexConsumer.overlay($overlay)") return this } override fun light(u: Int, v: Int): VertexConsumer { - BedrockLoader.logger.info("MeshBuilderVertexConsumer.light($u, $v)") + // BedrockLoader.logger.info("MeshBuilderVertexConsumer.light($u, $v)") emitter.lightmap(vertexIndex, v) return this } override fun light(light: Int): VertexConsumer { - BedrockLoader.logger.info("MeshBuilderVertexConsumer.light($light)") + // BedrockLoader.logger.info("MeshBuilderVertexConsumer.light($light)") emitter.lightmap(vertexIndex, light) return this } override fun normal(x: Float, y: Float, z: Float): VertexConsumer { - BedrockLoader.logger.info("MeshBuilderVertexConsumer.normal($x, $y, $z)") + // BedrockLoader.logger.info("MeshBuilderVertexConsumer.normal($x, $y, $z)") emitter.normal(vertexIndex, x, y, z) return this } override fun next() { - BedrockLoader.logger.info("MeshBuilderVertexConsumer.next()") - emitter.emit() + // BedrockLoader.logger.info("MeshBuilderVertexConsumer.next()") } override fun vertexIndex(index: Int) { + // BedrockLoader.logger.info("MeshBuilderVertexConsumer.vertexIndex($index)") vertexIndex = index } + override fun nextQuad() { + // BedrockLoader.logger.info("MeshBuilderVertexConsumer.nextQuad()") + emitter.spriteBake(0, sprite, MutableQuadView.BAKE_NORMALIZED) + emitter.emit() + } + override fun fixedColor(red: Int, green: Int, blue: Int, alpha: Int) { - BedrockLoader.logger.info("MeshBuilderVertexConsumer.fixedColor($red, $green, $blue, $alpha)") - emitter.spriteColor(vertexIndex, red, green, blue, alpha) + // BedrockLoader.logger.info("MeshBuilderVertexConsumer.fixedColor($red, $green, $blue, $alpha)") + emitter.spriteColor(vertexIndex, 0, (red and 0xFF) or ((green and 0xFF) shl 8) or ((blue and 0xFF) shl 16) or ((alpha and 0xFF) shl 24)) } override fun unfixColor() { - BedrockLoader.logger.info("MeshBuilderVertexConsumer.unfixColor()") - emitter.spriteColor(vertexIndex, -1, -1, -1, -1) + // BedrockLoader.logger.info("MeshBuilderVertexConsumer.unfixColor()") + emitter.spriteColor(vertexIndex, 0, -1) } fun build(): Mesh { diff --git a/src/main/kotlin/net/easecation/bedrockloader/render/VertexIndexedVertexConsumer.kt b/src/main/kotlin/net/easecation/bedrockloader/render/VertexIndexedVertexConsumer.kt index 05c8a0f..dd23ee9 100644 --- a/src/main/kotlin/net/easecation/bedrockloader/render/VertexIndexedVertexConsumer.kt +++ b/src/main/kotlin/net/easecation/bedrockloader/render/VertexIndexedVertexConsumer.kt @@ -6,4 +6,6 @@ interface VertexIndexedVertexConsumer : VertexConsumer { fun vertexIndex(index: Int) + fun nextQuad() + } \ No newline at end of file diff --git a/src/main/kotlin/net/easecation/bedrockloader/render/model/ModelPart.kt b/src/main/kotlin/net/easecation/bedrockloader/render/model/ModelPart.kt index ddaeae0..77373eb 100644 --- a/src/main/kotlin/net/easecation/bedrockloader/render/model/ModelPart.kt +++ b/src/main/kotlin/net/easecation/bedrockloader/render/model/ModelPart.kt @@ -254,6 +254,9 @@ class ModelPart(private val cuboids: List, private val children: Map