wip skeletal drawing

This commit is contained in:
Moritz Zwerger 2023-10-16 17:08:17 +02:00
parent 3159f3dab5
commit 7f78cc1f86
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
15 changed files with 117 additions and 41 deletions

View File

@ -85,6 +85,6 @@ class SkeletalLoaderTest {
val baked = loader[dummyModel]!!
assertEquals(baked.transforms, mapOf("body" to BakedSkeletalTransform(1, Vec3(0.0, 0.5, 0.0), mapOf("head" to BakedSkeletalTransform(2, Vec3(0.0, 1.0, 0.0), emptyMap())))))
assertEquals(baked.transform.children, mapOf("body" to BakedSkeletalTransform(1, Vec3(0.0, 0.5, 0.0), mapOf("head" to BakedSkeletalTransform(2, Vec3(0.0, 1.0, 0.0), emptyMap())))))
}
}

View File

@ -13,11 +13,10 @@
package de.bixilon.minosoft.data.direction
import de.bixilon.kotlinglm.func.rad
import de.bixilon.kotlinglm.mat4x4.Mat4
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.kutil.array.ArrayUtil
import de.bixilon.minosoft.data.Axes
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3Util.EMPTY
object DirectionUtil {
@ -39,14 +38,7 @@ object DirectionUtil {
return Directions.INDEXED[1][ArrayUtil.modifyArrayIndex(index.y + count, Directions.SIZE_SIDES)]
}
fun rotateMatrix(direction: Directions): Mat4 {
return when (direction) {
Directions.DOWN -> Mat4().translateAssign(Vec3(0.5f)).rotateAssign(180.0f.rad, Vec3(1, 0, 0)).translateAssign(Vec3(-0.5f))
Directions.UP -> Mat4().translateAssign(Vec3(0.5f)).rotateAssign((-180.0f).rad, Vec3(1, 0, 0)).translateAssign(Vec3(-0.5f)) // ToDo
Directions.NORTH -> Mat4()
Directions.SOUTH -> Mat4().translateAssign(Vec3(0.5f)).rotateAssign(180.0f.rad, Vec3(0, 1, 0)).translateAssign(Vec3(-0.5f))
Directions.WEST -> Mat4().translateAssign(Vec3(0.5f)).rotateAssign((-270.0f).rad, Vec3(0, 1, 0)).translateAssign(Vec3(-0.5f))
Directions.EAST -> Mat4().translateAssign(Vec3(0.5f)).rotateAssign((-90.0f).rad, Vec3(0, 1, 0)).translateAssign(Vec3(-0.5f))
}
fun getRotation(direction: Directions): Vec3 {
return Vec3.EMPTY // TODO
}
}

View File

@ -12,7 +12,6 @@
*/
package de.bixilon.minosoft.data.direction
import de.bixilon.kotlinglm.mat4x4.Mat4
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.kotlinglm.vec3.Vec3i
@ -46,7 +45,7 @@ enum class Directions(
val vectord = Vec3d(vector)
val axis: Axes = unsafeNull()
val rotatedMatrix: Mat4 = unsafeNull()
val rotation: Vec3 = unsafeNull()
val inverted: Directions = unsafeNull()
private fun invert(): Directions {
@ -170,14 +169,13 @@ enum class Directions(
return minDirection
}
init {
val rotationMatrix = Directions::rotatedMatrix.javaField!!
val rotation = Directions::rotation.javaField!!
val inverted = Directions::inverted.javaField!!
val axis = Directions::axis.javaField!!
for (direction in VALUES) {
inverted.forceSet(direction, direction.invert())
rotationMatrix.forceSet(direction, DirectionUtil.rotateMatrix(direction))
rotation.forceSet(direction, DirectionUtil.getRotation(direction))
axis.forceSet(direction, Axes[direction])
}
NAME_MAP.unsafeCast<MutableMap<String, Directions>>()["bottom"] = DOWN

View File

@ -104,6 +104,7 @@ object RenderLoader {
Log.log(LogMessageType.RENDERING, LogLevels.VERBOSE) { "Baking models (after ${stopwatch.labTime()})..." }
font.postInit(renderLatch)
models.bake(renderLatch)
models.upload()
models.cleanup()
Log.log(LogMessageType.RENDERING, LogLevels.VERBOSE) { "Post loading renderer (after ${stopwatch.labTime()})..." }

View File

@ -37,7 +37,7 @@ class DoubleChestRenderer(
light: Int,
) : StorageBlockEntityRenderer<StorageBlockEntity>(
blockState,
model.createInstance(context, (blockPosition - context.camera.offset.offset).toVec3, (blockState.getFacing()).rotatedMatrix),
model.createInstance(context, (blockPosition - context.camera.offset.offset).toVec3, (blockState.getFacing()).rotation),
light,
) {

View File

@ -37,7 +37,7 @@ class SingleChestRenderer(
light: Int,
) : StorageBlockEntityRenderer<StorageBlockEntity>(
blockState,
model.createInstance(context, (blockPosition - context.camera.offset.offset).toVec3, blockState.getFacing().rotatedMatrix),
model.createInstance(context, (blockPosition - context.camera.offset.offset).toVec3, blockState.getFacing().rotation),
light,
) {

View File

@ -60,6 +60,10 @@ class ModelLoader(
Log.log(LogMessageType.LOADING, LogLevels.VERBOSE) { "Baked models in ${time.formatNanos()}!" }
}
fun upload() {
skeletal.upload()
}
fun cleanup() {
block.cleanup()
item.cleanup()

View File

@ -46,6 +46,12 @@ class SkeletalLoader(private val loader: ModelLoader) {
}
}
fun upload() {
for ((name, baked) in this.baked) {
baked.load()
}
}
fun cleanup() {
this::registered.forceSet(null)
}

View File

@ -46,20 +46,15 @@ class SkeletalManager(
fun draw(instance: SkeletalInstance, light: Int) {
prepareDraw()
shader.light = light
// val transforms = instance.calculateTransforms()
// var stride = 0
// for (transform in transforms) {
// for (float in transform.array) {
// uniformBuffer.buffer.put(stride++, float)
// }
// }
// uniformBuffer.upload(0 until (transforms.size * MAT4_SIZE))
instance.transform.pack(uniformBuffer.buffer)
uniformBuffer.upload(0 until instance.model.transformCount * MAT4_SIZE)
instance.model.mesh.draw()
}
private companion object {
companion object {
private const val TRANSFORMS = 128
private const val MAT4_SIZE = 4 * 4
const val MAT4_SIZE = 4 * 4
}
}

View File

@ -1,6 +1,6 @@
/*
* 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.
*
@ -23,7 +23,7 @@ import de.bixilon.minosoft.gui.rendering.system.base.buffer.uniform.FloatUniform
import de.bixilon.minosoft.gui.rendering.system.base.shader.NativeShader
import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureManager
class SkeletalShader(
open class SkeletalShader(
override val native: NativeShader,
buffer: FloatUniformBuffer,
) : Shader(), TextureShader, AnimatedShader, LightShader, ViewProjectionShader, FogShader {

View File

@ -13,7 +13,6 @@
package de.bixilon.minosoft.gui.rendering.skeletal.baked
import de.bixilon.kotlinglm.mat4x4.Mat4
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalMesh
@ -21,7 +20,8 @@ import de.bixilon.minosoft.gui.rendering.skeletal.instance.SkeletalInstance
data class BakedSkeletalModel(
val mesh: SkeletalMesh,
val transforms: MutableMap<String, BakedSkeletalTransform>,
val transform: BakedSkeletalTransform,
val transformCount: Int,
// TODO: animations
) {
private var state = SkeletalModelStates.DECLARED
@ -39,7 +39,13 @@ data class BakedSkeletalModel(
state = SkeletalModelStates.UNLOADED
}
fun createInstance(context: RenderContext, position: Vec3, transform: Mat4 = Mat4()): SkeletalInstance {
TODO()
fun createInstance(context: RenderContext, position: Vec3, rotation: Vec3): SkeletalInstance {
val transforms = this.transform.instance()
val instance = SkeletalInstance(context, this, transforms)
instance.update(position, rotation)
return instance
}
}

View File

@ -14,9 +14,21 @@
package de.bixilon.minosoft.gui.rendering.skeletal.baked
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.gui.rendering.skeletal.instance.TransformInstance
data class BakedSkeletalTransform(
val id: Int,
val pivot: Vec3,
val children: Map<String, BakedSkeletalTransform>,
)
) {
fun instance(): TransformInstance {
val children: MutableMap<String, TransformInstance> = mutableMapOf()
for ((name, child) in this.children) {
children[name] = child.instance()
}
return TransformInstance(id, pivot, children)
}
}

View File

@ -13,18 +13,42 @@
package de.bixilon.minosoft.gui.rendering.skeletal.instance
import de.bixilon.kotlinglm.mat4x4.Mat4
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.gui.rendering.RenderContext
import de.bixilon.minosoft.gui.rendering.shader.Shader
import de.bixilon.minosoft.gui.rendering.skeletal.baked.BakedSkeletalModel
class SkeletalInstance(
val context: RenderContext,
val model: BakedSkeletalModel,
val transform: TransformInstance,
) {
var light = 0xFF
fun draw(light: Int = 0xFF) {
fun draw() {
context.skeletal.draw(this, light)
}
fun draw(light: Int) {
this.light = light
context.skeletal.draw(this, light)
}
fun draw(shader: Shader) {
TODO()
}
fun draw(shader: Shader? = null) {
TODO()
fun update(position: Vec3, rotation: Vec3) {
val matrix = Mat4()
.translateAssign(Vec3(position - context.camera.offset.offset))
// .rotateAssign((EntityRotation.HALF_CIRCLE_DEGREE - yaw).rad, Y_ROTATION_VECTOR)
transform.value = matrix
}
companion object {
private val Y_ROTATION_VECTOR = Vec3(0, 1, 0)
}
}

View File

@ -0,0 +1,37 @@
/*
* 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.skeletal.instance
import de.bixilon.kotlinglm.mat4x4.Mat4
import de.bixilon.kotlinglm.vec3.Vec3
import de.bixilon.minosoft.gui.rendering.skeletal.SkeletalManager
import java.nio.FloatBuffer
class TransformInstance(
val id: Int,
val pivot: Vec3,
val children: Map<String, TransformInstance>,
) {
var value = Mat4()
fun pack(buffer: FloatBuffer) {
pack(buffer, value)
}
private fun pack(buffer: FloatBuffer, parent: Mat4) {
val value = parent * value
val offset = this.id * SkeletalManager.MAT4_SIZE
buffer.put(value.array, offset, SkeletalManager.MAT4_SIZE)
}
}

View File

@ -64,8 +64,9 @@ data class SkeletalModel(
val transforms: MutableMap<String, BakedSkeletalTransform> = mutableMapOf()
val transformId = AtomicInteger(1)
for ((name, transform) in this.transforms) {
transforms[name] = transform.bake(AtomicInteger(1))
transforms[name] = transform.bake(transformId)
}
val baseTransform = BakedSkeletalTransform(0, Vec3.EMPTY, transforms)
@ -73,6 +74,6 @@ data class SkeletalModel(
element.bake(mesh, textures, baseTransform)
}
return BakedSkeletalModel(mesh, transforms)
return BakedSkeletalModel(mesh, baseTransform, transformId.get())
}
}