ItemFeature: render multiple items

This commit is contained in:
Moritz Zwerger 2023-11-15 18:09:40 +01:00
parent 88eeac3e09
commit 2fa06dba62
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
2 changed files with 42 additions and 5 deletions

View File

@ -25,6 +25,7 @@ import de.bixilon.minosoft.gui.rendering.util.mesh.MeshStruct
class BlockMesh(context: RenderContext) : Mesh(context, BlockMeshStruct), BlockVertexConsumer { class BlockMesh(context: RenderContext) : Mesh(context, BlockMeshStruct), BlockVertexConsumer {
override val order = context.system.quadOrder override val order = context.system.quadOrder
val offset = Vec3()
override fun ensureSize(size: Int) { override fun ensureSize(size: Int) {
data.ensureSize(size) data.ensureSize(size)
@ -33,7 +34,7 @@ class BlockMesh(context: RenderContext) : Mesh(context, BlockMeshStruct), BlockV
override fun addVertex(position: FloatArray, uv: Vec2, texture: ShaderTexture, tintColor: Int, light: Int) { override fun addVertex(position: FloatArray, uv: Vec2, texture: ShaderTexture, tintColor: Int, light: Int) {
data.ensureSize(BlockMeshStruct.FLOATS_PER_VERTEX) data.ensureSize(BlockMeshStruct.FLOATS_PER_VERTEX)
val transformedUV = texture.transformUV(uv).array val transformedUV = texture.transformUV(uv).array
data.add(position) data.add(position[0] + offset.x, position[1] + offset.y, position[2] + offset.z)
data.add(transformedUV) data.add(transformedUV)
data.add( data.add(
texture.shaderId.buffer(), texture.shaderId.buffer(),
@ -43,7 +44,7 @@ class BlockMesh(context: RenderContext) : Mesh(context, BlockMeshStruct), BlockV
override inline fun addVertex(x: Float, y: Float, z: Float, u: Float, v: Float, textureId: Float, lightTint: Float) { override inline fun addVertex(x: Float, y: Float, z: Float, u: Float, v: Float, textureId: Float, lightTint: Float) {
data.add( data.add(
x, y, z, x + offset.x, y + offset.y, z + offset.z,
u, v, u, v,
textureId, lightTint, textureId, lightTint,
) )

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.gui.rendering.entities.feature.item package de.bixilon.minosoft.gui.rendering.entities.feature.item
import de.bixilon.kotlinglm.mat4x4.Mat4 import de.bixilon.kotlinglm.mat4x4.Mat4
import de.bixilon.kutil.random.RandomUtil.nextFloat
import de.bixilon.minosoft.data.container.stack.ItemStack import de.bixilon.minosoft.data.container.stack.ItemStack
import de.bixilon.minosoft.gui.rendering.entities.feature.block.BlockMesh import de.bixilon.minosoft.gui.rendering.entities.feature.block.BlockMesh
import de.bixilon.minosoft.gui.rendering.entities.feature.properties.MeshedFeature import de.bixilon.minosoft.gui.rendering.entities.feature.properties.MeshedFeature
@ -21,9 +22,11 @@ import de.bixilon.minosoft.gui.rendering.entities.renderer.EntityRenderer
import de.bixilon.minosoft.gui.rendering.entities.visibility.EntityLayer import de.bixilon.minosoft.gui.rendering.entities.visibility.EntityLayer
import de.bixilon.minosoft.gui.rendering.models.item.ItemRenderUtil.getModel import de.bixilon.minosoft.gui.rendering.models.item.ItemRenderUtil.getModel
import de.bixilon.minosoft.gui.rendering.models.raw.display.DisplayPositions import de.bixilon.minosoft.gui.rendering.models.raw.display.DisplayPositions
import de.bixilon.minosoft.gui.rendering.util.mat.mat4.Mat4Util.EMPTY_INSTANCE
import de.bixilon.minosoft.gui.rendering.util.mat.mat4.Mat4Util.reset import de.bixilon.minosoft.gui.rendering.util.mat.mat4.Mat4Util.reset
import de.bixilon.minosoft.gui.rendering.util.mat.mat4.Mat4Util.translateXAssign import de.bixilon.minosoft.gui.rendering.util.mat.mat4.Mat4Util.translateXAssign
import de.bixilon.minosoft.gui.rendering.util.mat.mat4.Mat4Util.translateZAssign import de.bixilon.minosoft.gui.rendering.util.mat.mat4.Mat4Util.translateZAssign
import java.util.*
open class ItemFeature( open class ItemFeature(
renderer: EntityRenderer<*>, renderer: EntityRenderer<*>,
@ -31,6 +34,7 @@ open class ItemFeature(
val display: DisplayPositions, val display: DisplayPositions,
) : MeshedFeature<BlockMesh>(renderer) { ) : MeshedFeature<BlockMesh>(renderer) {
private var matrix = Mat4() private var matrix = Mat4()
private var displayMatrix: Mat4 = Mat4.EMPTY_INSTANCE
var stack: ItemStack? = stack var stack: ItemStack? = stack
set(value) { set(value) {
if (field == value) return if (field == value) return
@ -53,23 +57,51 @@ open class ItemFeature(
private fun createMesh(stack: ItemStack) { private fun createMesh(stack: ItemStack) {
val model = stack.item.item.getModel(renderer.renderer.connection) ?: return val model = stack.item.item.getModel(renderer.renderer.connection) ?: return
val display = model.getDisplay(display)
this.displayMatrix = display?.matrix ?: Mat4.EMPTY_INSTANCE
val mesh = BlockMesh(renderer.renderer.context) val mesh = BlockMesh(renderer.renderer.context)
val tint = renderer.renderer.context.tints.getItemTint(stack) val tint = renderer.renderer.context.tints.getItemTint(stack)
val count = count(stack.item.count)
model.render(mesh, stack, tint) // 0 without offset
if (count > 1) {
val random = Random(1234567890123456789L)
for (i in 0 until count - 1) {
mesh.offset.x = random.nextFloat(-0.1f, 0.1f)
mesh.offset.y = random.nextFloat(-0.1f, 0.1f)
mesh.offset.z = random.nextFloat(-0.1f, 0.1f)
model.render(mesh, stack, tint) model.render(mesh, stack, tint)
}
}
// TODO: enchantment glint, ...
this.mesh = mesh this.mesh = mesh
} }
private fun count(count: Int): Int {
// that is not like vanilla, but imho better
return when {
count <= 0 -> 0
count == 1 -> 1
count < 16 -> 2
count < 32 -> 3
count < 48 -> 4
else -> 5
}
}
private fun updateMatrix() { private fun updateMatrix() {
this.matrix.reset() this.matrix.reset()
this.matrix this.matrix
.translateXAssign(-0.5f).translateZAssign(-0.5f) .translateXAssign(-0.5f).translateZAssign(-0.5f)
// TODO: rotate? // TODO
this.matrix = renderer.matrix * matrix
this.matrix = renderer.matrix * displayMatrix * matrix
} }
override fun draw(mesh: BlockMesh) { override fun draw(mesh: BlockMesh) {
@ -79,4 +111,8 @@ open class ItemFeature(
shader.tint = renderer.light.value shader.tint = renderer.light.value
super.draw(mesh) super.draw(mesh)
} }
override fun unload() {
this.displayMatrix = Mat4.EMPTY_INSTANCE
}
} }