load skeletal models async

This commit is contained in:
Bixilon 2022-09-26 13:38:53 +02:00
parent f253c71f7a
commit 0eee704cdf
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
6 changed files with 63 additions and 17 deletions

View File

@ -189,10 +189,7 @@ class RenderWindow(
Log.log(LogMessageType.RENDERING_LOADING, LogLevels.VERBOSE) { "Loading skeletal meshes (after ${stopwatch.labTime()})" }
for (model in modelLoader.entities.skeletal.values) {
model.loadMesh(this)
}
modelLoader.entities.loadSkeletal()
Log.log(LogMessageType.RENDERING_LOADING, LogLevels.VERBOSE) { "Registering callbacks (after ${stopwatch.labTime()})..." }

View File

@ -15,6 +15,7 @@ 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) {
@ -24,7 +25,10 @@ abstract class SkeletalEntityModel<E : Entity>(renderer: EntityRenderer, entity:
override fun prepare() {
super.prepare()
instance.model.loadMesh(renderWindow)
if (instance.model.state != SkeletalModelStates.LOADED) {
instance.model.preload(renderWindow) // ToDo: load async
instance.model.load()
}
}
override fun draw() {

View File

@ -24,7 +24,6 @@ import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalMesh
import de.bixilon.minosoft.gui.rendering.skeletal.model.SkeletalModel
import de.bixilon.minosoft.gui.rendering.skeletal.model.outliner.SkeletalOutliner
import de.bixilon.minosoft.gui.rendering.system.base.texture.ShaderTexture
import de.bixilon.minosoft.gui.rendering.util.mesh.Mesh
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.rotateAssign
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap
@ -35,8 +34,8 @@ class BakedSkeletalModel(
val textures: Int2ObjectOpenHashMap<ShaderTexture>,
) {
lateinit var mesh: SkeletalMesh
val loaded: Boolean
get() = this::mesh.isInitialized && mesh.state == Mesh.MeshStates.LOADED
var state: SkeletalModelStates = SkeletalModelStates.DECLARED
private set
private fun calculateOutlinerMapping(): Map<UUID, Int> {
val mapping: Object2IntOpenHashMap<UUID> = Object2IntOpenHashMap()
@ -68,10 +67,8 @@ class BakedSkeletalModel(
return mapping
}
fun loadMesh(renderWindow: RenderWindow) {
if (loaded) {
return
}
fun preload(renderWindow: RenderWindow) {
check(state == SkeletalModelStates.DECLARED) { "Can not preload model in $state" }
val mesh = SkeletalMesh(renderWindow, 1000)
val outlinerMapping = calculateOutlinerMapping()
@ -118,14 +115,20 @@ class BakedSkeletalModel(
}
}
}
mesh.load()
this.mesh = mesh
state = SkeletalModelStates.PRE_LOADED
}
fun load() {
check(state == SkeletalModelStates.PRE_LOADED) { "Can not load model in state: $state" }
mesh.load()
state = SkeletalModelStates.LOADED
}
fun unload() {
if (loaded) {
mesh.unload()
}
check(state == SkeletalModelStates.LOADED) { "Can not unload model in state $state" }
mesh.unload()
state = SkeletalModelStates.UNLOADED
}
companion object {

View File

@ -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.skeletal.baked
enum class SkeletalModelStates {
DECLARED,
PRE_LOADED,
LOADED,
UNLOADED,
;
}

View File

@ -21,6 +21,7 @@ import de.bixilon.minosoft.data.entities.EntityRotation
import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.renderer.drawable.DeltaDrawable
import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel
import de.bixilon.minosoft.gui.rendering.skeletal.baked.SkeletalModelStates
import de.bixilon.minosoft.gui.rendering.skeletal.model.animations.SkeletalAnimation
import de.bixilon.minosoft.gui.rendering.skeletal.model.outliner.SkeletalOutliner
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
@ -137,6 +138,9 @@ class SkeletalInstance(
}
fun unload() {
model.unload()
val model = model
if (model.state == SkeletalModelStates.LOADED) {
model.unload()
}
}
}

View File

@ -13,6 +13,8 @@
package de.bixilon.minosoft.gui.rendering.world.entities
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.data.registries.ResourceLocation
import de.bixilon.minosoft.gui.rendering.RenderWindow
@ -37,4 +39,18 @@ class EntityModels(val renderWindow: RenderWindow) {
fun cleanup() {
unbakedModels.clear()
}
fun loadSkeletal() {
val latch = CountUpAndDownLatch(1)
for (model in skeletal.values) {
latch.inc()
DefaultThreadPool += { model.preload(renderWindow); latch.dec() }
}
latch.dec()
latch.await()
for (model in skeletal.values) {
model.load()
}
}
}