From 442fcb6c5b91def1cab21f91d99f27befc9a5470 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 3 Jun 2023 18:29:04 +0300 Subject: [PATCH] Use KMath-geometry for solids --- .../kscience/visionforge/gdml/gdmlLoader.kt | 1 + .../space/kscience/visionforge/solid/Solid.kt | 42 ++++++++++++------- .../solid/transform/RemoveSingleChild.kt | 6 +-- .../visionforge/solid/three/ThreeFactory.kt | 10 ++--- 4 files changed, 35 insertions(+), 24 deletions(-) diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt index e17248ad..230af4b0 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt @@ -6,6 +6,7 @@ import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus import space.kscience.gdml.* +import space.kscience.kmath.geometry.RotationOrder import space.kscience.visionforge.* import space.kscience.visionforge.html.VisionOutput import space.kscience.visionforge.solid.* diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index 8bd64336..e0140fe4 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -8,6 +8,10 @@ import space.kscience.dataforge.meta.descriptors.value import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus +import space.kscience.kmath.complex.Quaternion +import space.kscience.kmath.geometry.RotationOrder +import space.kscience.kmath.geometry.fromEuler +import space.kscience.kmath.geometry.radians import space.kscience.visionforge.* import space.kscience.visionforge.Vision.Companion.VISIBLE_KEY import space.kscience.visionforge.solid.Solid.Companion.DETAIL_KEY @@ -122,15 +126,6 @@ public var Solid.layer: Int // Common properties -public enum class RotationOrder { - XYZ, - YZX, - ZXY, - XZY, - YXZ, - ZYX -} - /** * Rotation order */ @@ -211,25 +206,42 @@ public var Solid.rotationX: Number by float(X_ROTATION_KEY, 0f) public var Solid.rotationY: Number by float(Y_ROTATION_KEY, 0f) public var Solid.rotationZ: Number by float(Z_ROTATION_KEY, 0f) -public var Solid.quaternion: Pair? +/** + * Raw quaternion value defined in properties + */ +public var Solid.quaternionValue: Quaternion? get() = properties.getValue(Solid.QUATERNION_KEY)?.list?.let { require(it.size == 4) { "Quaternion must be a number array of 4 elements" } - it[0].float to Float32Vector3D(it[1].float, it[2].float, it[3].float) + Quaternion(it[0].float, it[1].float, it[2].float, it[3].float) } set(value) { properties.setValue( Solid.QUATERNION_KEY, value?.let { ListValue( - value.first, - value.second.x, - value.second.y, - value.second.z + value.w, + value.x, + value.y, + value.z ) } ) } +/** + * Quaternion value including information from euler angles + */ +public var Solid.quaternion: Quaternion + get() = quaternionValue ?: Quaternion.fromEuler( + rotationX.radians, + rotationY.radians, + rotationZ.radians, + rotationOrder + ) + set(value) { + quaternionValue = value + } + //public var Solid.quaternion: Quaternion? // get() = meta[Solid::quaternion.name]?.value?.doubleArray?.let { Quaternion(it) } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt index 6a309d94..d2667e76 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt @@ -3,6 +3,7 @@ package space.kscience.visionforge.solid.transform import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName +import space.kscience.kmath.complex.QuaternionField import space.kscience.visionforge.root import space.kscience.visionforge.solid.* @@ -14,10 +15,7 @@ internal fun Solid.updateFrom(other: Solid): Solid { x += other.x y += other.y z += other.y - if(quaternion != null || other.quaternion != null) TODO("Quaternion support not implemented") - rotationX += other.rotationX - rotationY += other.rotationY - rotationZ += other.rotationZ + quaternion = with(QuaternionField) { other.quaternion * quaternion } scaleX *= other.scaleX scaleY *= other.scaleY scaleZ *= other.scaleZ diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt index a0852c72..ec42a3c7 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt @@ -49,15 +49,15 @@ public fun Object3D.updatePosition(vision: Vision) { // } else { // setRotationFromEuler( Euler(obj.rotationX, obj.rotationY, obj.rotationZ, obj.rotationOrder.name)) // } - val quaternion = vision.quaternion + val quaternion = vision.quaternionValue if (quaternion != null) { setRotationFromQuaternion( Quaternion( - quaternion.second.x, - quaternion.second.y, - quaternion.second.z, - quaternion.first + quaternion.x, + quaternion.y, + quaternion.z, + quaternion.w ) ) } else {