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 {
override val order = context.system.quadOrder
val offset = Vec3()
override fun ensureSize(size: Int) {
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) {
data.ensureSize(BlockMeshStruct.FLOATS_PER_VERTEX)
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(
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) {
data.add(
x, y, z,
x + offset.x, y + offset.y, z + offset.z,
u, v,
textureId, lightTint,
)

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.gui.rendering.entities.feature.item
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.gui.rendering.entities.feature.block.BlockMesh
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.models.item.ItemRenderUtil.getModel
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.translateXAssign
import de.bixilon.minosoft.gui.rendering.util.mat.mat4.Mat4Util.translateZAssign
import java.util.*
open class ItemFeature(
renderer: EntityRenderer<*>,
@ -31,6 +34,7 @@ open class ItemFeature(
val display: DisplayPositions,
) : MeshedFeature<BlockMesh>(renderer) {
private var matrix = Mat4()
private var displayMatrix: Mat4 = Mat4.EMPTY_INSTANCE
var stack: ItemStack? = stack
set(value) {
if (field == value) return
@ -53,23 +57,51 @@ open class ItemFeature(
private fun createMesh(stack: ItemStack) {
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 tint = renderer.renderer.context.tints.getItemTint(stack)
model.render(mesh, stack, tint)
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)
}
}
// TODO: enchantment glint, ...
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() {
this.matrix.reset()
this.matrix
.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) {
@ -79,4 +111,8 @@ open class ItemFeature(
shader.tint = renderer.light.value
super.draw(mesh)
}
override fun unload() {
this.displayMatrix = Mat4.EMPTY_INSTANCE
}
}