mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-19 04:15:14 -04:00
improve entity model loading, all chest models
This commit is contained in:
parent
490ce22a5c
commit
4e0a9b1847
@ -13,27 +13,44 @@
|
||||
|
||||
package de.bixilon.minosoft.data.entities.block.container.storage
|
||||
|
||||
import de.bixilon.minosoft.data.entities.block.BlockEntity
|
||||
import de.bixilon.minosoft.data.entities.block.BlockEntityFactory
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
||||
import de.bixilon.minosoft.data.registries.blocks.properties.ChestTypes
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.world.entities.BlockEntityRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.world.entities.renderer.storage.ChestBlockEntityRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.world.entities.renderer.storage.DoubleChestRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.world.entities.renderer.storage.SingleChestRenderer
|
||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
open class ChestBlockEntity(connection: PlayConnection) : StorageBlockEntity(connection) {
|
||||
|
||||
override fun createRenderer(renderWindow: RenderWindow, blockState: BlockState, blockPosition: Vec3i): BlockEntityRenderer<out BlockEntity>? {
|
||||
return ChestBlockEntityRenderer(this, renderWindow, blockState, blockPosition)
|
||||
override fun createRenderer(renderWindow: RenderWindow, blockState: BlockState, blockPosition: Vec3i): BlockEntityRenderer<*>? {
|
||||
val type = blockState.properties[BlockProperties.CHEST_TYPE] ?: return null
|
||||
if (type == ChestTypes.SINGLE) {
|
||||
return SingleChestRenderer(this, renderWindow, blockState, blockPosition, renderWindow.modelLoader.entities.models[getSingleModel()] ?: return null)
|
||||
}
|
||||
|
||||
if (type == ChestTypes.LEFT) {
|
||||
// only left chest will be rendered (the model is the double chest)
|
||||
return DoubleChestRenderer(this, renderWindow, blockState, blockPosition, renderWindow.modelLoader.entities.models[getDoubleModel()] ?: return null)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
protected open fun getSingleModel(): ResourceLocation {
|
||||
return SingleChestRenderer.NormalChest.MODEL
|
||||
}
|
||||
|
||||
protected open fun getDoubleModel(): ResourceLocation {
|
||||
return DoubleChestRenderer.NormalChest.MODEL
|
||||
}
|
||||
|
||||
companion object : BlockEntityFactory<ChestBlockEntity> {
|
||||
override val RESOURCE_LOCATION: ResourceLocation = ResourceLocation("minecraft:chest")
|
||||
val SINGLE_MODEL = "minecraft:block/entities/single_chest".toResourceLocation()
|
||||
val DOUBLE_MODEL = "minecraft:block/entities/double_chest".toResourceLocation()
|
||||
|
||||
override fun build(connection: PlayConnection): ChestBlockEntity {
|
||||
return ChestBlockEntity(connection)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 Moritz Zwerger
|
||||
* 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.
|
||||
*
|
||||
@ -13,12 +13,23 @@
|
||||
|
||||
package de.bixilon.minosoft.data.entities.block.container.storage
|
||||
|
||||
import de.bixilon.minosoft.data.entities.block.BlockEntity
|
||||
import de.bixilon.minosoft.data.entities.block.BlockEntityFactory
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.world.entities.BlockEntityRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.world.entities.renderer.storage.SingleChestRenderer
|
||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
class EnderChestBlockEntity(connection: PlayConnection) : StorageBlockEntity(connection) {
|
||||
|
||||
override fun createRenderer(renderWindow: RenderWindow, blockState: BlockState, blockPosition: Vec3i): BlockEntityRenderer<out BlockEntity>? {
|
||||
val model = renderWindow.modelLoader.entities.models[SingleChestRenderer.EnderChest.MODEL] ?: return null
|
||||
return SingleChestRenderer(this, renderWindow, blockState, blockPosition, model)
|
||||
}
|
||||
|
||||
companion object : BlockEntityFactory<EnderChestBlockEntity> {
|
||||
override val RESOURCE_LOCATION: ResourceLocation = ResourceLocation("minecraft:ender_chest")
|
||||
|
||||
|
@ -15,10 +15,20 @@ package de.bixilon.minosoft.data.entities.block.container.storage
|
||||
|
||||
import de.bixilon.minosoft.data.entities.block.BlockEntityFactory
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.world.entities.renderer.storage.DoubleChestRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.world.entities.renderer.storage.SingleChestRenderer
|
||||
import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection
|
||||
|
||||
class TrappedChestBlockEntity(connection: PlayConnection) : ChestBlockEntity(connection) {
|
||||
|
||||
override fun getSingleModel(): ResourceLocation {
|
||||
return SingleChestRenderer.TrappedChest.MODEL
|
||||
}
|
||||
|
||||
override fun getDoubleModel(): ResourceLocation {
|
||||
return DoubleChestRenderer.TrappedChest.MODEL
|
||||
}
|
||||
|
||||
companion object : BlockEntityFactory<TrappedChestBlockEntity> {
|
||||
override val RESOURCE_LOCATION: ResourceLocation = ResourceLocation("minecraft:trapped_chest")
|
||||
|
||||
|
@ -20,7 +20,6 @@ import de.bixilon.minosoft.data.registries.registries.Registries
|
||||
|
||||
open class TrappedChestBlock(resourceLocation: ResourceLocation, registries: Registries, data: Map<String, Any>) : ChestBlock<TrappedChestBlockEntity>(resourceLocation, registries, data) {
|
||||
|
||||
|
||||
companion object : BlockFactory<TrappedChestBlock> {
|
||||
override fun build(resourceLocation: ResourceLocation, registries: Registries, data: Map<String, Any>): TrappedChestBlock {
|
||||
return TrappedChestBlock(resourceLocation, registries, data)
|
||||
|
@ -188,6 +188,13 @@ class RenderWindow(
|
||||
renderer.postInit(latch)
|
||||
framebufferManager.postInit()
|
||||
|
||||
|
||||
Log.log(LogMessageType.RENDERING_LOADING, LogLevels.VERBOSE) { "Loading skeletal meshes ${stopwatch.totalTime()}" }
|
||||
|
||||
for (model in modelLoader.entities.models.values) {
|
||||
model.loadMesh(this)
|
||||
}
|
||||
|
||||
Log.log(LogMessageType.RENDERING_LOADING, LogLevels.VERBOSE) { "Registering callbacks (${stopwatch.labTime()})..." }
|
||||
|
||||
connection.registerEvent(CallbackEventInvoker.of<WindowFocusChangeEvent> {
|
||||
@ -211,10 +218,6 @@ class RenderWindow(
|
||||
|
||||
connection.fireEvent(ResizeWindowEvent(previousSize = Vec2i(0, 0), size = window.size))
|
||||
|
||||
for (model in modelLoader.blockModels.values) {
|
||||
model.loadMesh(this)
|
||||
}
|
||||
|
||||
Log.log(LogMessageType.RENDERING_LOADING) { "Rendering is fully prepared in ${stopwatch.totalTime()}" }
|
||||
initialized = true
|
||||
latch.dec()
|
||||
|
@ -14,12 +14,10 @@
|
||||
package de.bixilon.minosoft.gui.rendering.models
|
||||
|
||||
import de.bixilon.kutil.cast.CastUtil.unsafeCast
|
||||
import de.bixilon.kutil.collections.CollectionUtil.synchronizedMapOf
|
||||
import de.bixilon.kutil.collections.CollectionUtil.toSynchronizedMap
|
||||
import de.bixilon.kutil.collections.map.SynchronizedMap
|
||||
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
|
||||
import de.bixilon.kutil.latch.CountUpAndDownLatch
|
||||
import de.bixilon.minosoft.assets.util.FileUtil.readJson
|
||||
import de.bixilon.minosoft.assets.util.FileUtil.readJsonObject
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.data.registries.blocks.types.Block
|
||||
@ -31,20 +29,19 @@ import de.bixilon.minosoft.gui.rendering.models.unbaked.GenericUnbakedModel
|
||||
import de.bixilon.minosoft.gui.rendering.models.unbaked.UnbakedBlockModel
|
||||
import de.bixilon.minosoft.gui.rendering.models.unbaked.UnbakedItemModel
|
||||
import de.bixilon.minosoft.gui.rendering.models.unbaked.block.RootModel
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.model.SkeletalModel
|
||||
import de.bixilon.minosoft.gui.rendering.world.entities.DefaultEntityModels
|
||||
import de.bixilon.minosoft.gui.rendering.world.entities.EntityModels
|
||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||
import de.bixilon.minosoft.util.logging.Log
|
||||
import de.bixilon.minosoft.util.logging.LogLevels
|
||||
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
|
||||
|
||||
class ModelLoader(
|
||||
val renderWindow: RenderWindow,
|
||||
) {
|
||||
private val assetsManager = renderWindow.connection.assetsManager
|
||||
private val unbakedBlockModels: SynchronizedMap<ResourceLocation, GenericUnbakedModel> = BuiltinModels.BUILTIN_MODELS.toSynchronizedMap()
|
||||
val blockModels: SynchronizedMap<ResourceLocation, BakedSkeletalModel> = synchronizedMapOf()
|
||||
val entities = EntityModels(renderWindow)
|
||||
|
||||
private val registry: Registries = renderWindow.connection.registries
|
||||
|
||||
@ -53,18 +50,6 @@ class ModelLoader(
|
||||
unbakedBlockModels.clear()
|
||||
}
|
||||
|
||||
private fun ResourceLocation.model(): ResourceLocation {
|
||||
return ResourceLocation(this.namespace, "models/" + this.path + ".json")
|
||||
}
|
||||
|
||||
private fun ResourceLocation.bbModel(): ResourceLocation {
|
||||
return ResourceLocation(this.namespace, "models/" + this.path + ".bbmodel")
|
||||
}
|
||||
|
||||
private fun ResourceLocation.blockState(): ResourceLocation {
|
||||
return ResourceLocation(this.namespace, "blockstates/" + this.path + ".json")
|
||||
}
|
||||
|
||||
private fun loadBlockStates(block: Block) {
|
||||
val blockStateJson = assetsManager[block.resourceLocation.blockState()].readJsonObject()
|
||||
|
||||
@ -106,13 +91,6 @@ class ModelLoader(
|
||||
return model
|
||||
}
|
||||
|
||||
private fun loadBlockEntityModel(resourceLocation: ResourceLocation): SkeletalModel {
|
||||
val model: SkeletalModel = renderWindow.connection.assetsManager[resourceLocation].readJson()
|
||||
this.blockModels[resourceLocation] = model.bake(renderWindow, Int2ObjectOpenHashMap())
|
||||
println("Loaded $resourceLocation!")
|
||||
return model
|
||||
}
|
||||
|
||||
private fun loadBlockModels(latch: CountUpAndDownLatch) {
|
||||
val blockLatch = CountUpAndDownLatch(1, latch)
|
||||
// ToDo: Optimize performance
|
||||
@ -139,12 +117,15 @@ class ModelLoader(
|
||||
itemLatch.await()
|
||||
}
|
||||
|
||||
private fun loadBlockEntityModels(latch: CountUpAndDownLatch) {
|
||||
Log.log(LogMessageType.VERSION_LOADING, LogLevels.VERBOSE) { "Loading block entity models..." }
|
||||
private fun loadEntityModels(latch: CountUpAndDownLatch) {
|
||||
Log.log(LogMessageType.VERSION_LOADING, LogLevels.VERBOSE) { "Loading entity models..." }
|
||||
val itemLatch = CountUpAndDownLatch(1, latch)
|
||||
|
||||
loadBlockEntityModel("minecraft:block/entities/single_chest".toResourceLocation().bbModel())
|
||||
|
||||
for (register in DefaultEntityModels.MODELS) {
|
||||
itemLatch.inc()
|
||||
DefaultThreadPool += { register.register(renderWindow, this); itemLatch.dec() }
|
||||
}
|
||||
itemLatch.dec()
|
||||
itemLatch.await()
|
||||
}
|
||||
@ -152,10 +133,25 @@ class ModelLoader(
|
||||
fun load(latch: CountUpAndDownLatch) {
|
||||
loadBlockModels(latch)
|
||||
loadItemModels(latch)
|
||||
loadBlockEntityModels(latch)
|
||||
loadEntityModels(latch)
|
||||
|
||||
Log.log(LogMessageType.VERSION_LOADING, LogLevels.VERBOSE) { "Done loading models!" }
|
||||
|
||||
cleanup()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun ResourceLocation.model(): ResourceLocation {
|
||||
return ResourceLocation(this.namespace, "models/" + this.path + ".json")
|
||||
}
|
||||
|
||||
fun ResourceLocation.blockState(): ResourceLocation {
|
||||
return ResourceLocation(this.namespace, "blockstates/" + this.path + ".json")
|
||||
}
|
||||
|
||||
fun ResourceLocation.bbModel(): ResourceLocation {
|
||||
return ResourceLocation(this.namespace, "models/" + this.path + ".bbmodel")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ data class SkeletalModel(
|
||||
val animations: List<SkeletalAnimation> = listOf(),
|
||||
) {
|
||||
|
||||
fun bake(renderWindow: RenderWindow, textureOverride: Int2ObjectOpenHashMap<AbstractTexture>): BakedSkeletalModel {
|
||||
fun bake(renderWindow: RenderWindow, textureOverride: MutableMap<Int, AbstractTexture>): BakedSkeletalModel {
|
||||
val textures: Int2ObjectOpenHashMap<AbstractTexture> = Int2ObjectOpenHashMap()
|
||||
for (entry in this.textures) {
|
||||
val override = textureOverride[entry.id]
|
||||
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.world.entities
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.world.entities.renderer.storage.DoubleChestRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.world.entities.renderer.storage.SingleChestRenderer
|
||||
|
||||
object DefaultEntityModels {
|
||||
val MODELS = listOf(
|
||||
SingleChestRenderer.NormalChest,
|
||||
SingleChestRenderer.TrappedChest,
|
||||
SingleChestRenderer.EnderChest,
|
||||
|
||||
DoubleChestRenderer.NormalChest,
|
||||
DoubleChestRenderer.TrappedChest,
|
||||
)
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.world.entities
|
||||
|
||||
import de.bixilon.minosoft.assets.util.FileUtil.readJson
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
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.texture.AbstractTexture
|
||||
|
||||
class EntityModels(val renderWindow: RenderWindow) {
|
||||
private val unbakedModels: MutableMap<ResourceLocation, SkeletalModel> = mutableMapOf()
|
||||
val models: MutableMap<ResourceLocation, BakedSkeletalModel> = mutableMapOf()
|
||||
|
||||
@Synchronized
|
||||
fun loadUnbakedModel(path: ResourceLocation): SkeletalModel {
|
||||
return unbakedModels.getOrPut(path) { renderWindow.connection.assetsManager[path].readJson() }
|
||||
}
|
||||
|
||||
fun loadModel(name: ResourceLocation, path: ResourceLocation, textureOverride: MutableMap<Int, AbstractTexture> = mutableMapOf()): BakedSkeletalModel {
|
||||
return models.getOrPut(name) { loadUnbakedModel(path).bake(renderWindow, textureOverride) }
|
||||
}
|
||||
|
||||
fun cleanup() {
|
||||
unbakedModels.clear()
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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.world.entities
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.models.ModelLoader
|
||||
|
||||
interface EntityRendererRegister {
|
||||
|
||||
fun register(renderWindow: RenderWindow, modelLoader: ModelLoader) {}
|
||||
}
|
@ -1,33 +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.world.entities.renderer.storage
|
||||
|
||||
import de.bixilon.kutil.cast.CastUtil.nullCast
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.entities.block.container.storage.ChestBlockEntity
|
||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.skeletal.instance.SkeletalInstance
|
||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
class ChestBlockEntityRenderer(
|
||||
val entity: ChestBlockEntity,
|
||||
renderWindow: RenderWindow,
|
||||
blockState: BlockState,
|
||||
blockPosition: Vec3i,
|
||||
) : StorageBlockEntityRenderer<ChestBlockEntity>(
|
||||
blockState,
|
||||
SkeletalInstance(renderWindow, blockPosition, renderWindow.modelLoader.blockModels["minecraft:models/block/entities/single_chest.bbmodel".toResourceLocation()]!!, (blockState.properties[BlockProperties.FACING]?.nullCast() ?: Directions.NORTH).rotatedMatrix))
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.world.entities.renderer.storage
|
||||
|
||||
import de.bixilon.kutil.cast.CastUtil.nullCast
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.entities.block.container.storage.StorageBlockEntity
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.models.ModelLoader
|
||||
import de.bixilon.minosoft.gui.rendering.models.ModelLoader.Companion.bbModel
|
||||
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.world.entities.EntityRendererRegister
|
||||
import de.bixilon.minosoft.util.DateUtil
|
||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
class DoubleChestRenderer(
|
||||
val entity: StorageBlockEntity,
|
||||
renderWindow: RenderWindow,
|
||||
blockState: BlockState,
|
||||
blockPosition: Vec3i,
|
||||
model: BakedSkeletalModel,
|
||||
) : StorageBlockEntityRenderer<StorageBlockEntity>(
|
||||
blockState,
|
||||
SkeletalInstance(renderWindow, blockPosition, model, (blockState.properties[BlockProperties.FACING]?.nullCast() ?: Directions.NORTH).rotatedMatrix)) {
|
||||
|
||||
|
||||
companion object {
|
||||
val DOUBLE_MODEL = "minecraft:block/entities/double_chest".toResourceLocation().bbModel()
|
||||
|
||||
fun register(renderWindow: RenderWindow, modelLoader: ModelLoader, textureName1: ResourceLocation, textureName2: ResourceLocation, model: ResourceLocation) {
|
||||
val texture1 = renderWindow.textureManager.staticTextures.createTexture(textureName1)
|
||||
val texture2 = renderWindow.textureManager.staticTextures.createTexture(textureName2)
|
||||
modelLoader.entities.loadModel(model, DOUBLE_MODEL, mutableMapOf(0 to texture1, 1 to texture2))
|
||||
}
|
||||
}
|
||||
|
||||
object NormalChest : EntityRendererRegister {
|
||||
val MODEL = "minecraft:models/block/entities/double_chest".toResourceLocation()
|
||||
val TEXTURE1 = "minecraft:entity/chest/normal_left".toResourceLocation().texture()
|
||||
val TEXTURE2 = "minecraft:entity/chest/normal_right".toResourceLocation().texture()
|
||||
val TEXTURE_CHRISTMAS1 = "minecraft:entity/chest/christmas_left".toResourceLocation().texture()
|
||||
val TEXTURE_CHRISTMAS2 = "minecraft:entity/chest/christmas_right".toResourceLocation().texture()
|
||||
|
||||
override fun register(renderWindow: RenderWindow, modelLoader: ModelLoader) {
|
||||
val christmas = DateUtil.christmas
|
||||
register(renderWindow, modelLoader, if (christmas) TEXTURE_CHRISTMAS1 else TEXTURE1, if (christmas) TEXTURE_CHRISTMAS2 else TEXTURE2, MODEL)
|
||||
}
|
||||
}
|
||||
|
||||
object TrappedChest : EntityRendererRegister {
|
||||
val MODEL = "minecraft:models/block/entities/double_trapped_chest".toResourceLocation()
|
||||
val TEXTURE1 = "minecraft:entity/chest/trapped_left".toResourceLocation().texture()
|
||||
val TEXTURE2 = "minecraft:entity/chest/trapped_right".toResourceLocation().texture()
|
||||
|
||||
override fun register(renderWindow: RenderWindow, modelLoader: ModelLoader) {
|
||||
register(renderWindow, modelLoader, TEXTURE1, TEXTURE2, MODEL)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.world.entities.renderer.storage
|
||||
|
||||
import de.bixilon.kutil.cast.CastUtil.nullCast
|
||||
import de.bixilon.minosoft.data.direction.Directions
|
||||
import de.bixilon.minosoft.data.entities.block.container.storage.StorageBlockEntity
|
||||
import de.bixilon.minosoft.data.registries.ResourceLocation
|
||||
import de.bixilon.minosoft.data.registries.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
|
||||
import de.bixilon.minosoft.gui.rendering.RenderWindow
|
||||
import de.bixilon.minosoft.gui.rendering.models.ModelLoader
|
||||
import de.bixilon.minosoft.gui.rendering.models.ModelLoader.Companion.bbModel
|
||||
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.world.entities.EntityRendererRegister
|
||||
import de.bixilon.minosoft.util.DateUtil
|
||||
import de.bixilon.minosoft.util.KUtil.toResourceLocation
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
class SingleChestRenderer(
|
||||
val entity: StorageBlockEntity,
|
||||
renderWindow: RenderWindow,
|
||||
blockState: BlockState,
|
||||
blockPosition: Vec3i,
|
||||
model: BakedSkeletalModel,
|
||||
) : StorageBlockEntityRenderer<StorageBlockEntity>(
|
||||
blockState,
|
||||
SkeletalInstance(renderWindow, blockPosition, model, (blockState.properties[BlockProperties.FACING]?.nullCast() ?: Directions.NORTH).rotatedMatrix)) {
|
||||
|
||||
|
||||
companion object {
|
||||
val SINGLE_MODEL = "minecraft:block/entities/single_chest".toResourceLocation().bbModel()
|
||||
|
||||
fun register(renderWindow: RenderWindow, modelLoader: ModelLoader, textureName: ResourceLocation, model: ResourceLocation) {
|
||||
val texture = renderWindow.textureManager.staticTextures.createTexture(textureName)
|
||||
modelLoader.entities.loadModel(model, SINGLE_MODEL, mutableMapOf(0 to texture))
|
||||
}
|
||||
}
|
||||
|
||||
object NormalChest : EntityRendererRegister {
|
||||
val MODEL = "minecraft:models/block/entities/single_chest".toResourceLocation()
|
||||
val TEXTURE = "minecraft:entity/chest/normal".toResourceLocation().texture()
|
||||
val TEXTURE_CHRISTMAS = "minecraft:entity/chest/christmas".toResourceLocation().texture()
|
||||
|
||||
override fun register(renderWindow: RenderWindow, modelLoader: ModelLoader) {
|
||||
register(renderWindow, modelLoader, if (DateUtil.christmas) TEXTURE_CHRISTMAS else TEXTURE, MODEL)
|
||||
}
|
||||
}
|
||||
|
||||
object TrappedChest : EntityRendererRegister {
|
||||
val MODEL = "minecraft:models/block/entities/trapped_chest".toResourceLocation()
|
||||
val TEXTURE = "minecraft:entity/chest/trapped".toResourceLocation().texture()
|
||||
|
||||
override fun register(renderWindow: RenderWindow, modelLoader: ModelLoader) {
|
||||
register(renderWindow, modelLoader, TEXTURE, MODEL)
|
||||
}
|
||||
}
|
||||
|
||||
object EnderChest : EntityRendererRegister {
|
||||
val MODEL = "minecraft:models/block/entities/ender_chest".toResourceLocation()
|
||||
val TEXTURE = "minecraft:entity/chest/ender".toResourceLocation().texture()
|
||||
|
||||
override fun register(renderWindow: RenderWindow, modelLoader: ModelLoader) {
|
||||
register(renderWindow, modelLoader, TEXTURE, MODEL)
|
||||
}
|
||||
}
|
||||
}
|
46
src/main/java/de/bixilon/minosoft/util/DateUtil.kt
Normal file
46
src/main/java/de/bixilon/minosoft/util/DateUtil.kt
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.util
|
||||
|
||||
import de.bixilon.kutil.time.TimeUtil
|
||||
import java.util.*
|
||||
|
||||
@Deprecated("Part of kutl 1.10")
|
||||
object DateUtil {
|
||||
val currentCalendar: Calendar
|
||||
get() {
|
||||
val calendar = Calendar.getInstance()
|
||||
calendar.timeInMillis = TimeUtil.time
|
||||
return calendar
|
||||
}
|
||||
|
||||
val christmas: Boolean
|
||||
get() {
|
||||
val calendar = currentCalendar
|
||||
if (calendar.get(Calendar.MONTH) != Calendar.DECEMBER) {
|
||||
return false
|
||||
}
|
||||
val day = calendar.get(Calendar.DAY_OF_MONTH)
|
||||
return day in 24..26
|
||||
}
|
||||
|
||||
val newYear: Boolean
|
||||
get() {
|
||||
val calendar = currentCalendar
|
||||
val month = calendar.get(Calendar.MONTH)
|
||||
val day = calendar.get(Calendar.DAY_OF_MONTH)
|
||||
|
||||
return (month == Calendar.DECEMBER && day == 31) || (month == Calendar.JANUARY && day == 1)
|
||||
}
|
||||
}
|
@ -0,0 +1,332 @@
|
||||
{
|
||||
"meta": {
|
||||
"format_version": "4.0",
|
||||
"model_format": "free",
|
||||
"box_uv": true
|
||||
},
|
||||
"name": "double_chest",
|
||||
"geometry_name": "chest",
|
||||
"visible_box": [1, 1, 0],
|
||||
"resolution": {
|
||||
"width": 64,
|
||||
"height": 64
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "bottom_left",
|
||||
"from": [8, -10, -7],
|
||||
"to": [23, 0, 7],
|
||||
"rotation": [-180, 0, 0],
|
||||
"uv_offset": [0, 19],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [14, 33, 29, 43],
|
||||
"texture": 1
|
||||
},
|
||||
"east": {
|
||||
"uv": [0, 33, 14, 43],
|
||||
"texture": 1
|
||||
},
|
||||
"south": {
|
||||
"uv": [43, 33, 58, 43],
|
||||
"texture": 1
|
||||
},
|
||||
"west": {
|
||||
"uv": [29, 33, 43, 43],
|
||||
"texture": 1
|
||||
},
|
||||
"up": {
|
||||
"uv": [29, 33, 14, 19],
|
||||
"texture": 1
|
||||
},
|
||||
"down": {
|
||||
"uv": [44, 19, 29, 33],
|
||||
"texture": 1
|
||||
}
|
||||
},
|
||||
"uuid": "76801e5b-8a1b-0a5d-c258-beef5dbc79ee"
|
||||
},
|
||||
{
|
||||
"name": "lid_left",
|
||||
"from": [8, -14, -7],
|
||||
"to": [23, -9, 7],
|
||||
"rotation": [-180, 0, 0],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [14, 14, 29, 19],
|
||||
"texture": 1
|
||||
},
|
||||
"east": {
|
||||
"uv": [0, 14, 14, 19],
|
||||
"texture": 1
|
||||
},
|
||||
"south": {
|
||||
"uv": [43, 14, 58, 19],
|
||||
"texture": 1
|
||||
},
|
||||
"west": {
|
||||
"uv": [29, 14, 43, 19],
|
||||
"texture": 1
|
||||
},
|
||||
"up": {
|
||||
"uv": [29, 14, 14, 0],
|
||||
"texture": 1
|
||||
},
|
||||
"down": {
|
||||
"uv": [44, 0, 29, 14],
|
||||
"texture": 1
|
||||
}
|
||||
},
|
||||
"uuid": "01d53de6-eeef-3c77-dd07-6f6d52b0527b"
|
||||
},
|
||||
{
|
||||
"name": "lock_left",
|
||||
"from": [-9, -11, -8],
|
||||
"to": [-8, -7, -7],
|
||||
"rotation": [0, 0, -180],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [1, 1, 2, 5],
|
||||
"texture": 0
|
||||
},
|
||||
"east": {
|
||||
"uv": [0, 1, 1, 5],
|
||||
"texture": 0
|
||||
},
|
||||
"south": {
|
||||
"uv": [3, 1, 4, 5],
|
||||
"texture": 0
|
||||
},
|
||||
"west": {
|
||||
"uv": [2, 1, 3, 5],
|
||||
"texture": 0
|
||||
},
|
||||
"up": {
|
||||
"uv": [2, 1, 1, 0],
|
||||
"texture": 0
|
||||
},
|
||||
"down": {
|
||||
"uv": [3, 0, 2, 1],
|
||||
"texture": 0
|
||||
}
|
||||
},
|
||||
"uuid": "3cc1a7d6-4cf0-42bc-032f-1b3a602ca1f6"
|
||||
},
|
||||
{
|
||||
"name": "bottom_right",
|
||||
"from": [-7, -10, -7],
|
||||
"to": [8, 0, 7],
|
||||
"rotation": [-180, 0, 0],
|
||||
"uv_offset": [0, 19],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [14, 33, 29, 43],
|
||||
"texture": 0
|
||||
},
|
||||
"east": {
|
||||
"uv": [0, 33, 14, 43],
|
||||
"texture": 0
|
||||
},
|
||||
"south": {
|
||||
"uv": [43, 33, 58, 43],
|
||||
"texture": 0
|
||||
},
|
||||
"west": {
|
||||
"uv": [29, 33, 43, 43],
|
||||
"texture": 0
|
||||
},
|
||||
"up": {
|
||||
"uv": [29, 33, 14, 19],
|
||||
"texture": 0
|
||||
},
|
||||
"down": {
|
||||
"uv": [44, 19, 29, 33],
|
||||
"texture": 0
|
||||
}
|
||||
},
|
||||
"uuid": "803e6dc7-ed11-6324-fd9f-3f22b1d809e8"
|
||||
},
|
||||
{
|
||||
"name": "lid_right",
|
||||
"from": [-7, -14, -7],
|
||||
"to": [8, -9, 7],
|
||||
"rotation": [-180, 0, 0],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [14, 14, 29, 19],
|
||||
"texture": 0
|
||||
},
|
||||
"east": {
|
||||
"uv": [0, 14, 14, 19],
|
||||
"texture": 0
|
||||
},
|
||||
"south": {
|
||||
"uv": [43, 14, 58, 19],
|
||||
"texture": 0
|
||||
},
|
||||
"west": {
|
||||
"uv": [29, 14, 43, 19],
|
||||
"texture": 0
|
||||
},
|
||||
"up": {
|
||||
"uv": [29, 14, 14, 0],
|
||||
"texture": 0
|
||||
},
|
||||
"down": {
|
||||
"uv": [44, 0, 29, 14],
|
||||
"texture": 0
|
||||
}
|
||||
},
|
||||
"uuid": "5fdcaa6f-15bd-6696-9e45-a7a4143b40d6"
|
||||
},
|
||||
{
|
||||
"name": "lock_right",
|
||||
"from": [-8, -11, -8],
|
||||
"to": [-7, -7, -7],
|
||||
"rotation": [0, 0, -180],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [1, 1, 2, 5],
|
||||
"texture": 0
|
||||
},
|
||||
"east": {
|
||||
"uv": [0, 1, 1, 5],
|
||||
"texture": 0
|
||||
},
|
||||
"south": {
|
||||
"uv": [3, 1, 4, 5],
|
||||
"texture": 0
|
||||
},
|
||||
"west": {
|
||||
"uv": [2, 1, 3, 5],
|
||||
"texture": 0
|
||||
},
|
||||
"up": {
|
||||
"uv": [2, 1, 1, 0],
|
||||
"texture": 0
|
||||
},
|
||||
"down": {
|
||||
"uv": [3, 0, 2, 1],
|
||||
"texture": 0
|
||||
}
|
||||
},
|
||||
"uuid": "1fdffae9-b046-1951-ff2a-fd3f30db2514"
|
||||
}
|
||||
],
|
||||
"outliner": [
|
||||
{
|
||||
"name": "root",
|
||||
"origin": [8, 8, 8],
|
||||
"uuid": "17d8814a-c29f-abdc-4f4a-c9b07cd032df",
|
||||
"children": [
|
||||
"76801e5b-8a1b-0a5d-c258-beef5dbc79ee",
|
||||
"803e6dc7-ed11-6324-fd9f-3f22b1d809e8",
|
||||
{
|
||||
"name": "lid",
|
||||
"origin": [0, 10, 7],
|
||||
"uuid": "c9b45550-2e8b-af52-a981-4aedc81fb456",
|
||||
"children": ["01d53de6-eeef-3c77-dd07-6f6d52b0527b", "5fdcaa6f-15bd-6696-9e45-a7a4143b40d6", "3cc1a7d6-4cf0-42bc-032f-1b3a602ca1f6", "1fdffae9-b046-1951-ff2a-fd3f30db2514"]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"textures": [
|
||||
{
|
||||
"path": "entity/chest/normal_left",
|
||||
"name": "normal_left",
|
||||
"namespace": "minecraft",
|
||||
"id": 0,
|
||||
"uuid": "9038a773-2512-f607-b2da-58c3649228ad"
|
||||
},
|
||||
{
|
||||
"path": "entity/chest/normal_right",
|
||||
"name": "normal_right",
|
||||
"namespace": "minecraft",
|
||||
"id": 1,
|
||||
"uuid": "dbef04c5-267c-2d45-5fcb-190a93892a20"
|
||||
}
|
||||
],
|
||||
"animations": [
|
||||
{
|
||||
"uuid": "d951b58f-d87c-519b-c3a7-22db3d46871c",
|
||||
"name": "animation.chest.opening",
|
||||
"loop": "hold",
|
||||
"length": 0.3,
|
||||
"animators": {
|
||||
"c9b45550-2e8b-af52-a981-4aedc81fb456": {
|
||||
"name": "lid",
|
||||
"type": "bone",
|
||||
"keyframes": [
|
||||
{
|
||||
"channel": "rotation",
|
||||
"data_points": [
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
}
|
||||
],
|
||||
"uuid": "d595c66b-58da-743a-223e-baff1a2910f1",
|
||||
"time": 0,
|
||||
"color": -1,
|
||||
"interpolation": "sine"
|
||||
},
|
||||
{
|
||||
"channel": "rotation",
|
||||
"data_points": [
|
||||
{
|
||||
"x": -90,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
}
|
||||
],
|
||||
"uuid": "ac945fe7-65b4-1f09-dc05-782860c4aa7c",
|
||||
"time": 0.3,
|
||||
"interpolation": "sine"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "581b97d7-b54c-456f-e91e-7b619572a530",
|
||||
"name": "animation.chest.closing",
|
||||
"loop": "hold",
|
||||
"length": 0.5,
|
||||
"animators": {
|
||||
"c9b45550-2e8b-af52-a981-4aedc81fb456": {
|
||||
"name": "lid",
|
||||
"type": "bone",
|
||||
"keyframes": [
|
||||
{
|
||||
"channel": "rotation",
|
||||
"data_points": [
|
||||
{
|
||||
"x": -90,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
}
|
||||
],
|
||||
"uuid": "ac945fe7-65b4-1f09-dc05-782860c4aa7c",
|
||||
"time": 0,
|
||||
"interpolation": "sine"
|
||||
},
|
||||
{
|
||||
"channel": "rotation",
|
||||
"data_points": [
|
||||
{
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
}
|
||||
],
|
||||
"uuid": "8ef02eb5-7b0c-462d-42ab-cce77b9a4497",
|
||||
"time": 0.5,
|
||||
"interpolation": "sine"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -133,7 +133,7 @@
|
||||
"path": "entity/chest/normal",
|
||||
"name": "normal",
|
||||
"namespace": "minecraft",
|
||||
"id": "0",
|
||||
"id": 0,
|
||||
"render_mode": "normal",
|
||||
"uuid": "9038a773-2512-f607-b2da-58c3649228ad"
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user