mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 11:24:56 -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.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.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.feature.properties.MeshedFeature
|
||||||
import de.bixilon.minosoft.gui.rendering.entities.renderer.EntityRenderer
|
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
|
||||||
@ -32,9 +34,11 @@ open class ItemFeature(
|
|||||||
renderer: EntityRenderer<*>,
|
renderer: EntityRenderer<*>,
|
||||||
stack: ItemStack?,
|
stack: ItemStack?,
|
||||||
val display: DisplayPositions,
|
val display: DisplayPositions,
|
||||||
|
val many: Boolean = true,
|
||||||
) : MeshedFeature<BlockMesh>(renderer) {
|
) : MeshedFeature<BlockMesh>(renderer) {
|
||||||
private var matrix = Mat4()
|
private var matrix = Mat4()
|
||||||
private var displayMatrix: Mat4 = Mat4.EMPTY_INSTANCE
|
private var displayMatrix: Mat4 = Mat4.EMPTY_INSTANCE
|
||||||
|
private var distance: ItemRenderDistance? = null
|
||||||
var stack: ItemStack? = stack
|
var stack: ItemStack? = stack
|
||||||
set(value) {
|
set(value) {
|
||||||
if (field == value) return
|
if (field == value) return
|
||||||
@ -48,6 +52,7 @@ open class ItemFeature(
|
|||||||
|
|
||||||
override fun update(millis: Long, delta: Float) {
|
override fun update(millis: Long, delta: Float) {
|
||||||
if (!_enabled) return unload()
|
if (!_enabled) return unload()
|
||||||
|
updateDistance()
|
||||||
if (this.mesh == null) {
|
if (this.mesh == null) {
|
||||||
val stack = this.stack ?: return unload()
|
val stack = this.stack ?: return unload()
|
||||||
createMesh(stack)
|
createMesh(stack)
|
||||||
@ -55,7 +60,15 @@ open class ItemFeature(
|
|||||||
updateMatrix()
|
updateMatrix()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateDistance() {
|
||||||
|
val distance = ItemRenderDistance.of(renderer.distance)
|
||||||
|
if (distance == this.distance) return
|
||||||
|
unload()
|
||||||
|
this.distance = distance
|
||||||
|
}
|
||||||
|
|
||||||
private fun createMesh(stack: ItemStack) {
|
private fun createMesh(stack: ItemStack) {
|
||||||
|
val distance = this.distance ?: return
|
||||||
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)
|
val display = model.getDisplay(display)
|
||||||
this.displayMatrix = display?.matrix ?: Mat4.EMPTY_INSTANCE
|
this.displayMatrix = display?.matrix ?: Mat4.EMPTY_INSTANCE
|
||||||
@ -63,15 +76,17 @@ open class ItemFeature(
|
|||||||
|
|
||||||
val tint = renderer.renderer.context.tints.getItemTint(stack)
|
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
|
model.render(mesh, stack, tint) // 0 without offset
|
||||||
|
|
||||||
if (count > 1) {
|
if (count > 1) {
|
||||||
val random = Random(1234567890123456789L)
|
val random = Random(1234567890123456789L)
|
||||||
for (i in 0 until count - 1) {
|
for (i in 0 until count - 1) {
|
||||||
mesh.offset.x = random.nextFloat(-0.2f, 0.2f)
|
mesh.offset.x = random.nextFloat(-spread, spread)
|
||||||
mesh.offset.y = random.nextFloat(-0.2f, 0.2f)
|
mesh.offset.y = random.nextFloat(-spread, spread)
|
||||||
mesh.offset.z = random.nextFloat(-0.2f, 0.2f)
|
mesh.offset.z = random.nextFloat(-spread, spread)
|
||||||
|
|
||||||
model.render(mesh, stack, tint)
|
model.render(mesh, stack, tint)
|
||||||
}
|
}
|
||||||
@ -81,26 +96,12 @@ open class ItemFeature(
|
|||||||
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)
|
.translateXAssign(-0.5f)
|
||||||
.translateZAssign(-0.5f)
|
.translateZAssign(-0.5f)
|
||||||
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
|
|
||||||
this.matrix = renderer.matrix * displayMatrix * matrix
|
this.matrix = renderer.matrix * displayMatrix * matrix
|
||||||
}
|
}
|
||||||
@ -108,6 +109,12 @@ open class ItemFeature(
|
|||||||
override fun draw(mesh: BlockMesh) {
|
override fun draw(mesh: BlockMesh) {
|
||||||
renderer.renderer.context.system.reset(faceCulling = false)
|
renderer.renderer.context.system.reset(faceCulling = false)
|
||||||
val shader = renderer.renderer.features.block.shader
|
val shader = renderer.renderer.features.block.shader
|
||||||
|
draw(mesh, shader)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected open fun draw(mesh: BlockMesh, shader: BlockShader) {
|
||||||
|
shader.use()
|
||||||
shader.matrix = matrix
|
shader.matrix = matrix
|
||||||
shader.tint = renderer.light.value
|
shader.tint = renderer.light.value
|
||||||
super.draw(mesh)
|
super.draw(mesh)
|
||||||
@ -115,5 +122,54 @@ open class ItemFeature(
|
|||||||
|
|
||||||
override fun unload() {
|
override fun unload() {
|
||||||
this.displayMatrix = Mat4.EMPTY_INSTANCE
|
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
|
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.kutil.observer.DataObserver.Companion.observe
|
||||||
import de.bixilon.minosoft.data.entities.entities.item.ItemEntity
|
import de.bixilon.minosoft.data.entities.entities.item.ItemEntity
|
||||||
import de.bixilon.minosoft.data.registries.identified.Identified
|
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.feature.item.ItemFeature
|
||||||
import de.bixilon.minosoft.gui.rendering.entities.renderer.EntityRenderer
|
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.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) {
|
class ItemEntityRenderer(renderer: EntitiesRenderer, entity: ItemEntity) : EntityRenderer<ItemEntity>(renderer, entity) {
|
||||||
val item = ItemFeature(this, null, DisplayPositions.GROUND).register()
|
val item = ItemFeature(this, null, DisplayPositions.GROUND).register()
|
||||||
|
private var floating = 0.0f
|
||||||
|
private var rotation = 0.0f
|
||||||
|
|
||||||
init {
|
init {
|
||||||
entity::stack.observe(this, true) { item.stack = it }
|
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 {
|
companion object : RegisteredEntityModelFactory<ItemEntity>, Identified {
|
||||||
|
const val CIRCLE = PIf * 2.0f
|
||||||
override val identifier get() = ItemEntity.identifier
|
override val identifier get() = ItemEntity.identifier
|
||||||
|
|
||||||
override fun create(renderer: EntitiesRenderer, entity: ItemEntity) = ItemEntityRenderer(renderer, entity)
|
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(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) {
|
override fun addQuad(positions: FaceVertexData, uvData: FaceVertexData, textureId: Float, lightTint: Float) {
|
||||||
|
|
||||||
val tint = (lightTint.toBits() shl 8) or 0xFF
|
val tint = (lightTint.toBits() shl 8) or 0xFF
|
||||||
|
|
||||||
|
|
||||||
gui.context.system.quadOrder.iterateReverse { p, uv ->
|
gui.context.system.quadOrder.iterateReverse { p, uv ->
|
||||||
val vertexOffset = p * Vec3.length
|
val vertexOffset = p * Vec3.length
|
||||||
val uvOffset = uv * Vec2.length
|
val uvOffset = uv * Vec2.length
|
||||||
@ -62,9 +60,6 @@ class BlockGUIConsumer(
|
|||||||
|
|
||||||
consumer.addVertex(x, y, textureId, uvData[uvOffset], uvData[uvOffset + 1], tint, options)
|
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 {
|
companion object {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user