abstract chest animation, shulker model, more

This commit is contained in:
Moritz Zwerger 2023-10-22 01:51:42 +02:00
parent e6180b5623
commit a98e8a38b7
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
23 changed files with 341 additions and 104 deletions

View File

@ -11,7 +11,7 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage.chest
package de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.kutil.primitive.FloatUtil.matches
@ -20,6 +20,7 @@ import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel
import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalTransform
import de.bixilon.minosoft.gui.rendering.skeletal.baked.animation.keyframe.instance.KeyframeInstance.Companion.NOT_OVER
import de.bixilon.minosoft.gui.rendering.skeletal.baked.animation.keyframe.instance.KeyframeInstance.Companion.OVER
import de.bixilon.minosoft.gui.rendering.skeletal.instance.SkeletalInstance
import de.bixilon.minosoft.gui.rendering.skeletal.mesh.SkeletalMesh
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
import de.bixilon.minosoft.test.IT
@ -28,18 +29,15 @@ import org.testng.Assert.assertTrue
import org.testng.annotations.Test
@Test(groups = ["skeletal", "block_entity_rendering"])
class ChestAnimationTest {
private val progress = ChestAnimation::class.java.getDeclaredField("progress").apply { isAccessible = true }
class OpenCloseAnimationTest {
private fun ChestAnimation.getProgress(): Float = progress.getFloat(this)
private fun create(): ChestAnimation {
private fun create(): Animation {
val mesh = IT.OBJENESIS.newInstance(SkeletalMesh::class.java)
val context = IT.OBJENESIS.newInstance(RenderContext::class.java)
val model = BakedSkeletalModel(mesh, BakedSkeletalTransform(0, Vec3.EMPTY, mapOf("lid" to BakedSkeletalTransform(1, Vec3.EMPTY, emptyMap()))), 1, emptyMap())
val model = BakedSkeletalModel(mesh, BakedSkeletalTransform(0, Vec3.EMPTY, emptyMap()), 1, emptyMap())
val instance = model.createInstance(context)
return ChestAnimation(instance)
return Animation(instance)
}
fun `create animation`() {
@ -84,5 +82,19 @@ class ChestAnimationTest {
assertEquals(animation.getProgress(), 0.0f)
}
// TODO: test transforming
private class Animation(
instance: SkeletalInstance,
) : OpenCloseAnimation(instance) {
override val transform = instance.transform
override val name get() = "dummy"
override val closingDuration get() = 0.3f
override val openingDuration get() = 0.4f
override fun transform() = Unit
fun getProgress() = this.progress
}
}

View File

@ -25,5 +25,5 @@ object DebugOptions {
const val LOG_RAW_CHAT = false
const val FORCE_CHEST_ANIMATION = true
const val FORCE_CHEST_ANIMATION = false
}

View File

@ -13,11 +13,8 @@
package de.bixilon.minosoft.data.direction
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.kutil.array.ArrayUtil
import de.bixilon.minosoft.data.Axes
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rad
object DirectionUtil {
@ -38,17 +35,4 @@ object DirectionUtil {
return Directions.INDEXED[1][ArrayUtil.modifyArrayIndex(index.y + count, Directions.SIZE_SIDES)]
}
fun getRotation(direction: Directions): Vec3 {
// north is the base direction
// TODO: verify
return when (direction) {
Directions.NORTH -> Vec3.EMPTY
Directions.SOUTH -> Vec3(0, 180, 0)
Directions.WEST -> Vec3(0, 90, 0)
Directions.EAST -> Vec3(0, 270, 0)
Directions.UP -> Vec3(0, 0, 90)
Directions.DOWN -> Vec3(0, 0, 270)
}.rad
}
}

View File

@ -45,7 +45,6 @@ enum class Directions(
val vectord = Vec3d(vector)
val axis: Axes = unsafeNull()
val rotation: Vec3 = unsafeNull()
val inverted: Directions = unsafeNull()
private fun invert(): Directions {
@ -157,12 +156,10 @@ enum class Directions(
}
init {
val rotation = Directions::rotation.javaField!!
val inverted = Directions::inverted.javaField!!
val axis = Directions::axis.javaField!!
for (direction in VALUES) {
inverted.forceSet(direction, direction.invert())
rotation.forceSet(direction, DirectionUtil.getRotation(direction))
axis.forceSet(direction, Axes[direction])
}
NAME_MAP.unsafeCast<MutableMap<String, Directions>>()["bottom"] = DOWN

View File

@ -19,7 +19,7 @@ import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
class BeaconBlockEntity(connection: PlayConnection) : BlockEntity(connection), BlockActionEntity {
override fun setBlockActionData(data1: Int, data2: Int) {
override fun setBlockActionData(type: Int, data: Int) {
// no data used, just recalculates the beam
}

View File

@ -22,8 +22,8 @@ class BellBlockEntity(connection: PlayConnection) : BlockEntity(connection), Blo
var shakingDirection: Directions = Directions.NORTH
private set
override fun setBlockActionData(data1: Int, data2: Int) {
shakingDirection = Directions[data2.toInt()]
override fun setBlockActionData(type: Int, data: Int) {
shakingDirection = Directions[data.toInt()]
}
companion object : BlockEntityFactory<BellBlockEntity> {

View File

@ -14,5 +14,5 @@
package de.bixilon.minosoft.data.entities.block
interface BlockActionEntity {
fun setBlockActionData(data1: Int, data2: Int)
fun setBlockActionData(type: Int, data: Int)
}

View File

@ -48,7 +48,7 @@ class MobSpawnerBlockEntity(connection: PlayConnection) : BlockEntity(connection
flameParticleType?.let { connection.world += FlameParticle(connection, Vec3d(particlePosition), Vec3d.EMPTY, it.default()) }
}
override fun setBlockActionData(data1: Int, data2: Int) {
override fun setBlockActionData(type: Int, data: Int) {
// ToDo
}

View File

@ -41,8 +41,8 @@ class NoteBlockBlockEntity(connection: PlayConnection) : BlockEntity(connection)
return properties[BlockProperties.NOTE]?.toInt() ?: 0
}
override fun setBlockActionData(data1: Int, data2: Int) {
instrument = when (data1.toInt()) {
override fun setBlockActionData(type: Int, data: Int) {
instrument = when (type.toInt()) {
0 -> Instruments.HARP
1 -> Instruments.BASS
2 -> Instruments.SNARE
@ -51,7 +51,7 @@ class NoteBlockBlockEntity(connection: PlayConnection) : BlockEntity(connection)
else -> null
}
pitch = data2.toInt()
pitch = data.toInt()
showParticleNextTick = true
// ToDo: Play sound?

View File

@ -13,16 +13,23 @@
package de.bixilon.minosoft.data.entities.block.container.storage
import de.bixilon.kotlinglm.vec3.Vec3i
import de.bixilon.minosoft.data.entities.block.BlockEntityFactory
import de.bixilon.minosoft.data.registries.blocks.state.BlockState
import de.bixilon.minosoft.data.registries.identified.AliasedIdentified
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.chunk.entities.BlockEntityRenderer
import de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage.shulker.ShulkerBoxRenderer
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.util.KUtil
import de.bixilon.minosoft.util.KUtil.toResourceLocationList
class ShulkerBoxBlockEntity(connection: PlayConnection) : StorageBlockEntity(connection) {
override fun createRenderer(context: RenderContext, blockState: BlockState, blockPosition: Vec3i, light: Int): BlockEntityRenderer<*>? {
return ShulkerBoxRenderer(this, context, blockState, blockPosition, context.models.skeletal[ShulkerBoxRenderer.MODEL] ?: return null, light)
}
companion object : BlockEntityFactory<ShulkerBoxBlockEntity>, AliasedIdentified {
override val identifier: ResourceLocation = minecraft("shulker_box")

View File

@ -34,8 +34,13 @@ abstract class StorageBlockEntity(connection: PlayConnection) : ContainerBlockEn
val closed: Boolean get() = viewing <= 0
override fun setBlockActionData(data1: Int, data2: Int) {
val viewing = data2 and 0xFF // unsigned
override fun setBlockActionData(type: Int, data: Int) {
when (type) {
1 -> setViewing(data and 0xFF)
}
}
protected fun setViewing(viewing: Int) {
if (this.viewing == viewing) return
val previous = this.viewing
this.viewing = viewing

View File

@ -22,7 +22,7 @@ import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
class EndGatewayBlockEntity(connection: PlayConnection) : BlockEntity(connection), BlockActionEntity {
override fun setBlockActionData(data1: Int, data2: Int) {
override fun setBlockActionData(type: Int, data: Int) {
// just emits the beacon like beam
}

View File

@ -29,9 +29,9 @@ open class PistonBlockEntity(connection: PlayConnection) : BlockEntity(connectio
var direction: Directions = Directions.NORTH
private set
override fun setBlockActionData(data1: Int, data2: Int) {
state = PistonStates[data1.toInt()]
direction = Directions[data2.toInt()]
override fun setBlockActionData(type: Int, data: Int) {
state = PistonStates[type.toInt()]
direction = Directions[data.toInt()]
}
companion object : BlockEntityFactory<PistonBlockEntity> {

View File

@ -17,6 +17,7 @@ import de.bixilon.kutil.latch.AbstractLatch
import de.bixilon.kutil.latch.AbstractLatch.Companion.child
import de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage.chest.DoubleChestRenderer
import de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage.chest.SingleChestRenderer
import de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage.shulker.ShulkerBoxRenderer
import de.bixilon.minosoft.gui.rendering.models.loader.ModelLoader
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels
@ -24,12 +25,11 @@ import de.bixilon.minosoft.util.logging.LogMessageType
object DefaultEntityModels {
val MODELS = listOf(
SingleChestRenderer.NormalChest,
SingleChestRenderer.TrappedChest,
SingleChestRenderer.EnderChest,
SingleChestRenderer.NormalChest, SingleChestRenderer.TrappedChest, SingleChestRenderer.EnderChest,
DoubleChestRenderer.NormalChest,
DoubleChestRenderer.TrappedChest,
DoubleChestRenderer.NormalChest, DoubleChestRenderer.TrappedChest,
ShulkerBoxRenderer,
)

View File

@ -0,0 +1,67 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage
import de.bixilon.minosoft.gui.rendering.skeletal.baked.animation.AbstractAnimation
import de.bixilon.minosoft.gui.rendering.skeletal.baked.animation.keyframe.instance.KeyframeInstance.Companion.NOT_OVER
import de.bixilon.minosoft.gui.rendering.skeletal.baked.animation.keyframe.instance.KeyframeInstance.Companion.OVER
import de.bixilon.minosoft.gui.rendering.skeletal.instance.SkeletalInstance
import de.bixilon.minosoft.gui.rendering.skeletal.instance.TransformInstance
abstract class OpenCloseAnimation(
protected val instance: SkeletalInstance,
) : AbstractAnimation {
protected abstract val transform: TransformInstance
protected var progress = 0.0f
protected var opening = true
protected abstract val closingDuration: Float
protected abstract val openingDuration: Float
override fun draw(delta: Float): Boolean {
return if (opening) drawOpening(delta) else drawClosing(delta)
}
private fun drawOpening(delta: Float): Boolean {
this.progress += delta / openingDuration
if (this.progress > 1.0f) {
this.progress = 1.0f
}
transform()
return NOT_OVER
}
private fun drawClosing(delta: Float): Boolean {
this.progress -= delta / closingDuration
if (progress <= 0.0f) {
this.progress = 0.0f
return OVER
}
transform()
return NOT_OVER
}
protected abstract fun transform()
fun open() {
if (progress <= 0.0f) {
instance.animation.play(this)
}
opening = true
}
fun close() {
opening = false
}
}

View File

@ -14,47 +14,24 @@
package de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage.chest
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.gui.rendering.skeletal.baked.animation.AbstractAnimation
import de.bixilon.minosoft.gui.rendering.skeletal.baked.animation.keyframe.instance.KeyframeInstance.Companion.NOT_OVER
import de.bixilon.minosoft.gui.rendering.skeletal.baked.animation.keyframe.instance.KeyframeInstance.Companion.OVER
import de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage.OpenCloseAnimation
import de.bixilon.minosoft.gui.rendering.skeletal.instance.SkeletalInstance
import de.bixilon.minosoft.gui.rendering.util.mat.mat4.Mat4Util.rotateRadAssign
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.interpolateSine
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rad
class ChestAnimation(
private val instance: SkeletalInstance,
) : AbstractAnimation {
private val transform = instance.transform.children[TRANSFORM]!!
private var progress = 0.0f
private var opening = true
instance: SkeletalInstance,
) : OpenCloseAnimation(instance) {
override val transform = instance.transform.children[TRANSFORM]!!
override val name get() = NAME
override fun draw(delta: Float): Boolean {
return if (opening) drawOpening(delta) else drawClosing(delta)
}
override val closingDuration get() = 0.3f
override val openingDuration get() = 0.4f
private fun drawOpening(delta: Float): Boolean {
this.progress += delta / OPENING_TIME
if (this.progress > 1.0f) {
this.progress = 1.0f
}
transform()
return NOT_OVER
}
private fun drawClosing(delta: Float): Boolean {
this.progress -= delta / CLOSING_TIME
if (progress <= 0.0f) {
this.progress = 0.0f
return OVER
}
transform()
return NOT_OVER
}
private fun transform() {
override fun transform() {
val rotation = interpolateSine(this.progress, BASE, OPEN)
transform.value
.translateAssign(transform.pivot)
@ -62,25 +39,11 @@ class ChestAnimation(
.translateAssign(-transform.pivot)
}
fun open() {
if (progress <= 0.0f) {
instance.animation.play(this)
}
opening = true
}
fun close() {
opening = false
}
companion object {
const val TRANSFORM = "lid"
const val NAME = "chest"
const val OPENING_TIME = 0.4f
const val CLOSING_TIME = 0.3f
private val BASE = Vec3(0.0f, 0.0f, 0.0f).rad
private val OPEN = Vec3(90.0f, 0.0f, 0.0f).rad
}

View File

@ -13,12 +13,15 @@
package de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage.chest
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.data.direction.Directions
import de.bixilon.minosoft.data.entities.block.container.storage.ChestBlockEntity
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties.getFacing
import de.bixilon.minosoft.data.registries.blocks.state.BlockState
import de.bixilon.minosoft.data.world.positions.BlockPosition
import de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage.StorageBlockEntityRenderer
import de.bixilon.minosoft.gui.rendering.skeletal.instance.SkeletalInstance
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rad
abstract class ChestRenderer(
state: BlockState,
@ -33,7 +36,8 @@ abstract class ChestRenderer(
}
override fun update(position: BlockPosition, state: BlockState, light: Int) {
skeletal?.update(position, state.getFacing())
val rotation = ROTATION[state.getFacing().ordinal - Directions.SIDE_OFFSET]
skeletal?.update(position, rotation)
skeletal?.light = light
}
@ -44,4 +48,13 @@ abstract class ChestRenderer(
override fun close() {
animation?.close()
}
private companion object {
val ROTATION = arrayOf(
Vec3(0, 0, 0).rad,
Vec3(0, 180, 0).rad,
Vec3(0, 90, 0).rad,
Vec3(0, 270, 0).rad,
)
}
}

View File

@ -0,0 +1,54 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage.shulker
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage.OpenCloseAnimation
import de.bixilon.minosoft.gui.rendering.skeletal.instance.SkeletalInstance
import de.bixilon.minosoft.gui.rendering.util.mat.mat4.Mat4Util.rotateRadAssign
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.interpolateLinear
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rad
class ShulkerAnimation(
instance: SkeletalInstance,
) : OpenCloseAnimation(instance) {
override val transform = instance.transform.children[TRANSFORM]!!
override val name get() = NAME
override val closingDuration get() = 0.5f
override val openingDuration get() = 0.5f
override fun transform() {
val rotation = interpolateLinear(this.progress, ROTATION_CLOSED, ROTATION_OPENED)
val translation = interpolateLinear(this.progress, TRANSLATION_CLOSED, TRANSLATION_OPENED)
transform.value
.translateAssign(translation)
.translateAssign(transform.pivot)
.rotateRadAssign(rotation)
.translateAssign(-transform.pivot)
}
companion object {
const val TRANSFORM = "lid"
const val NAME = "shulker"
private val ROTATION_CLOSED = Vec3(0.0f, 0.0f, 0.0f).rad
private val ROTATION_OPENED = Vec3(0.0f, 270.0f, 0.0f).rad
private val TRANSLATION_CLOSED = Vec3(0.0f, 0.0f, 0.0f)
private val TRANSLATION_OPENED = Vec3(0.0f, 0.5f, 0.0f)
}
}

View File

@ -0,0 +1,80 @@
/*
* Minosoft
* Copyright (C) 2020-2023 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage.shulker
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.kotlinglm.vec3.Vec3i
import de.bixilon.minosoft.data.entities.block.container.storage.ShulkerBoxBlockEntity
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties.getFacing
import de.bixilon.minosoft.data.registries.blocks.state.BlockState
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.data.world.positions.BlockPosition
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.chunk.entities.EntityRendererRegister
import de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage.StorageBlockEntityRenderer
import de.bixilon.minosoft.gui.rendering.models.loader.ModelLoader
import de.bixilon.minosoft.gui.rendering.models.loader.SkeletalLoader.Companion.sModel
import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rad
class ShulkerBoxRenderer(
val entity: ShulkerBoxBlockEntity,
context: RenderContext,
state: BlockState,
position: Vec3i,
model: BakedSkeletalModel,
light: Int,
) : StorageBlockEntityRenderer<ShulkerBoxBlockEntity>(state, model.createInstance(context)) {
val animation = skeletal?.let { ShulkerAnimation(it) }
init {
update(position, state, light)
}
override fun update(position: BlockPosition, state: BlockState, light: Int) {
val facing = state.getFacing()
val rotation = ROTATIONS[facing.ordinal]
skeletal?.update(position, rotation)
skeletal?.light = light
}
override fun open() {
animation?.open()
}
override fun close() {
animation?.close()
}
companion object : EntityRendererRegister {
val MODEL = minecraft("block/entities/shulker_box").sModel()
private val named = minecraft("shulker")
private val texture = minecraft("entity/shulker/shulker").texture()
private val ROTATIONS = arrayOf(
Vec3(180, 0, 0).rad,
Vec3(0, 0, 0).rad,
Vec3(270, 180, 0).rad,
Vec3(90, 0, 0).rad,
Vec3(90, 0, 90).rad,
Vec3(90, 0, 270).rad,
)
override fun register(loader: ModelLoader) {
val texture = loader.context.textures.staticTextures.createTexture(texture)
loader.skeletal.register(MODEL, override = mapOf(this.named to texture))
}
}
}

View File

@ -17,11 +17,11 @@ import de.bixilon.kotlinglm.mat4x4.Mat4
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.kotlinglm.vec3.Vec3i
import de.bixilon.minosoft.data.direction.Directions
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.shader.Shader
import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel
import de.bixilon.minosoft.gui.rendering.util.mat.mat4.Mat4Util.rotateRadAssign
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY_INSTANCE
class SkeletalInstance(
val context: RenderContext,
@ -34,7 +34,7 @@ class SkeletalInstance(
fun draw() {
context.system.reset()
context.system.reset(faceCulling = false)
val shader = context.skeletal.shader
shader.use()
shader.light = light
@ -50,19 +50,25 @@ class SkeletalInstance(
model.mesh.draw()
}
fun update(position: Vec3, rotation: Vec3) {
fun update(position: Vec3, rotation: Vec3, pivot: Vec3 = Vec3.EMPTY_INSTANCE) {
this.position = Mat4()
.translateAssign(position)
.translateAssign(pivot)
.rotateRadAssign(rotation)
.translateAssign(-pivot)
}
fun update(position: Vec3d, rotation: Vec3) {
update(Vec3(position - context.camera.offset.offset), rotation)
}
fun update(position: Vec3i, direction: Directions) {
fun update(position: Vec3i, rotation: Vec3) {
val position = Vec3(position - context.camera.offset.offset)
position.x += 0.5f; position.z += 0.5f // models origin is the center of block origin
update(position, direction.rotation)
update(position, rotation, BLOCK_PIVOT)
}
private companion object {
val BLOCK_PIVOT = Vec3(0.0f, 0.5f, 0.0f)
}
}

View File

@ -23,7 +23,7 @@ data class SkeletalRotation(
) {
fun apply(offset: Vec3, from: Vec3, to: Vec3): SkeletalRotation {
val origin = (this.origin ?: ((to - from) / 2.0f)) + offset
val origin = (this.origin ?: ((to + from) / 2.0f)) + offset
return SkeletalRotation(value, origin, rescale)
}

View File

@ -30,8 +30,8 @@ class BlockActionS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
} else {
buffer.readBlockPosition()
}
val data1 = buffer.readByte().toInt()
val data2 = buffer.readByte().toInt()
val type = buffer.readByte().toInt()
val data = buffer.readByte().toInt()
val block: Block = if (buffer.versionId < FLATTENING_VERSION) buffer.readRegistryItem(buffer.connection.registries.blockState)!!.block else buffer.readRegistryItem(buffer.connection.registries.block)
override fun handle(connection: PlayConnection) {
@ -41,10 +41,10 @@ class BlockActionS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
Log.log(LogMessageType.NETWORK_IN, LogLevels.WARN) { "Block entity $blockEntity can not accept block entity actions!" }
return
}
blockEntity.setBlockActionData(data1, data2)
blockEntity.setBlockActionData(type, data)
}
override fun log(reducedLog: Boolean) {
Log.log(LogMessageType.NETWORK_IN, level = LogLevels.VERBOSE) { "Block action (position=$position, data1=$data1, data2=$data2, block=$block)" }
Log.log(LogMessageType.NETWORK_IN, level = LogLevels.VERBOSE) { "Block action (position=$position, type=$type, data=$data, block=$block)" }
}
}

View File

@ -0,0 +1,49 @@
{
"elements": {
"base": {
"from": [-8, 0, -8],
"to": [8, 8, 8],
"texture": "minecraft:shulker",
"uv": [0, 28],
"rotation": {
"value": [0, 0, 180]
},
"faces": {
"down": {},
"up": {},
"north": {},
"south": {},
"west": {},
"east": {}
}
},
"lid": {
"transform": "lid",
"from": [-8, 4, -8],
"to": [8, 16, 8],
"texture": "minecraft:shulker",
"rotation": {
"value": [0, 0, 180]
},
"uv": [0, 0],
"faces": {
"down": {},
"up": {},
"north": {},
"south": {},
"west": {},
"east": {}
}
}
},
"transforms": {
"lid": {
"pivot": [0, 8, 0]
}
},
"textures": {
"minecraft:shulker": {
"resolution": [64, 64]
}
}
}