Skip to content

Commit

Permalink
Merge branch 'main' into feature/vulkan
Browse files Browse the repository at this point in the history
  • Loading branch information
fabmax committed Jan 29, 2025
2 parents b07353b + 07d2999 commit c2bf234
Show file tree
Hide file tree
Showing 6 changed files with 225 additions and 91 deletions.
4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[versions]
agp = "8.2.0"
kotlin = "2.1.0"
kotlin = "2.1.10"
kotlin-coroutines = "1.10.1"
kotlin-serialization = "1.8.0"
kotlin-datetime = "0.6.1"
kotlin-atomicfu = "0.27.0"
kotlin-dokka = "2.0.0"
lwjgl = "3.3.6"
jsvg = "1.6.1"
jsvg = "1.7.0"
androidsvg = "1.4"
physxjni = "2.5.0"
physxjswebidl = "2.5.0"
Expand Down
64 changes: 51 additions & 13 deletions kool-core/src/commonMain/kotlin/de/fabmax/kool/math/Quat.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ package de.fabmax.kool.math

import de.fabmax.kool.util.Float32Buffer
import de.fabmax.kool.util.MixedBuffer
import kotlin.math.cos
import kotlin.math.sin
import kotlin.math.sqrt
import kotlin.math.*

fun QuatF.toQuatD() = QuatD(x.toDouble(), y.toDouble(), z.toDouble(), w.toDouble())
fun QuatF.toMutableQuatD(result: MutableQuatD = MutableQuatD()) = result.set(x.toDouble(), y.toDouble(), z.toDouble(), w.toDouble())
Expand Down Expand Up @@ -113,11 +111,31 @@ open class QuatF(open val x: Float, open val y: Float, open val z: Float, open v
* [MutableVec4f]: result = that * weight + this * (1 - weight).
*/
fun mix(that: QuatF, weight: Float, result: MutableQuatF = MutableQuatF()): MutableQuatF {
result.x = that.x * weight + x * (1f - weight)
result.y = that.y * weight + y * (1f - weight)
result.z = that.z * weight + z * (1f - weight)
result.w = that.w * weight + w * (1f - weight)
return result.norm()
val dot = x * that.x + y * that.y + z * that.z + w * that.w
val absCosom = abs(dot)

val scale0: Float
val scale1: Float

if (1.0f - absCosom > FUZZY_EQ_F) {
val sinSqr = 1.0f - absCosom * absCosom
val sinom = 1.0f / sqrt(sinSqr)
val omega = atan2(sqrt(sinSqr), absCosom)
scale0 = sin((1.0f - weight) * omega) * sinom
scale1 = sin(weight * omega) * sinom
} else {
scale0 = 1.0f - weight
scale1 = weight
}

val adjustedScale = if (dot >= 0.0f) scale1 else -scale1

result.x = scale0 * x + adjustedScale * that.x
result.y = scale0 * y + adjustedScale * that.y
result.z = scale0 * z + adjustedScale * that.z
result.w = scale0 * w + adjustedScale * that.w

return result
}

/**
Expand Down Expand Up @@ -434,11 +452,31 @@ open class QuatD(open val x: Double, open val y: Double, open val z: Double, ope
* [MutableVec4d]: result = that * weight + this * (1 - weight).
*/
fun mix(that: QuatD, weight: Double, result: MutableQuatD = MutableQuatD()): MutableQuatD {
result.x = that.x * weight + x * (1.0 - weight)
result.y = that.y * weight + y * (1.0 - weight)
result.z = that.z * weight + z * (1.0 - weight)
result.w = that.w * weight + w * (1.0 - weight)
return result.norm()
val dot = x * that.x + y * that.y + z * that.z + w * that.w
val absCosom = abs(dot)

val scale0: Double
val scale1: Double

if (1.0 - absCosom > FUZZY_EQ_D) {
val sinSqr = 1.0 - absCosom * absCosom
val sinom = 1.0 / sqrt(sinSqr)
val omega = atan2(sqrt(sinSqr), absCosom)
scale0 = sin((1.0 - weight) * omega) * sinom
scale1 = sin(weight * omega) * sinom
} else {
scale0 = 1.0 - weight
scale1 = weight
}

val adjustedScale = if (dot >= 0.0) scale1 else -scale1

result.x = scale0 * x + adjustedScale * that.x
result.y = scale0 * y + adjustedScale * that.y
result.z = scale0 * z + adjustedScale * that.z
result.w = scale0 * w + adjustedScale * that.w

return result
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ data class GltfFile(
val modelAnim = Animation(anim.name)
modelAnimations += modelAnim

val animNodes = mutableMapOf<Node, AnimationNode>()
val animNodes = mutableMapOf<Node, AnimatedTransformGroup>()
anim.channels.forEach { channel ->
val nodeGrp = modelNodes[channel.target.nodeRef]
if (nodeGrp != null) {
Expand All @@ -240,7 +240,7 @@ data class GltfFile(
}
}

private fun makeTranslationAnimation(animCh: GltfAnimation.Channel, animNd: AnimationNode, modelAnim: Animation) {
private fun makeTranslationAnimation(animCh: GltfAnimation.Channel, animNd: AnimatedTransformGroup, modelAnim: Animation) {
val inputAcc = animCh.samplerRef.inputAccessorRef
val outputAcc = animCh.samplerRef.outputAccessorRef

Expand All @@ -261,6 +261,7 @@ data class GltfFile(
}
modelAnim.channels += transChannel

val bindTranslation = animNd.initTranslation
val inTime = FloatAccessor(inputAcc)
val outTranslation = Vec3fAccessor(outputAcc)
for (i in 0 until min(inputAcc.count, outputAcc.count)) {
Expand All @@ -269,16 +270,21 @@ data class GltfFile(
val startTan = outTranslation.next()
val point = outTranslation.next()
val endTan = outTranslation.next()
CubicTranslationKey(t, point, startTan, endTan)
CubicTranslationKey(
t,
point - bindTranslation,
startTan - bindTranslation,
endTan - bindTranslation
)
} else {
TranslationKey(t, outTranslation.next())
TranslationKey(t, outTranslation.next() - bindTranslation)
}
transKey.interpolation = interpolation
transChannel.keys[t] = transKey
}
}

private fun makeRotationAnimation(animCh: GltfAnimation.Channel, animNd: AnimationNode, modelAnim: Animation) {
private fun makeRotationAnimation(animCh: GltfAnimation.Channel, animNd: AnimatedTransformGroup, modelAnim: Animation) {
val inputAcc = animCh.samplerRef.inputAccessorRef
val outputAcc = animCh.samplerRef.outputAccessorRef

Expand All @@ -299,6 +305,7 @@ data class GltfFile(
}
modelAnim.channels += rotChannel

val bindRotation = animNd.initRotation
val inTime = FloatAccessor(inputAcc)
val outRotation = Vec4fAccessor(outputAcc)
for (i in 0 until min(inputAcc.count, outputAcc.count)) {
Expand All @@ -307,16 +314,21 @@ data class GltfFile(
val startTan = outRotation.next().toQuatF()
val point = outRotation.next().toQuatF()
val endTan = outRotation.next().toQuatF()
CubicRotationKey(t, point, startTan, endTan)
CubicRotationKey(
t,
bindRotation.inverted().mul(point),
bindRotation.inverted().mul(startTan),
bindRotation.inverted().mul(endTan)
)
} else {
RotationKey(t, outRotation.next().toQuatF())
RotationKey(t, bindRotation.inverted().mul(outRotation.next().toQuatF()))
}
rotKey.interpolation = interpolation
rotChannel.keys[t] = rotKey
}
}

private fun makeScaleAnimation(animCh: GltfAnimation.Channel, animNd: AnimationNode, modelAnim: Animation) {
private fun makeScaleAnimation(animCh: GltfAnimation.Channel, animNd: AnimatedTransformGroup, modelAnim: Animation) {
val inputAcc = animCh.samplerRef.inputAccessorRef
val outputAcc = animCh.samplerRef.outputAccessorRef

Expand All @@ -337,6 +349,7 @@ data class GltfFile(
}
modelAnim.channels += scaleChannel

val bindScale = animNd.initScale
val inTime = FloatAccessor(inputAcc)
val outScale = Vec3fAccessor(outputAcc)
for (i in 0 until min(inputAcc.count, outputAcc.count)) {
Expand All @@ -345,9 +358,9 @@ data class GltfFile(
val startTan = outScale.next()
val point = outScale.next()
val endTan = outScale.next()
CubicScaleKey(t, point, startTan, endTan)
CubicScaleKey(t, bindScale / point, bindScale / startTan, bindScale / endTan)
} else {
ScaleKey(t, outScale.next())
ScaleKey(t, bindScale / outScale.next())
}
scaleKey.interpolation = interpolation
scaleChannel.keys[t] = scaleKey
Expand Down
4 changes: 4 additions & 0 deletions kool-core/src/commonMain/kotlin/de/fabmax/kool/scene/Model.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ class Model(name: String? = null) : Node(name) {
}

fun applyAnimation(deltaT: Float) {
for (i in animations.indices) {
animations[i].reset()
}

var firstActive = true
for (i in animations.indices) {
if (animations[i].weight > 0f) {
Expand Down
Loading

0 comments on commit c2bf234

Please sign in to comment.