From 75540a078f70d5e5d4b7d3811791994c4bd6ffe7 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 21 Aug 2022 17:21:36 +0300 Subject: [PATCH] Add quaternion support --- .../visionforge/html/HtmlVisionContext.kt | 8 ++++---- .../kscience/visionforge/solid/FX3DPlugin.kt | 2 ++ .../space/kscience/visionforge/solid/Solid.kt | 20 +++++++++++++++++++ .../solid/transform/RemoveSingleChild.kt | 1 + .../visionforge/solid/three/ThreeFactory.kt | 15 +++++++++++++- 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt index 513676d4..007658b1 100644 --- a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt @@ -34,11 +34,11 @@ public interface HtmlVisionContext : ContextAware { public typealias HtmlVisionContextFragment = context(HtmlVisionContext) TagConsumer<*>.() -> Unit -context(HtmlVisionContext) - public fun HtmlVisionContextFragment(content: TagConsumer<*>.() -> Unit): HtmlVisionFragment = content +context(HtmlVisionContext) public fun HtmlVisionFragment( + content: TagConsumer<*>.() -> Unit +): HtmlVisionFragment = content -context(HtmlVisionContext) - private fun TagConsumer.vision( +context(HtmlVisionContext) private fun TagConsumer.vision( visionManager: VisionManager, name: Name, vision: Vision, diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt index 8a0abcdb..990b0b54 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt @@ -97,6 +97,8 @@ public class FX3DPlugin : AbstractPlugin() { scaleYProperty().bind(binding[Solid.Y_SCALE_KEY].float(obj.scaleY.toFloat())) scaleZProperty().bind(binding[Solid.Z_SCALE_KEY].float(obj.scaleZ.toFloat())) + if(obj.quaternion!= null) TODO("Quaternion support not implemented") + val rotateX = Rotate(0.0, Rotate.X_AXIS).apply { angleProperty().bind(binding[Solid.X_ROTATION_KEY].float(obj.rotationX.toFloat()).multiply(180.0 / PI)) } 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 5585a970..b87f0c93 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 @@ -203,6 +203,26 @@ 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? + 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 Point3D(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 + ) + } + ) + } + + //public var Solid.quaternion: Quaternion? // get() = meta[Solid::quaternion.name]?.value?.doubleArray?.let { Quaternion(it) } // set(value) { 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 d1e6fe5a..6a309d94 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 @@ -14,6 +14,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 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 cf42c139..a0852c72 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 @@ -11,6 +11,7 @@ import space.kscience.visionforge.visible import three.core.BufferGeometry import three.core.Object3D import three.math.Euler +import three.math.Quaternion import kotlin.reflect.KClass /** @@ -48,8 +49,20 @@ public fun Object3D.updatePosition(vision: Vision) { // } else { // setRotationFromEuler( Euler(obj.rotationX, obj.rotationY, obj.rotationZ, obj.rotationOrder.name)) // } + val quaternion = vision.quaternion - setRotationFromEuler(Euler(vision.rotationX, vision.rotationY, vision.rotationZ, vision.rotationOrder.name)) + if (quaternion != null) { + setRotationFromQuaternion( + Quaternion( + quaternion.second.x, + quaternion.second.y, + quaternion.second.z, + quaternion.first + ) + ) + } else { + setRotationFromEuler(Euler(vision.rotationX, vision.rotationY, vision.rotationZ, vision.rotationOrder.name)) + } scale.set(vision.scaleX, vision.scaleY, vision.scaleZ) updateMatrix()