fix build, remove player rendering, wip refactor skeletal animations

This commit is contained in:
Moritz Zwerger 2023-10-14 20:47:35 +02:00
parent c5ece6b11b
commit 03d80673d4
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
48 changed files with 199 additions and 871 deletions

View File

@ -16,11 +16,10 @@ package de.bixilon.minosoft.data.entities.block
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.util.KUtil
class BeaconBlockEntity(connection: PlayConnection) : BlockEntity(connection), BlockActionEntity { class BeaconBlockEntity(connection: PlayConnection) : BlockEntity(connection), BlockActionEntity {
override fun setBlockActionData(data1: Byte, data2: Byte) { override fun setBlockActionData(data1: Int, data2: Int) {
// no data used, just recalculates the beam // no data used, just recalculates the beam
} }

View File

@ -17,13 +17,12 @@ import de.bixilon.minosoft.data.direction.Directions
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.util.KUtil
class BellBlockEntity(connection: PlayConnection) : BlockEntity(connection), BlockActionEntity { class BellBlockEntity(connection: PlayConnection) : BlockEntity(connection), BlockActionEntity {
var shakingDirection: Directions = Directions.NORTH var shakingDirection: Directions = Directions.NORTH
private set private set
override fun setBlockActionData(data1: Byte, data2: Byte) { override fun setBlockActionData(data1: Int, data2: Int) {
shakingDirection = Directions[data2.toInt()] shakingDirection = Directions[data2.toInt()]
} }

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2021 Moritz Zwerger * 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 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.
* *
@ -14,5 +14,5 @@
package de.bixilon.minosoft.data.entities.block package de.bixilon.minosoft.data.entities.block
interface BlockActionEntity { interface BlockActionEntity {
fun setBlockActionData(data1: Byte, data2: Byte) fun setBlockActionData(data1: Int, data2: 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()) } flameParticleType?.let { connection.world += FlameParticle(connection, Vec3d(particlePosition), Vec3d.EMPTY, it.default()) }
} }
override fun setBlockActionData(data1: Byte, data2: Byte) { override fun setBlockActionData(data1: Int, data2: Int) {
// ToDo // ToDo
} }

View File

@ -41,7 +41,7 @@ class NoteBlockBlockEntity(connection: PlayConnection) : BlockEntity(connection)
return properties[BlockProperties.NOTE]?.toInt() ?: 0 return properties[BlockProperties.NOTE]?.toInt() ?: 0
} }
override fun setBlockActionData(data1: Byte, data2: Byte) { override fun setBlockActionData(data1: Int, data2: Int) {
instrument = when (data1.toInt()) { instrument = when (data1.toInt()) {
0 -> Instruments.HARP 0 -> Instruments.HARP
1 -> Instruments.BASS 1 -> Instruments.BASS

View File

@ -31,23 +31,23 @@ open class ChestBlockEntity(connection: PlayConnection) : StorageBlockEntity(con
override fun createRenderer(context: RenderContext, blockState: BlockState, blockPosition: Vec3i, light: Int): BlockEntityRenderer<*>? { override fun createRenderer(context: RenderContext, blockState: BlockState, blockPosition: Vec3i, light: Int): BlockEntityRenderer<*>? {
val type: ChestTypes = blockState[BlockProperties.CHEST_TYPE] val type: ChestTypes = blockState[BlockProperties.CHEST_TYPE]
if (type == ChestTypes.SINGLE) { if (type == ChestTypes.SINGLE) {
return SingleChestRenderer(this, context, blockState, blockPosition, context.models.entities.skeletal[getSingleModel()] ?: return null, light) return SingleChestRenderer(this, context, blockState, blockPosition, context.models.skeletal[getSingleModel()] ?: return null, light)
} }
if (type == ChestTypes.LEFT) { if (type == ChestTypes.LEFT) {
// only left chest will be rendered (the model is the double chest), reduces drawing overhead // only left chest will be rendered (the model is the double chest), reduces drawing overhead
return DoubleChestRenderer(this, context, blockState, blockPosition, context.models.entities.skeletal[getDoubleModel()] ?: return null, light) return DoubleChestRenderer(this, context, blockState, blockPosition, context.models.skeletal[getDoubleModel()] ?: return null, light)
} }
return null return null
} }
protected open fun getSingleModel(): ResourceLocation { protected open fun getSingleModel(): ResourceLocation {
return SingleChestRenderer.NormalChest.MODEL return SingleChestRenderer.NormalChest.NAME
} }
protected open fun getDoubleModel(): ResourceLocation { protected open fun getDoubleModel(): ResourceLocation {
return DoubleChestRenderer.NormalChest.MODEL return DoubleChestRenderer.NormalChest.NAME
} }
companion object : BlockEntityFactory<ChestBlockEntity> { companion object : BlockEntityFactory<ChestBlockEntity> {

View File

@ -27,7 +27,7 @@ import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
class EnderChestBlockEntity(connection: PlayConnection) : StorageBlockEntity(connection) { class EnderChestBlockEntity(connection: PlayConnection) : StorageBlockEntity(connection) {
override fun createRenderer(context: RenderContext, blockState: BlockState, blockPosition: Vec3i, light: Int): BlockEntityRenderer<out BlockEntity>? { override fun createRenderer(context: RenderContext, blockState: BlockState, blockPosition: Vec3i, light: Int): BlockEntityRenderer<out BlockEntity>? {
val model = context.models.entities.skeletal[SingleChestRenderer.EnderChest.MODEL] ?: return null val model = context.models.skeletal[SingleChestRenderer.EnderChest.NAME] ?: return null
return SingleChestRenderer(this, context, blockState, blockPosition, model, light) return SingleChestRenderer(this, context, blockState, blockPosition, model, light)
} }

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger * 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 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.
* *
@ -22,30 +22,39 @@ import de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage.Storage
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
abstract class StorageBlockEntity(connection: PlayConnection) : ContainerBlockEntity(connection), BlockActionEntity { abstract class StorageBlockEntity(connection: PlayConnection) : ContainerBlockEntity(connection), BlockActionEntity {
protected var blockEntityRenderer: StorageBlockEntityRenderer<*>? = null protected var storageRenderer: StorageBlockEntityRenderer<*>? = null
override var renderer: BlockEntityRenderer<out BlockEntity>? override var renderer: BlockEntityRenderer<out BlockEntity>?
get() = blockEntityRenderer get() = storageRenderer
set(value) { set(value) {
blockEntityRenderer = value?.unsafeCast() storageRenderer = value?.unsafeCast()
} }
var playersLookingIntoStorage: Int = 0 var viewing: Int = 0
private set private set
val closed: Boolean get() = playersLookingIntoStorage <= 0 val closed: Boolean get() = viewing <= 0
override fun setBlockActionData(data1: Byte, data2: Byte) { override fun setBlockActionData(data1: Int, data2: Int) {
val closed = closed val viewing = data2 and 0xFF // unsigned
playersLookingIntoStorage = data2.toInt() if (this.viewing == viewing) return
val previous = this.viewing
this.viewing = viewing
if (this.closed == closed) { when {
// state has not changed viewing == 0 -> onClose()
return previous == 0 -> onOpen()
} else -> onViewingChange(viewing)
if (playersLookingIntoStorage <= 0) {
blockEntityRenderer?.close()
} else {
blockEntityRenderer?.open()
} }
} }
protected open fun onViewingChange(viewing: Int) = Unit
protected fun onOpen() {
storageRenderer?.playOpen()
}
protected fun onClose() {
storageRenderer?.playClose()
}
} }

View File

@ -23,11 +23,11 @@ import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
class TrappedChestBlockEntity(connection: PlayConnection) : ChestBlockEntity(connection) { class TrappedChestBlockEntity(connection: PlayConnection) : ChestBlockEntity(connection) {
override fun getSingleModel(): ResourceLocation { override fun getSingleModel(): ResourceLocation {
return SingleChestRenderer.TrappedChest.MODEL return SingleChestRenderer.TrappedChest.NAME
} }
override fun getDoubleModel(): ResourceLocation { override fun getDoubleModel(): ResourceLocation {
return DoubleChestRenderer.TrappedChest.MODEL return DoubleChestRenderer.TrappedChest.NAME
} }
companion object : BlockEntityFactory<TrappedChestBlockEntity> { companion object : BlockEntityFactory<TrappedChestBlockEntity> {

View File

@ -19,11 +19,10 @@ import de.bixilon.minosoft.data.entities.block.BlockEntityFactory
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.util.KUtil
class EndGatewayBlockEntity(connection: PlayConnection) : BlockEntity(connection), BlockActionEntity { class EndGatewayBlockEntity(connection: PlayConnection) : BlockEntity(connection), BlockActionEntity {
override fun setBlockActionData(data1: Byte, data2: Byte) { override fun setBlockActionData(data1: Int, data2: Int) {
// just emits the beacon like beam // just emits the beacon like beam
} }

View File

@ -22,7 +22,6 @@ import de.bixilon.minosoft.data.entities.block.BlockEntityFactory
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
import de.bixilon.minosoft.util.KUtil
open class PistonBlockEntity(connection: PlayConnection) : BlockEntity(connection), BlockActionEntity { open class PistonBlockEntity(connection: PlayConnection) : BlockEntity(connection), BlockActionEntity {
var state: PistonStates = PistonStates.PULL var state: PistonStates = PistonStates.PULL
@ -30,7 +29,7 @@ open class PistonBlockEntity(connection: PlayConnection) : BlockEntity(connectio
var direction: Directions = Directions.NORTH var direction: Directions = Directions.NORTH
private set private set
override fun setBlockActionData(data1: Byte, data2: Byte) { override fun setBlockActionData(data1: Int, data2: Int) {
state = PistonStates[data1.toInt()] state = PistonStates[data1.toInt()]
direction = Directions[data2.toInt()] direction = Directions[data2.toInt()]
} }

View File

@ -15,7 +15,6 @@ package de.bixilon.minosoft.data.entities.entities.player
import de.bixilon.kotlinglm.vec2.Vec2 import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec3.Vec3d import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.kutil.bit.BitByte.isBitMask import de.bixilon.kutil.bit.BitByte.isBitMask
import de.bixilon.kutil.cast.CastUtil.nullCast
import de.bixilon.kutil.json.JsonObject import de.bixilon.kutil.json.JsonObject
import de.bixilon.kutil.observer.set.SetObserver.Companion.observedSet import de.bixilon.kutil.observer.set.SetObserver.Companion.observedSet
import de.bixilon.kutil.primitive.IntUtil.toInt import de.bixilon.kutil.primitive.IntUtil.toInt
@ -37,9 +36,6 @@ import de.bixilon.minosoft.data.registries.item.items.dye.DyeableItem
import de.bixilon.minosoft.data.registries.shapes.aabb.AABB import de.bixilon.minosoft.data.registries.shapes.aabb.AABB
import de.bixilon.minosoft.data.text.formatting.color.ChatColors import de.bixilon.minosoft.data.text.formatting.color.ChatColors
import de.bixilon.minosoft.data.text.formatting.color.RGBColor import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.entity.EntityRenderer
import de.bixilon.minosoft.gui.rendering.entity.models.EntityModel
import de.bixilon.minosoft.gui.rendering.entity.models.minecraft.player.PlayerModel
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.EMPTY import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.EMPTY
import de.bixilon.minosoft.physics.entities.living.player.PlayerPhysics import de.bixilon.minosoft.physics.entities.living.player.PlayerPhysics
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
@ -55,12 +51,6 @@ abstract class PlayerEntity(
val additional: PlayerAdditional, val additional: PlayerAdditional,
) : LivingEntity(connection, entityType, data, position, rotation) { ) : LivingEntity(connection, entityType, data, position, rotation) {
protected var _model: PlayerModel?
get() = super.model.nullCast()
set(value) {
super.model = value
}
override val dimensions: Vec2 override val dimensions: Vec2
get() = pose?.let { getDimensions(it) } ?: Vec2(type.width, type.height) get() = pose?.let { getDimensions(it) } ?: Vec2(type.width, type.height)
@ -145,10 +135,6 @@ abstract class PlayerEntity(
return ChatColors.RED return ChatColors.RED
} }
override fun createModel(renderer: EntityRenderer): EntityModel<PlayerEntity>? {
return PlayerModel(renderer, this).apply { this@PlayerEntity.model = this }
}
override fun createPhysics(): PlayerPhysics<*> { override fun createPhysics(): PlayerPhysics<*> {
return PlayerPhysics(this) return PlayerPhysics(this)
} }
@ -156,7 +142,6 @@ abstract class PlayerEntity(
fun swingHand(hand: Hands) { fun swingHand(hand: Hands) {
val arm = hand.getArm(mainArm) val arm = hand.getArm(mainArm)
_model?.swingArm(arm)
} }
override fun handleAnimation(animation: EntityAnimations) { override fun handleAnimation(animation: EntityAnimations) {

View File

@ -27,8 +27,6 @@ import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity
import de.bixilon.minosoft.data.entities.entities.player.additional.PlayerAdditional import de.bixilon.minosoft.data.entities.entities.player.additional.PlayerAdditional
import de.bixilon.minosoft.data.entities.entities.player.compass.CompassPosition import de.bixilon.minosoft.data.entities.entities.player.compass.CompassPosition
import de.bixilon.minosoft.data.registries.effects.attributes.integrated.IntegratedAttributeModifiers import de.bixilon.minosoft.data.registries.effects.attributes.integrated.IntegratedAttributeModifiers
import de.bixilon.minosoft.gui.rendering.entity.EntityRenderer
import de.bixilon.minosoft.gui.rendering.entity.models.minecraft.player.LocalPlayerModel
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.EMPTY import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3dUtil.EMPTY
import de.bixilon.minosoft.input.camera.MovementInputActions import de.bixilon.minosoft.input.camera.MovementInputActions
import de.bixilon.minosoft.input.camera.PlayerMovementInput import de.bixilon.minosoft.input.camera.PlayerMovementInput
@ -109,10 +107,6 @@ class LocalPlayerEntity(
override val usingHand: Hands? override val usingHand: Hands?
get() = using?.hand get() = using?.hand
override fun createModel(renderer: EntityRenderer): LocalPlayerModel {
return LocalPlayerModel(renderer, this).apply { this@LocalPlayerEntity.model = this }
}
override fun createPhysics() = LocalPlayerPhysics(this) override fun createPhysics() = LocalPlayerPhysics(this)
override fun physics(): LocalPlayerPhysics = super.physics().unsafeCast() override fun physics(): LocalPlayerPhysics = super.physics().unsafeCast()
} }

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger * 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 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.
* *
@ -13,8 +13,14 @@
package de.bixilon.minosoft.gui.rendering.chunk.entities package de.bixilon.minosoft.gui.rendering.chunk.entities
import de.bixilon.kutil.latch.AbstractLatch
import de.bixilon.kutil.latch.AbstractLatch.Companion.child
import de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage.DoubleChestRenderer import de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage.DoubleChestRenderer
import de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage.SingleChestRenderer import de.bixilon.minosoft.gui.rendering.chunk.entities.renderer.storage.SingleChestRenderer
import de.bixilon.minosoft.gui.rendering.models.loader.ModelLoader
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.LogMessageType
object DefaultEntityModels { object DefaultEntityModels {
val MODELS = listOf( val MODELS = listOf(
@ -25,4 +31,14 @@ object DefaultEntityModels {
DoubleChestRenderer.NormalChest, DoubleChestRenderer.NormalChest,
DoubleChestRenderer.TrappedChest, DoubleChestRenderer.TrappedChest,
) )
fun load(loader: ModelLoader, latch: AbstractLatch?) {
Log.log(LogMessageType.LOADING, LogLevels.VERBOSE) { "Loading entity models..." }
val innerLatch = latch.child(MODELS.size)
for (register in MODELS) {
register.register(loader); innerLatch.dec()
}
}
} }

View File

@ -1,74 +0,0 @@
/*
* 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
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
import de.bixilon.kutil.latch.AbstractLatch
import de.bixilon.kutil.latch.AbstractLatch.Companion.child
import de.bixilon.kutil.latch.SimpleLatch
import de.bixilon.minosoft.assets.util.InputStreamUtil.readJson
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.models.loader.ModelLoader
import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel
import de.bixilon.minosoft.gui.rendering.skeletal.model.SkeletalModel
import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.LogMessageType
class EntityModels(private val loader: ModelLoader) {
val context: RenderContext = loader.context
private val unbakedModels: MutableMap<ResourceLocation, SkeletalModel> = mutableMapOf()
val skeletal: MutableMap<ResourceLocation, BakedSkeletalModel> = mutableMapOf()
@Synchronized
fun loadUnbakedModel(path: ResourceLocation): SkeletalModel {
return unbakedModels.getOrPut(path) { context.connection.assetsManager[path].readJson() }
}
@Synchronized
fun loadModel(name: ResourceLocation, path: ResourceLocation, textureOverride: MutableMap<Int, ShaderTexture> = mutableMapOf()): BakedSkeletalModel {
return skeletal.getOrPut(name) { loadUnbakedModel(path).bake(context, textureOverride) }
}
fun cleanup() {
unbakedModels.clear()
}
fun bake() {
val latch = SimpleLatch(1)
for (model in skeletal.values) {
latch.inc()
DefaultThreadPool += { model.preload(context); latch.dec() }
}
latch.dec()
latch.await()
for (model in skeletal.values) {
model.load()
}
}
fun load(latch: AbstractLatch?) {
Log.log(LogMessageType.LOADING, LogLevels.VERBOSE) { "Loading entity models..." }
val innerLatch = latch.child(DefaultEntityModels.MODELS.size)
for (register in DefaultEntityModels.MODELS) {
DefaultThreadPool += { register.register(context, loader); innerLatch.dec() }
}
innerLatch.await()
}
}

View File

@ -13,10 +13,9 @@
package de.bixilon.minosoft.gui.rendering.chunk.entities package de.bixilon.minosoft.gui.rendering.chunk.entities
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.models.loader.ModelLoader import de.bixilon.minosoft.gui.rendering.models.loader.ModelLoader
interface EntityRendererRegister { interface EntityRendererRegister {
fun register(context: RenderContext, modelLoader: ModelLoader) = Unit fun register(loader: ModelLoader) = Unit
} }

View File

@ -18,16 +18,15 @@ import de.bixilon.kutil.time.DateUtil
import de.bixilon.minosoft.data.entities.block.container.storage.StorageBlockEntity import de.bixilon.minosoft.data.entities.block.container.storage.StorageBlockEntity
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties.getFacing 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.blocks.state.BlockState
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.gui.rendering.RenderContext import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.chunk.entities.EntityRendererRegister import de.bixilon.minosoft.gui.rendering.chunk.entities.EntityRendererRegister
import de.bixilon.minosoft.gui.rendering.models.loader.ModelLoader import de.bixilon.minosoft.gui.rendering.models.loader.ModelLoader
import de.bixilon.minosoft.gui.rendering.models.loader.ModelLoader.Companion.bbModel import de.bixilon.minosoft.gui.rendering.models.loader.ModelLoader.Companion.bbModel
import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel
import de.bixilon.minosoft.gui.rendering.skeletal.instance.SkeletalInstance
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture
import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3 import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3
import de.bixilon.minosoft.util.KUtil.toResourceLocation
class DoubleChestRenderer( class DoubleChestRenderer(
val entity: StorageBlockEntity, val entity: StorageBlockEntity,
@ -38,40 +37,41 @@ class DoubleChestRenderer(
light: Int, light: Int,
) : StorageBlockEntityRenderer<StorageBlockEntity>( ) : StorageBlockEntityRenderer<StorageBlockEntity>(
blockState, blockState,
SkeletalInstance(context, model, (blockPosition - context.camera.offset.offset).toVec3, (blockState.getFacing()).rotatedMatrix), model.createInstance(context, (blockPosition - context.camera.offset.offset).toVec3, (blockState.getFacing()).rotatedMatrix),
light, light,
) { ) {
companion object { companion object {
val DOUBLE_MODEL = "minecraft:block/entities/double_chest".toResourceLocation().bbModel() val DOUBLE_MODEL = minecraft("block/entities/double_chest").bbModel()
private val named = arrayOf(minecraft("left"), minecraft("right"))
fun register(context: RenderContext, modelLoader: ModelLoader, textureName1: ResourceLocation, textureName2: ResourceLocation, model: ResourceLocation) { private fun register(loader: ModelLoader, name: ResourceLocation, textures: Array<ResourceLocation>) {
val texture1 = context.textures.staticTextures.createTexture(textureName1) if (textures.size != 2) throw IllegalStateException("Textures must be left and right!")
val texture2 = context.textures.staticTextures.createTexture(textureName2) val static = loader.context.textures.staticTextures
modelLoader.entities.loadModel(model, DOUBLE_MODEL, mutableMapOf(0 to texture1, 1 to texture2)) val override = mapOf(
named[0] to static.createTexture(textures[0]),
named[1] to static.createTexture(textures[1]),
)
loader.skeletal.register(name, DOUBLE_MODEL, override)
} }
} }
object NormalChest : EntityRendererRegister { object NormalChest : EntityRendererRegister {
val MODEL = "minecraft:models/block/entities/double_chest".toResourceLocation() val NAME = minecraft("block/entities/double_chest")
val TEXTURE1 = "minecraft:entity/chest/normal_left".toResourceLocation().texture() private val textures = arrayOf(minecraft("entity/chest/normal_left").texture(), minecraft("entity/chest/normal_right").texture())
val TEXTURE2 = "minecraft:entity/chest/normal_right".toResourceLocation().texture() private val christmas = arrayOf(minecraft("entity/chest/christmas_left").texture(), minecraft("entity/chest/christmas_right").texture())
val TEXTURE_CHRISTMAS1 = "minecraft:entity/chest/christmas_left".toResourceLocation().texture()
val TEXTURE_CHRISTMAS2 = "minecraft:entity/chest/christmas_right".toResourceLocation().texture()
override fun register(context: RenderContext, modelLoader: ModelLoader) { override fun register(loader: ModelLoader) {
val christmas = DateUtil.christmas register(loader, NAME, if (DateUtil.christmas) christmas else textures)
register(context, modelLoader, if (christmas) TEXTURE_CHRISTMAS1 else TEXTURE1, if (christmas) TEXTURE_CHRISTMAS2 else TEXTURE2, MODEL)
} }
} }
object TrappedChest : EntityRendererRegister { object TrappedChest : EntityRendererRegister {
val MODEL = "minecraft:models/block/entities/double_trapped_chest".toResourceLocation() val NAME = minecraft("block/entities/double_trapped_chest")
val TEXTURE1 = "minecraft:entity/chest/trapped_left".toResourceLocation().texture() private val textures = arrayOf(minecraft("entity/chest/trapped_left").texture(), minecraft("entity/chest/trapped_right").texture())
val TEXTURE2 = "minecraft:entity/chest/trapped_right".toResourceLocation().texture()
override fun register(context: RenderContext, modelLoader: ModelLoader) { override fun register(loader: ModelLoader) {
register(context, modelLoader, TEXTURE1, TEXTURE2, MODEL) register(loader, NAME, textures)
} }
} }
} }

View File

@ -18,16 +18,15 @@ import de.bixilon.kutil.time.DateUtil
import de.bixilon.minosoft.data.entities.block.container.storage.StorageBlockEntity import de.bixilon.minosoft.data.entities.block.container.storage.StorageBlockEntity
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties.getFacing 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.blocks.state.BlockState
import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft
import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.gui.rendering.RenderContext import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.chunk.entities.EntityRendererRegister import de.bixilon.minosoft.gui.rendering.chunk.entities.EntityRendererRegister
import de.bixilon.minosoft.gui.rendering.models.loader.ModelLoader import de.bixilon.minosoft.gui.rendering.models.loader.ModelLoader
import de.bixilon.minosoft.gui.rendering.models.loader.ModelLoader.Companion.bbModel import de.bixilon.minosoft.gui.rendering.models.loader.ModelLoader.Companion.bbModel
import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel
import de.bixilon.minosoft.gui.rendering.skeletal.instance.SkeletalInstance
import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture import de.bixilon.minosoft.gui.rendering.textures.TextureUtil.texture
import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3 import de.bixilon.minosoft.gui.rendering.util.VecUtil.toVec3
import de.bixilon.minosoft.util.KUtil.toResourceLocation
class SingleChestRenderer( class SingleChestRenderer(
val entity: StorageBlockEntity, val entity: StorageBlockEntity,
@ -38,44 +37,45 @@ class SingleChestRenderer(
light: Int, light: Int,
) : StorageBlockEntityRenderer<StorageBlockEntity>( ) : StorageBlockEntityRenderer<StorageBlockEntity>(
blockState, blockState,
SkeletalInstance(context, model, (blockPosition - context.camera.offset.offset).toVec3, blockState.getFacing().rotatedMatrix), model.createInstance(context, (blockPosition - context.camera.offset.offset).toVec3, blockState.getFacing().rotatedMatrix),
light, light,
) { ) {
companion object { companion object {
val SINGLE_MODEL = "minecraft:block/entities/single_chest".toResourceLocation().bbModel() val SINGLE_MODEL = minecraft("block/entities/single_chest").bbModel()
private val named = minecraft("chest")
fun register(context: RenderContext, modelLoader: ModelLoader, textureName: ResourceLocation, model: ResourceLocation) { fun register(loader: ModelLoader, name: ResourceLocation, texture: ResourceLocation) {
val texture = context.textures.staticTextures.createTexture(textureName) val texture = loader.context.textures.staticTextures.createTexture(texture)
modelLoader.entities.loadModel(model, SINGLE_MODEL, mutableMapOf(0 to texture)) loader.skeletal.register(name, SINGLE_MODEL, mapOf(named to texture))
} }
} }
object NormalChest : EntityRendererRegister { object NormalChest : EntityRendererRegister {
val MODEL = "minecraft:models/block/entities/single_chest".toResourceLocation() val NAME = minecraft("block/entities/single_chest")
val TEXTURE = "minecraft:entity/chest/normal".toResourceLocation().texture() val TEXTURE = minecraft("entity/chest/normal").texture()
val TEXTURE_CHRISTMAS = "minecraft:entity/chest/christmas".toResourceLocation().texture() val TEXTURE_CHRISTMAS = minecraft("entity/chest/christmas").texture()
override fun register(context: RenderContext, modelLoader: ModelLoader) { override fun register(loader: ModelLoader) {
register(context, modelLoader, if (DateUtil.christmas) TEXTURE_CHRISTMAS else TEXTURE, MODEL) register(loader, NAME, if (DateUtil.christmas) TEXTURE_CHRISTMAS else TEXTURE)
} }
} }
object TrappedChest : EntityRendererRegister { object TrappedChest : EntityRendererRegister {
val MODEL = "minecraft:models/block/entities/trapped_chest".toResourceLocation() val NAME = minecraft("block/entities/trapped_chest")
val TEXTURE = "minecraft:entity/chest/trapped".toResourceLocation().texture() val TEXTURE = minecraft("entity/chest/trapped").texture()
override fun register(context: RenderContext, modelLoader: ModelLoader) { override fun register(loader: ModelLoader) {
register(context, modelLoader, TEXTURE, MODEL) register(loader, NAME, TEXTURE)
} }
} }
object EnderChest : EntityRendererRegister { object EnderChest : EntityRendererRegister {
val MODEL = "minecraft:models/block/entities/ender_chest".toResourceLocation() val NAME = minecraft("block/entities/ender_chest")
val TEXTURE = "minecraft:entity/chest/ender".toResourceLocation().texture() val TEXTURE = minecraft("entity/chest/ender").texture()
override fun register(context: RenderContext, modelLoader: ModelLoader) { override fun register(loader: ModelLoader) {
register(context, modelLoader, TEXTURE, MODEL) register(loader, NAME, TEXTURE)
} }
} }
} }

View File

@ -26,19 +26,16 @@ abstract class StorageBlockEntityRenderer<E : StorageBlockEntity>(
) : BlockEntityRenderer<E> { ) : BlockEntityRenderer<E> {
override fun draw(context: RenderContext) { override fun draw(context: RenderContext) {
skeletal?.light = light skeletal?.draw(light)
skeletal?.draw()
} }
fun open() { @Deprecated("refactor")
val skeletal = this.skeletal ?: return fun playOpen() {
skeletal.clearAnimation() TODO()
skeletal.playAnimation("animation.chest.opening")
} }
fun close() { @Deprecated("refactor")
val skeletal = this.skeletal ?: return fun playClose() {
skeletal.clearAnimation() TODO()
skeletal.playAnimation("animation.chest.closing")
} }
} }

View File

@ -30,7 +30,6 @@ import de.bixilon.minosoft.data.entities.entities.player.local.LocalPlayerEntity
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
import de.bixilon.minosoft.gui.rendering.RenderContext import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.entity.models.EntityModel import de.bixilon.minosoft.gui.rendering.entity.models.EntityModel
import de.bixilon.minosoft.gui.rendering.entity.models.minecraft.player.LocalPlayerModel
import de.bixilon.minosoft.gui.rendering.events.VisibilityGraphChangeEvent import de.bixilon.minosoft.gui.rendering.events.VisibilityGraphChangeEvent
import de.bixilon.minosoft.gui.rendering.renderer.renderer.RendererBuilder import de.bixilon.minosoft.gui.rendering.renderer.renderer.RendererBuilder
import de.bixilon.minosoft.gui.rendering.renderer.renderer.world.LayerSettings import de.bixilon.minosoft.gui.rendering.renderer.renderer.world.LayerSettings
@ -54,7 +53,6 @@ class EntityRenderer(
val profile = connection.profiles.entity val profile = connection.profiles.entity
val visibilityGraph = context.camera.visibilityGraph val visibilityGraph = context.camera.visibilityGraph
private val models: LockMap<Entity, EntityModel<*>> = lockMapOf() private val models: LockMap<Entity, EntityModel<*>> = lockMapOf()
private lateinit var localModel: LocalPlayerModel
private var toUnload: MutableList<EntityModel<*>> = synchronizedListOf() private var toUnload: MutableList<EntityModel<*>> = synchronizedListOf()
var hitboxes = profile.hitbox.enabled var hitboxes = profile.hitbox.enabled
@ -99,9 +97,9 @@ class EntityRenderer(
} }
override fun postAsyncInit(latch: AbstractLatch) { override fun postAsyncInit(latch: AbstractLatch) {
localModel = context.connection.player.createModel(this) // localModel = context.connection.player.createModel(this)
models[connection.player] = localModel // models[connection.player] = localModel
} }
private fun unloadUnused() { private fun unloadUnused() {

View File

@ -1,41 +0,0 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.entity.models
import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.gui.rendering.entity.EntityRenderer
import de.bixilon.minosoft.gui.rendering.skeletal.baked.SkeletalModelStates
import de.bixilon.minosoft.gui.rendering.skeletal.instance.SkeletalInstance
abstract class SkeletalEntityModel<E : Entity>(renderer: EntityRenderer, entity: E) : EntityModel<E>(renderer, entity) {
abstract val instance: SkeletalInstance?
open val hideSkeletalModel: Boolean get() = false
override fun prepare() {
super.prepare()
if (instance?.model?.state != SkeletalModelStates.LOADED) {
instance?.model?.preload(context) // ToDo: load async
instance?.model?.load()
}
}
override fun draw() {
super.draw()
if (!hideSkeletalModel) {
instance?.updatePosition(entity.renderInfo.position, entity.renderInfo.rotation)
instance?.draw()
}
}
}

View File

@ -1,52 +0,0 @@
/*
* 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.entity.models.minecraft.player
import de.bixilon.kotlinglm.func.deg
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.data.entities.entities.player.Arms
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.animations.AnimationLoops
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.animations.animator.keyframes.KeyframeChannels
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.outliner.SkeletalOutliner
import kotlin.math.PI
import kotlin.math.cos
class ArmAnimator(
model: PlayerModel,
) : ExtremitiesAnimator("arm_animator", model) {
override val loop: AnimationLoops = AnimationLoops.LOOP
override val length: Float = 2.0f
override fun get(channel: KeyframeChannels, outliner: SkeletalOutliner, time: Float): Vec3? {
if (channel != KeyframeChannels.ROTATION) {
return null
}
if (outliner.name == "LEFT_ARM") {
return calculateAngle(time)
}
if (outliner.name == "RIGHT_ARM") {
return calculateAngle(time - 1.0f)
}
return null
}
private fun calculateAngle(time: Float): Vec3 {
val angle = cos(time * PI) * 1.4 * velocityMultiplier
return Vec3(angle.deg, 0, 0)
}
fun swingArm(arm: Arms) {
}
}

View File

@ -1,49 +0,0 @@
/*
* 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.entity.models.minecraft.player
import de.bixilon.kutil.math.interpolation.FloatInterpolation.interpolateLinear
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.animations.CustomSkeletalAnimation
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
abstract class ExtremitiesAnimator(
name: String,
val model: PlayerModel,
) : CustomSkeletalAnimation(name) {
protected var previousVelocityMultiplier = 0.0f
protected var _velocityMultiplier = 0.0f
var velocityMultiplier = 0.0f
private set
override fun tick() {
previousVelocityMultiplier = _velocityMultiplier
_velocityMultiplier = _getVelocityMultiplier()
}
override fun draw(millis: Long) {
val lastTick = lastTick
super.draw(millis)
velocityMultiplier = interpolateLinear((millis - lastTick) / ProtocolDefinition.TICK_TIMEf * 3, previousVelocityMultiplier, _velocityMultiplier)
}
private fun _getVelocityMultiplier(): Float {
//TODO var velocity = model.entity.deltaMovement.xz.length().toFloat()
var velocity = 0.0f
if (velocity > 1.0f) {
velocity = 1.0f
}
return velocity
}
}

View File

@ -1,47 +0,0 @@
/*
* 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.entity.models.minecraft.player
import de.bixilon.kotlinglm.func.deg
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.animations.AnimationLoops
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.animations.animator.keyframes.KeyframeChannels
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.outliner.SkeletalOutliner
import kotlin.math.PI
import kotlin.math.cos
class LegAnimator(
model: PlayerModel,
) : ExtremitiesAnimator("leg_animator", model) {
override val loop: AnimationLoops = AnimationLoops.LOOP
override val length: Float = 2.0f
override fun get(channel: KeyframeChannels, outliner: SkeletalOutliner, time: Float): Vec3? {
if (channel != KeyframeChannels.ROTATION) {
return null
}
if (outliner.name == "LEFT_LEG") {
return calculateAngle(time)
}
if (outliner.name == "RIGHT_LEG") {
return calculateAngle(time - 1.0f)
}
return null
}
private fun calculateAngle(time: Float): Vec3 {
val angle = cos(time * PI) * velocityMultiplier
return Vec3(angle.deg, 0, 0)
}
}

View File

@ -1,38 +0,0 @@
/*
* 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.entity.models.minecraft.player
import de.bixilon.kutil.observer.DataObserver.Companion.observe
import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity
import de.bixilon.minosoft.gui.rendering.entity.EntityRenderer
import de.bixilon.minosoft.gui.rendering.entity.models.DamageableModel
open class LocalPlayerModel(renderer: EntityRenderer, player: PlayerEntity) : PlayerModel(renderer, player), DamageableModel {
override val hideSkeletalModel: Boolean
get() = super.hideSkeletalModel || !context.camera.view.view.renderSelf
init {
renderer.profile.hitbox::showLocal.observe(this, true) { updateHitbox(it) }
renderer.context.camera.view::view.observe(this) { updateHitbox(it.renderSelf) }
}
private fun updateHitbox(config: Boolean = renderer.profile.hitbox.showLocal, view: Boolean = renderer.context.camera.view.view.renderSelf) {
hitbox.enabled = config || view
}
override fun onDamage() {
renderer.context.camera.matrixHandler.shaking.onDamage()
}
}

View File

@ -1,132 +0,0 @@
/*
* 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.entity.models.minecraft.player
import de.bixilon.kutil.observer.DataObserver.Companion.observe
import de.bixilon.kutil.observer.set.SetObserver.Companion.observeSet
import de.bixilon.minosoft.data.entities.entities.player.Arms
import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity
import de.bixilon.minosoft.data.entities.entities.player.SkinParts
import de.bixilon.minosoft.data.entities.entities.player.properties.PlayerProperties
import de.bixilon.minosoft.data.entities.entities.player.properties.textures.metadata.SkinModel
import de.bixilon.minosoft.gui.rendering.entity.EntityRenderer
import de.bixilon.minosoft.gui.rendering.entity.models.SkeletalEntityModel
import de.bixilon.minosoft.gui.rendering.models.loader.ModelLoader.Companion.bbModel
import de.bixilon.minosoft.gui.rendering.skeletal.instance.SkeletalInstance
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.animations.SkeletalAnimation
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.elements.SkeletalElement
import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicStateChangeCallback
import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTexture
import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTextureState
import de.bixilon.minosoft.gui.rendering.system.base.texture.skin.PlayerSkin
import de.bixilon.minosoft.util.KUtil.toResourceLocation
open class PlayerModel(renderer: EntityRenderer, player: PlayerEntity) : SkeletalEntityModel<PlayerEntity>(renderer, player), DynamicStateChangeCallback {
private var properties = player.additional.properties
var skin: PlayerSkin? = null
private set
protected var refreshModel = false
private val legAnimator = LegAnimator(this)
private val armAnimator = ArmAnimator(this)
private val animations: MutableList<SkeletalAnimation> = mutableListOf(legAnimator, armAnimator)
private var _instance: SkeletalInstance? = null
override var instance = createModel(properties)
init {
entity::skinParts.observeSet(this) { refreshModel = true }
player.additional::properties.observe(this) { this.properties = it; refreshModel = true }
}
private fun createModel(properties: PlayerProperties?): SkeletalInstance? {
val skin = context.textures.skins.getSkin(entity, properties) ?: return null
val skinModel = skin.model
val unbaked = context.models.entities.loadUnbakedModel(if (skinModel == SkinModel.SLIM) SLIM_MODEL else WIDE_MODEL)
val elements: MutableList<SkeletalElement> = mutableListOf()
elementLoop@ for (element in unbaked.elements) {
for (skinPart in SkinParts.VALUES) {
if (skinPart.name == element.name) {
elements += element.skinCopy(entity.skinParts, skinPart)
continue@elementLoop
}
}
elements += element
}
skin.texture.usages.incrementAndGet()
this.skin?.texture?.usages?.decrementAndGet()
this.skin = skin
skin.texture += this
val skinTexture = if (skin.texture.state != DynamicTextureState.LOADED) context.textures.skins.default[entity.uuid] ?: return null else skin
val model = unbaked.copy(elements = elements, animations = animations).bake(context, mapOf(0 to skinTexture.texture))
val instance = SkeletalInstance(context, model)
for (animation in animations) {
instance.playAnimation(animation)
}
refreshModel = false
this.properties = properties
return instance
}
override fun prepareAsync() {
if (refreshModel) {
_instance = instance
instance = createModel(properties)
}
super.prepareAsync()
}
override fun prepare() {
_instance?.unload()
_instance = null
super.prepare()
}
private fun SkeletalElement.skinCopy(parts: Set<SkinParts>, part: SkinParts): SkeletalElement {
if (part in parts) {
return this
}
return this.copy(visible = false)
}
override fun onStateChange(texture: DynamicTexture, state: DynamicTextureState) {
if (skin?.texture === texture) {
refreshModel = true
}
}
override fun unload() {
skin?.texture?.usages?.decrementAndGet()
}
fun swingArm(arm: Arms) {
armAnimator.swingArm(arm)
}
companion object {
private val WIDE_MODEL = "minecraft:entities/player/wide".toResourceLocation().bbModel()
private val SLIM_MODEL = "minecraft:entities/player/slim".toResourceLocation().bbModel()
}
}

View File

@ -23,7 +23,7 @@ import de.bixilon.minosoft.gui.rendering.font.renderer.properties.FormattingProp
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMeshCache import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIMeshCache
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexConsumer
import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderIdentifiable import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture
import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture import de.bixilon.minosoft.gui.rendering.system.base.texture.texture.Texture
@ -31,7 +31,7 @@ class WorldGUIConsumer(val mesh: SingleChunkMesh, val transform: Mat4, val light
private val whiteTexture = mesh.context.textures.whiteTexture private val whiteTexture = mesh.context.textures.whiteTexture
override val order: IntArray get() = mesh.order override val order: IntArray get() = mesh.order
override fun addVertex(position: Vec2, texture: ShaderIdentifiable?, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) { override fun addVertex(position: Vec2, texture: ShaderTexture?, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) {
val transformed = transform.fastTimes(position.x / ChatComponentRenderer.TEXT_BLOCK_RESOLUTION, -position.y / ChatComponentRenderer.TEXT_BLOCK_RESOLUTION) val transformed = transform.fastTimes(position.x / ChatComponentRenderer.TEXT_BLOCK_RESOLUTION, -position.y / ChatComponentRenderer.TEXT_BLOCK_RESOLUTION)
mesh.addVertex(transformed, uv, (texture as Texture?) ?: whiteTexture.texture, tint.rgb, light) mesh.addVertex(transformed, uv, (texture as Texture?) ?: whiteTexture.texture, tint.rgb, light)
} }

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger * 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 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.
* *
@ -13,13 +13,11 @@
package de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.overlays package de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.overlays
import de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.overlays.arm.ArmOverlay
import de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.overlays.simple.* import de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.overlays.simple.*
import de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.overlays.weather.WeatherOverlay import de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.overlays.weather.WeatherOverlay
object DefaultOverlays { object DefaultOverlays {
val OVERLAYS = listOf( val OVERLAYS = listOf(
ArmOverlay,
WallOverlay, WallOverlay,
WaterOverlay, WaterOverlay,
PumpkinOverlay, PumpkinOverlay,

View File

@ -1,66 +0,0 @@
/*
* 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.framebuffer.world.overlay.overlays.arm
import de.bixilon.kotlinglm.vec2.Vec2
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.data.entities.entities.player.Arms
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalVertexConsumer
import de.bixilon.minosoft.gui.rendering.skeletal.model.SkeletalModel
import de.bixilon.minosoft.gui.rendering.system.base.buffer.vertex.PrimitiveTypes
import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
import de.bixilon.minosoft.gui.rendering.util.mesh.MeshStruct
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
open class ArmMesh(context: RenderContext, primitiveType: PrimitiveTypes = context.system.quadType) : Mesh(context, ArmMeshStruct, primitiveType, initialCacheSize = 2 * 3 * ArmMeshStruct.FLOATS_PER_VERTEX), SkeletalVertexConsumer {
fun addVertex(position: FloatArray, uv: Vec2) {
data.add(position)
data.add(uv.array)
}
override fun addVertex(position: FloatArray, transformedUV: Vec2, transform: Float, textureShaderId: Float, flags: Float) {
addVertex(position, transformedUV)
}
override fun addVertex(position: FloatArray, uv: Vec2, transform: Int, texture: ShaderTexture, flags: Int) {
addVertex(position, uv)
}
fun addArm(model: SkeletalModel, arm: Arms, skin: ShaderTexture) {
val elements = model.elements.filter {
when (arm) {
Arms.LEFT -> it.name == "LEFT_ARM" || it.name == "LEFT_SLEEVE"
Arms.RIGHT -> it.name == "RIGHT_ARM" || it.name == "RIGHT_SLEEVE"
}
}
val textures = Int2ObjectOpenHashMap<ShaderTexture>()
textures[0] = skin
for (element in elements) {
element.bake(model, textures, emptyMap(), this)
}
}
data class ArmMeshStruct(
val position: Vec3,
val uv: Vec2,
) {
companion object : MeshStruct(ArmMeshStruct::class)
}
}

View File

@ -1,147 +0,0 @@
/*
* 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.framebuffer.world.overlay.overlays.arm
import de.bixilon.kotlinglm.GLM
import de.bixilon.kotlinglm.func.rad
import de.bixilon.kotlinglm.mat4x4.Mat4
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.kutil.cast.CastUtil.nullCast
import de.bixilon.kutil.cast.CastUtil.unsafeNull
import de.bixilon.kutil.observer.DataObserver.Companion.observe
import de.bixilon.minosoft.data.entities.entities.player.Arms
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.camera.CameraDefinition
import de.bixilon.minosoft.gui.rendering.entity.models.minecraft.player.PlayerModel
import de.bixilon.minosoft.gui.rendering.events.ResizeWindowEvent
import de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.Overlay
import de.bixilon.minosoft.gui.rendering.framebuffer.world.overlay.OverlayFactory
import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel.Companion.fromBlockCoordinates
import de.bixilon.minosoft.gui.rendering.system.base.IntegratedBufferTypes
import de.bixilon.minosoft.gui.rendering.system.base.RenderingCapabilities
import de.bixilon.minosoft.gui.rendering.system.base.texture.skin.PlayerSkin
import de.bixilon.minosoft.modding.event.listener.CallbackEventListener.Companion.listen
class ArmOverlay(private val context: RenderContext) : Overlay {
private val config = context.connection.profiles.rendering.overlay
private val shader = context.system.createShader(minosoft("arm")) { ArmOverlayShader(it) }
override val render: Boolean
get() = context.camera.view.view.renderArm && config.arm.render
private var arm = context.connection.player.mainArm // TODO: camera player entity
private var skin: PlayerSkin? = null
private var model: PlayerModel? = null
private var mesh: ArmMesh = unsafeNull()
private var refresh = false
private var refreshTransform = true
override fun init() {
context.connection.profiles.connection::mainArm.observe(this, true) { this.arm = it; refresh = true;refreshTransform = true }
context.connection.events.listen<ResizeWindowEvent> { this.refreshTransform = true }
}
private fun poll() {
val model = context.connection.player.model.nullCast<PlayerModel>()
val skin = model?.skin
// TODO: check skin parts
if (this.model == model && this.skin == skin) {
return
}
this.model = model
skin?.texture?.usages?.incrementAndGet()
this.skin?.texture?.usages?.decrementAndGet()
this.skin = skin
refresh = true
}
override fun postInit() {
shader.load()
createMesh()
}
private fun createMesh() {
this.mesh = ArmMesh(context)
val skin = this.skin
val model = this.model?.instance?.model?.model
if (model != null && skin != null) {
this.mesh.addArm(model, arm, skin.texture)
}
this.mesh.load()
}
override fun update() {
poll()
if (!refresh) {
return
}
this.mesh.unload()
createMesh()
this.refresh = false
}
private fun calculateTransform(): Mat4 {
val screen = context.window.sizef
val aspect = screen.x / screen.y
val projection = GLM.perspective(60.0f.rad, aspect, CameraDefinition.NEAR_PLANE, CameraDefinition.FAR_PLANE)
val model = this.model ?: return Mat4()
val outliner = model.instance?.model?.model?.outliner?.find { it.name == if (arm == Arms.LEFT) "LEFT_ARM" else "RIGHT_ARM" } ?: return Mat4()
val matrix = FirstPersonArmAnimator(model).calculateTransform(outliner, 0.0f)
val screenMatrix = Mat4()
val translation = Vec3(if (arm == Arms.LEFT) -0.08f else 0.08f, 0, 0)
if (aspect > 1.8f) {
translation.x *= aspect * 1.8f
}
screenMatrix.translateAssign(translation) // move inner side of arm to 0|0|0
screenMatrix.translateAssign(Vec3(if (arm == Arms.LEFT) -18 else -12, -38, -10).fromBlockCoordinates())
this.refreshTransform = false
return projection * screenMatrix * matrix
}
override fun draw() {
val skin = this.skin ?: return
context.system.clear(IntegratedBufferTypes.DEPTH_BUFFER)
context.system.disable(RenderingCapabilities.FACE_CULLING)
context.system.enable(RenderingCapabilities.DEPTH_TEST)
context.system.enable(RenderingCapabilities.BLENDING)
context.system.depthMask = true
shader.use()
shader.textureIndexLayer = skin.texture.shaderId
if (refreshTransform) {
shader.transform = calculateTransform()
}
mesh.draw()
context.system.clear(IntegratedBufferTypes.DEPTH_BUFFER)
}
companion object : OverlayFactory<ArmOverlay> {
override fun build(context: RenderContext): ArmOverlay {
return ArmOverlay(context)
}
}
}

View File

@ -1,30 +0,0 @@
/*
* Minosoft
* Copyright (C) 2020-2022 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.framebuffer.world.overlay.overlays.arm
import de.bixilon.kotlinglm.mat4x4.Mat4
import de.bixilon.minosoft.gui.rendering.shader.Shader
import de.bixilon.minosoft.gui.rendering.shader.types.TextureShader
import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureManager
class ArmOverlayShader(
override val native: NativeShader,
) : Shader(), TextureShader {
override var textures: TextureManager by textureManager()
var textureIndexLayer by uniform("uIndexLayer", 0, NativeShader::setUInt)
var transform by uniform("uTransform", Mat4())
}

View File

@ -1,40 +0,0 @@
/*
* 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.framebuffer.world.overlay.overlays.arm
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.data.entities.entities.player.Arms
import de.bixilon.minosoft.gui.rendering.entity.models.minecraft.player.PlayerModel
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.animations.AnimationLoops
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.animations.SkeletalAnimation
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.animations.animator.keyframes.KeyframeChannels
import de.bixilon.minosoft.gui.rendering.skeletal.model.legacy.outliner.SkeletalOutliner
class FirstPersonArmAnimator(private val player: PlayerModel) : SkeletalAnimation {
override val name: String = ""
override val loop = AnimationLoops.LOOP
override val length: Float = 100.0f
// TODO (swinging: move arm to front, rotate)
override fun get(channel: KeyframeChannels, outliner: SkeletalOutliner, time: Float): Vec3? {
if (channel != KeyframeChannels.ROTATION) {
return null
}
if (player.entity.mainArm == Arms.LEFT) {
return Vec3(-120, -20, 0)
}
return Vec3(-120, 20, 10)
}
}

View File

@ -24,7 +24,7 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions
import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicStateChangeCallback import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicStateChangeCallback
import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTexture import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTexture
import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTextureState import de.bixilon.minosoft.gui.rendering.system.base.texture.dynamic.DynamicTextureState
import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderIdentifiable import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY
open class DynamicImageElement( open class DynamicImageElement(
@ -82,7 +82,7 @@ open class DynamicImageElement(
this.parent = parent this.parent = parent
} }
private fun getAvailableTexture(): ShaderIdentifiable { private fun getAvailableTexture(): ShaderTexture {
val texture = texture ?: return context.textures.whiteTexture.texture val texture = texture ?: return context.textures.whiteTexture.texture
if (texture.state != DynamicTextureState.LOADED) { if (texture.state != DynamicTextureState.LOADED) {
return context.textures.whiteTexture.texture return context.textures.whiteTexture.texture

View File

@ -19,6 +19,7 @@ import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.RenderContext import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.system.base.MeshUtil.buffer import de.bixilon.minosoft.gui.rendering.system.base.MeshUtil.buffer
import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderIdentifiable import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderIdentifiable
import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
import de.bixilon.minosoft.gui.rendering.util.mesh.MeshStruct import de.bixilon.minosoft.gui.rendering.util.mesh.MeshStruct
import de.bixilon.minosoft.util.collections.floats.FragmentedArrayFloatList import de.bixilon.minosoft.util.collections.floats.FragmentedArrayFloatList
@ -30,7 +31,7 @@ class GUIMesh(
) : Mesh(context, GUIMeshStruct, initialCacheSize = 40000, clearOnLoad = false, data = data), GUIVertexConsumer { ) : Mesh(context, GUIMeshStruct, initialCacheSize = 40000, clearOnLoad = false, data = data), GUIVertexConsumer {
private val whiteTexture = context.textures.whiteTexture private val whiteTexture = context.textures.whiteTexture
override fun addVertex(position: Vec2, texture: ShaderIdentifiable?, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) { override fun addVertex(position: Vec2, texture: ShaderTexture?, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) {
addVertex(data, halfSize, position, texture ?: whiteTexture.texture, uv, tint, options) addVertex(data, halfSize, position, texture ?: whiteTexture.texture, uv, tint, options)
} }

View File

@ -18,7 +18,7 @@ import de.bixilon.kutil.collections.primitive.floats.AbstractFloatList
import de.bixilon.kutil.collections.primitive.floats.HeapArrayFloatList import de.bixilon.kutil.collections.primitive.floats.HeapArrayFloatList
import de.bixilon.minosoft.data.text.formatting.color.RGBColor import de.bixilon.minosoft.data.text.formatting.color.RGBColor
import de.bixilon.minosoft.gui.rendering.RenderContext import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderIdentifiable import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture
import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY
class GUIMeshCache( class GUIMeshCache(
@ -42,7 +42,7 @@ class GUIMeshCache(
} }
} }
override fun addVertex(position: Vec2, texture: ShaderIdentifiable?, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) { override fun addVertex(position: Vec2, texture: ShaderTexture?, uv: Vec2, tint: RGBColor, options: GUIVertexOptions?) {
GUIMesh.addVertex(data, halfSize, position, texture ?: whiteTexture.texture, uv, tint, options) GUIMesh.addVertex(data, halfSize, position, texture ?: whiteTexture.texture, uv, tint, options)
revision++ revision++
} }

View File

@ -17,7 +17,7 @@ import de.bixilon.kutil.latch.AbstractLatch
import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.data.registries.identified.ResourceLocationUtil.extend import de.bixilon.minosoft.data.registries.identified.ResourceLocationUtil.extend
import de.bixilon.minosoft.gui.rendering.RenderContext import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.chunk.entities.EntityModels import de.bixilon.minosoft.gui.rendering.chunk.entities.DefaultEntityModels
import de.bixilon.minosoft.util.logging.Log import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.LogMessageType import de.bixilon.minosoft.util.logging.LogMessageType
@ -27,16 +27,17 @@ class ModelLoader(
) { ) {
val packFormat = context.connection.assetsManager.properties.pack.format val packFormat = context.connection.assetsManager.properties.pack.format
val fluids = FluidModelLoader(this) val fluids = FluidModelLoader(this)
val entities = EntityModels(this)
val block = BlockLoader(this) val block = BlockLoader(this)
val item = ItemLoader(this) val item = ItemLoader(this)
val skeletal = SkeletalLoader(this)
fun load(latch: AbstractLatch) { fun load(latch: AbstractLatch) {
DefaultEntityModels.load(this, latch)
fluids.load(latch) fluids.load(latch)
entities.load(latch)
block.load(latch) block.load(latch)
item.load(latch) item.load(latch)
skeletal.load(latch)
Log.log(LogMessageType.LOADING, LogLevels.VERBOSE) { "Loaded all models!" } Log.log(LogMessageType.LOADING, LogLevels.VERBOSE) { "Loaded all models!" }
} }
@ -44,7 +45,7 @@ class ModelLoader(
fun bake(latch: AbstractLatch) { fun bake(latch: AbstractLatch) {
block.bake(latch) block.bake(latch)
item.bake(latch) item.bake(latch)
entities.bake() skeletal.bake(latch)
Log.log(LogMessageType.LOADING, LogLevels.VERBOSE) { "Baked models!" } Log.log(LogMessageType.LOADING, LogLevels.VERBOSE) { "Baked models!" }
} }
@ -52,6 +53,7 @@ class ModelLoader(
fun cleanup() { fun cleanup() {
block.cleanup() block.cleanup()
item.cleanup() item.cleanup()
skeletal.cleanup()
} }
companion object { companion object {

View File

@ -0,0 +1,39 @@
/*
* 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.models.loader
import de.bixilon.kutil.latch.AbstractLatch
import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel
import de.bixilon.minosoft.gui.rendering.system.base.texture.shader.ShaderTexture
class SkeletalLoader(private val loader: ModelLoader) {
fun load(latch: AbstractLatch?) {
}
fun bake(latch: AbstractLatch?) {
}
fun cleanup() {
}
operator fun get(name: ResourceLocation): BakedSkeletalModel? {
TODO()
}
fun register(name: ResourceLocation, template: ResourceLocation = name, override: Map<ResourceLocation, ShaderTexture>) {
TODO()
}
}

View File

@ -46,14 +46,14 @@ class SkeletalManager(
fun draw(instance: SkeletalInstance, light: Int) { fun draw(instance: SkeletalInstance, light: Int) {
prepareDraw() prepareDraw()
shader.light = light shader.light = light
val transforms = instance.calculateTransforms() // val transforms = instance.calculateTransforms()
var stride = 0 // var stride = 0
for (transform in transforms) { // for (transform in transforms) {
for (float in transform.array) { // for (float in transform.array) {
uniformBuffer.buffer.put(stride++, float) // uniformBuffer.buffer.put(stride++, float)
} // }
} // }
uniformBuffer.upload(0 until (transforms.size * MAT4_SIZE)) // uniformBuffer.upload(0 until (transforms.size * MAT4_SIZE))
instance.model.mesh.draw() instance.model.mesh.draw()
} }

View File

@ -11,7 +11,7 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft. * This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/ */
package de.bixilon.minosoft.gui.rendering.skeletal.bake package de.bixilon.minosoft.gui.rendering.skeletal.baked
import de.bixilon.kotlinglm.mat4x4.Mat4 import de.bixilon.kotlinglm.mat4x4.Mat4
import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.kotlinglm.vec3.Vec3
@ -40,6 +40,6 @@ data class BakedSkeletalModel(
} }
fun createInstance(context: RenderContext, position: Vec3, transform: Mat4 = Mat4()): SkeletalInstance { fun createInstance(context: RenderContext, position: Vec3, transform: Mat4 = Mat4()): SkeletalInstance {
TODO()
} }
} }

View File

@ -11,7 +11,7 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft. * This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/ */
package de.bixilon.minosoft.gui.rendering.skeletal.bake package de.bixilon.minosoft.gui.rendering.skeletal.baked
import de.bixilon.kotlinglm.vec3.Vec3 import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.data.registries.identified.ResourceLocation

View File

@ -11,7 +11,7 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft. * This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/ */
package de.bixilon.minosoft.gui.rendering.skeletal.bake package de.bixilon.minosoft.gui.rendering.skeletal.baked
enum class SkeletalModelStates { enum class SkeletalModelStates {
DECLARED, DECLARED,

View File

@ -11,7 +11,7 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft. * This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/ */
package de.bixilon.minosoft.gui.rendering.skeletal.bake package de.bixilon.minosoft.gui.rendering.skeletal.baked
class SkeletalTransform( class SkeletalTransform(
val id: Int, val id: Int,

View File

@ -13,8 +13,18 @@
package de.bixilon.minosoft.gui.rendering.skeletal.instance package de.bixilon.minosoft.gui.rendering.skeletal.instance
import de.bixilon.minosoft.gui.rendering.skeletal.bake.BakedSkeletalModel import de.bixilon.minosoft.gui.rendering.shader.Shader
import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel
class SkeletalInstance( class SkeletalInstance(
val model: BakedSkeletalModel, val model: BakedSkeletalModel,
) ) {
fun draw(light: Int = 0xFF) {
TODO()
}
fun draw(shader: Shader? = null) {
TODO()
}
}

View File

@ -16,8 +16,8 @@ package de.bixilon.minosoft.gui.rendering.skeletal.model
import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.gui.rendering.RenderContext import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalMesh import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalMesh
import de.bixilon.minosoft.gui.rendering.skeletal.bake.BakedSkeletalModel import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel
import de.bixilon.minosoft.gui.rendering.skeletal.bake.SkeletalTransform import de.bixilon.minosoft.gui.rendering.skeletal.baked.SkeletalTransform
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.SkeletalAnimation import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.SkeletalAnimation
import de.bixilon.minosoft.gui.rendering.skeletal.model.elements.SkeletalElement import de.bixilon.minosoft.gui.rendering.skeletal.model.elements.SkeletalElement
import de.bixilon.minosoft.gui.rendering.skeletal.model.textures.SkeletalTexture import de.bixilon.minosoft.gui.rendering.skeletal.model.textures.SkeletalTexture

View File

@ -17,8 +17,8 @@ import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.data.direction.Directions import de.bixilon.minosoft.data.direction.Directions
import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalMesh import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalMesh
import de.bixilon.minosoft.gui.rendering.skeletal.bake.SkeletalBakeContext import de.bixilon.minosoft.gui.rendering.skeletal.baked.SkeletalBakeContext
import de.bixilon.minosoft.gui.rendering.skeletal.bake.SkeletalTransform import de.bixilon.minosoft.gui.rendering.skeletal.baked.SkeletalTransform
import de.bixilon.minosoft.gui.rendering.skeletal.model.textures.SkeletalTextureInstance import de.bixilon.minosoft.gui.rendering.skeletal.model.textures.SkeletalTextureInstance
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY

View File

@ -20,7 +20,7 @@ import de.bixilon.minosoft.data.direction.Directions
import de.bixilon.minosoft.data.registries.identified.ResourceLocation import de.bixilon.minosoft.data.registries.identified.ResourceLocation
import de.bixilon.minosoft.gui.rendering.models.block.element.face.FaceUV import de.bixilon.minosoft.gui.rendering.models.block.element.face.FaceUV
import de.bixilon.minosoft.gui.rendering.models.block.legacy.ModelBakeUtil import de.bixilon.minosoft.gui.rendering.models.block.legacy.ModelBakeUtil
import de.bixilon.minosoft.gui.rendering.skeletal.bake.SkeletalBakeContext import de.bixilon.minosoft.gui.rendering.skeletal.baked.SkeletalBakeContext
import de.bixilon.minosoft.gui.rendering.system.base.MeshUtil.buffer import de.bixilon.minosoft.gui.rendering.system.base.MeshUtil.buffer
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rotateAssign import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rotateAssign

View File

@ -89,7 +89,7 @@ abstract class Mesh(
} }
fun addXQuad(start: Vec2, x: Float, end: Vec2, uvStart: Vec2 = Vec2(0.0f, 0.0f), uvEnd: Vec2 = Vec2(1.0f, 1.0f), vertexConsumer: (position: Vec3, uv: Vec2) -> Unit) { inline fun addXQuad(start: Vec2, x: Float, end: Vec2, uvStart: Vec2 = Vec2(0.0f, 0.0f), uvEnd: Vec2 = Vec2(1.0f, 1.0f), vertexConsumer: (position: Vec3, uv: Vec2) -> Unit) {
val positions = arrayOf( val positions = arrayOf(
Vec3(x, start.x, start.y), Vec3(x, start.x, start.y),
Vec3(x, start.x, end.y), Vec3(x, start.x, end.y),
@ -99,7 +99,7 @@ abstract class Mesh(
addQuad(positions, uvStart, uvEnd, vertexConsumer) addQuad(positions, uvStart, uvEnd, vertexConsumer)
} }
fun addYQuad(start: Vec2, y: Float, end: Vec2, uvStart: Vec2 = Vec2(0.0f, 0.0f), uvEnd: Vec2 = Vec2(1.0f, 1.0f), vertexConsumer: (position: Vec3, uv: Vec2) -> Unit) { inline fun addYQuad(start: Vec2, y: Float, end: Vec2, uvStart: Vec2 = Vec2(0.0f, 0.0f), uvEnd: Vec2 = Vec2(1.0f, 1.0f), vertexConsumer: (position: Vec3, uv: Vec2) -> Unit) {
val positions = arrayOf( val positions = arrayOf(
Vec3(start.x, y, end.y), Vec3(start.x, y, end.y),
Vec3(end.x, y, end.y), Vec3(end.x, y, end.y),
@ -109,7 +109,7 @@ abstract class Mesh(
addQuad(positions, uvStart, uvEnd, vertexConsumer) addQuad(positions, uvStart, uvEnd, vertexConsumer)
} }
fun addZQuad(start: Vec2, z: Float, end: Vec2, uvStart: Vec2 = Vec2(0.0f, 0.0f), uvEnd: Vec2 = Vec2(1.0f, 1.0f), vertexConsumer: (position: Vec3, uv: Vec2) -> Unit) { inline fun addZQuad(start: Vec2, z: Float, end: Vec2, uvStart: Vec2 = Vec2(0.0f, 0.0f), uvEnd: Vec2 = Vec2(1.0f, 1.0f), vertexConsumer: (position: Vec3, uv: Vec2) -> Unit) {
val positions = arrayOf( val positions = arrayOf(
Vec3(start.x, start.y, z), Vec3(start.x, start.y, z),
Vec3(start.x, end.y, z), Vec3(start.x, end.y, z),
@ -119,7 +119,7 @@ abstract class Mesh(
addQuad(positions, uvStart, uvEnd, vertexConsumer) addQuad(positions, uvStart, uvEnd, vertexConsumer)
} }
fun addQuad(positions: Array<Vec3>, uvStart: Vec2 = Vec2(0.0f, 0.0f), uvEnd: Vec2 = Vec2(1.0f, 1.0f), vertexConsumer: (position: Vec3, uv: Vec2) -> Unit) { inline fun addQuad(positions: Array<Vec3>, uvStart: Vec2 = Vec2(0.0f, 0.0f), uvEnd: Vec2 = Vec2(1.0f, 1.0f), vertexConsumer: (position: Vec3, uv: Vec2) -> Unit) {
val texturePositions = arrayOf( val texturePositions = arrayOf(
uvStart, uvStart,
Vec2(uvStart.x, uvEnd.y), Vec2(uvStart.x, uvEnd.y),

View File

@ -30,8 +30,8 @@ class BlockActionS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket {
} else { } else {
buffer.readBlockPosition() buffer.readBlockPosition()
} }
val data1: Byte = buffer.readByte() val data1 = buffer.readByte().toInt()
val data2: Byte = buffer.readByte() val data2 = 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) 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) { override fun handle(connection: PlayConnection) {