mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 03:15:35 -04:00
item rendering fixes, item item rotation and floating
This commit is contained in:
parent
80f4bd1286
commit
66f960a28d
@ -17,6 +17,8 @@ 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.block.BlockShader
|
||||
import de.bixilon.minosoft.gui.rendering.entities.feature.item.ItemFeature.ItemRenderDistance.Companion.getCount
|
||||
import de.bixilon.minosoft.gui.rendering.entities.feature.properties.MeshedFeature
|
||||
import de.bixilon.minosoft.gui.rendering.entities.renderer.EntityRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.entities.visibility.EntityLayer
|
||||
@ -32,9 +34,11 @@ open class ItemFeature(
|
||||
renderer: EntityRenderer<*>,
|
||||
stack: ItemStack?,
|
||||
val display: DisplayPositions,
|
||||
val many: Boolean = true,
|
||||
) : MeshedFeature<BlockMesh>(renderer) {
|
||||
private var matrix = Mat4()
|
||||
private var displayMatrix: Mat4 = Mat4.EMPTY_INSTANCE
|
||||
private var distance: ItemRenderDistance? = null
|
||||
var stack: ItemStack? = stack
|
||||
set(value) {
|
||||
if (field == value) return
|
||||
@ -48,6 +52,7 @@ open class ItemFeature(
|
||||
|
||||
override fun update(millis: Long, delta: Float) {
|
||||
if (!_enabled) return unload()
|
||||
updateDistance()
|
||||
if (this.mesh == null) {
|
||||
val stack = this.stack ?: return unload()
|
||||
createMesh(stack)
|
||||
@ -55,7 +60,15 @@ open class ItemFeature(
|
||||
updateMatrix()
|
||||
}
|
||||
|
||||
private fun updateDistance() {
|
||||
val distance = ItemRenderDistance.of(renderer.distance)
|
||||
if (distance == this.distance) return
|
||||
unload()
|
||||
this.distance = distance
|
||||
}
|
||||
|
||||
private fun createMesh(stack: ItemStack) {
|
||||
val distance = this.distance ?: return
|
||||
val model = stack.item.item.getModel(renderer.renderer.connection) ?: return
|
||||
val display = model.getDisplay(display)
|
||||
this.displayMatrix = display?.matrix ?: Mat4.EMPTY_INSTANCE
|
||||
@ -63,15 +76,17 @@ open class ItemFeature(
|
||||
|
||||
val tint = renderer.renderer.context.tints.getItemTint(stack)
|
||||
|
||||
val count = count(stack.item.count)
|
||||
val count = if (many) distance.getCount(stack.item.count) else 1
|
||||
val spread = maxOf(0.1f, count / 30.0f)
|
||||
|
||||
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.2f, 0.2f)
|
||||
mesh.offset.y = random.nextFloat(-0.2f, 0.2f)
|
||||
mesh.offset.z = random.nextFloat(-0.2f, 0.2f)
|
||||
mesh.offset.x = random.nextFloat(-spread, spread)
|
||||
mesh.offset.y = random.nextFloat(-spread, spread)
|
||||
mesh.offset.z = random.nextFloat(-spread, spread)
|
||||
|
||||
model.render(mesh, stack, tint)
|
||||
}
|
||||
@ -81,26 +96,12 @@ open class ItemFeature(
|
||||
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
|
||||
|
||||
|
||||
this.matrix = renderer.matrix * displayMatrix * matrix
|
||||
}
|
||||
@ -108,6 +109,12 @@ open class ItemFeature(
|
||||
override fun draw(mesh: BlockMesh) {
|
||||
renderer.renderer.context.system.reset(faceCulling = false)
|
||||
val shader = renderer.renderer.features.block.shader
|
||||
draw(mesh, shader)
|
||||
}
|
||||
|
||||
|
||||
protected open fun draw(mesh: BlockMesh, shader: BlockShader) {
|
||||
shader.use()
|
||||
shader.matrix = matrix
|
||||
shader.tint = renderer.light.value
|
||||
super.draw(mesh)
|
||||
@ -115,5 +122,54 @@ open class ItemFeature(
|
||||
|
||||
override fun unload() {
|
||||
this.displayMatrix = Mat4.EMPTY_INSTANCE
|
||||
super.unload()
|
||||
}
|
||||
|
||||
private enum class ItemRenderDistance(distance: Double) {
|
||||
CLOSE(10.0),
|
||||
MID(20.0),
|
||||
FAR(30.0),
|
||||
EXTREME(48.0),
|
||||
;
|
||||
|
||||
val distance = distance * distance
|
||||
|
||||
companion object {
|
||||
|
||||
fun of(distance: Double) = when {
|
||||
distance < CLOSE.distance -> CLOSE
|
||||
distance < MID.distance -> MID
|
||||
distance < FAR.distance -> FAR
|
||||
distance < EXTREME.distance -> EXTREME
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun ItemRenderDistance.getCount(count: Int) = when (this) {
|
||||
CLOSE -> when {
|
||||
count <= 16 -> count
|
||||
else -> 16
|
||||
}
|
||||
|
||||
MID -> when {
|
||||
count <= 4 -> count
|
||||
count < 16 -> 5
|
||||
count < 32 -> 6
|
||||
count < 48 -> 7
|
||||
else -> 8
|
||||
}
|
||||
|
||||
FAR -> when {
|
||||
count <= 2 -> count
|
||||
count < 32 -> 3
|
||||
else -> 4
|
||||
}
|
||||
|
||||
EXTREME -> when {
|
||||
count <= 1 -> count
|
||||
count <= 32 -> 1
|
||||
else -> 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
package de.bixilon.minosoft.gui.rendering.entities.renderer.item
|
||||
|
||||
import de.bixilon.kutil.math.MathConstants.PIf
|
||||
import de.bixilon.kutil.observer.DataObserver.Companion.observe
|
||||
import de.bixilon.minosoft.data.entities.entities.item.ItemEntity
|
||||
import de.bixilon.minosoft.data.registries.identified.Identified
|
||||
@ -21,17 +22,42 @@ import de.bixilon.minosoft.gui.rendering.entities.factory.RegisteredEntityModelF
|
||||
import de.bixilon.minosoft.gui.rendering.entities.feature.item.ItemFeature
|
||||
import de.bixilon.minosoft.gui.rendering.entities.renderer.EntityRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.models.raw.display.DisplayPositions
|
||||
import de.bixilon.minosoft.gui.rendering.util.mat.mat4.Mat4Util.translateYAssign
|
||||
import kotlin.math.sin
|
||||
|
||||
class ItemEntityRenderer(renderer: EntitiesRenderer, entity: ItemEntity) : EntityRenderer<ItemEntity>(renderer, entity) {
|
||||
val item = ItemFeature(this, null, DisplayPositions.GROUND).register()
|
||||
private var floating = 0.0f
|
||||
private var rotation = 0.0f
|
||||
|
||||
init {
|
||||
entity::stack.observe(this, true) { item.stack = it }
|
||||
// TODO: rotate, lift up and down
|
||||
}
|
||||
|
||||
override fun update(millis: Long, delta: Float) {
|
||||
updateFloatingRotation(delta)
|
||||
super.update(millis, delta)
|
||||
}
|
||||
|
||||
private fun updateFloatingRotation(delta: Float) {
|
||||
floating += delta / 3.0f
|
||||
if (floating > 1.0f) floating %= 1.0f
|
||||
|
||||
rotation += delta / CIRCLE
|
||||
if (rotation > 1.0f) rotation %= 1.0f
|
||||
}
|
||||
|
||||
override fun updateMatrix(delta: Float) {
|
||||
super.updateMatrix(delta)
|
||||
|
||||
this.matrix
|
||||
.translateYAssign(sin(floating * CIRCLE) * 0.1f + 0.1f)
|
||||
.rotateYassign(rotation * CIRCLE)
|
||||
}
|
||||
|
||||
|
||||
companion object : RegisteredEntityModelFactory<ItemEntity>, Identified {
|
||||
const val CIRCLE = PIf * 2.0f
|
||||
override val identifier get() = ItemEntity.identifier
|
||||
|
||||
override fun create(renderer: EntitiesRenderer, entity: ItemEntity) = ItemEntityRenderer(renderer, entity)
|
||||
|
@ -44,10 +44,8 @@ class BlockGUIConsumer(
|
||||
override fun addQuad(offset: FloatArray, positions: FaceVertexData, uvData: FaceVertexData, textureId: Float, lightTint: Float) = Broken("Not chunk rendering")
|
||||
|
||||
override fun addQuad(positions: FaceVertexData, uvData: FaceVertexData, textureId: Float, lightTint: Float) {
|
||||
|
||||
val tint = (lightTint.toBits() shl 8) or 0xFF
|
||||
|
||||
|
||||
gui.context.system.quadOrder.iterateReverse { p, uv ->
|
||||
val vertexOffset = p * Vec3.length
|
||||
val uvOffset = uv * Vec2.length
|
||||
@ -62,9 +60,6 @@ class BlockGUIConsumer(
|
||||
|
||||
consumer.addVertex(x, y, textureId, uvData[uvOffset], uvData[uvOffset + 1], tint, options)
|
||||
}
|
||||
|
||||
// block renders from (in normal cases) from 0 to 1
|
||||
// matrix should map those pixels into screen 2d space (offset until offset+size)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
Loading…
x
Reference in New Issue
Block a user