mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-14 09:56:37 -04:00
wip skeletal drawing
This commit is contained in:
parent
3159f3dab5
commit
7f78cc1f86
@ -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())))))
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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()})..." }
|
||||
|
@ -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,
|
||||
) {
|
||||
|
||||
|
@ -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,
|
||||
) {
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user