From 8204eb63c3fd03b96462c4ea6d8126b34e2b0ad3 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 3 Jun 2023 20:49:57 +0300 Subject: [PATCH] Make threeJS object generation suspend --- .../visionforge/solid/demo/VariableBox.kt | 2 +- .../solid/three/ThreeAmbientLightFactory.kt | 2 +- .../visionforge/solid/three/ThreeCanvas.kt | 12 +++++++----- .../solid/three/ThreeCanvasLabelFactory.kt | 2 +- .../solid/three/ThreeCompositeFactory.kt | 2 +- .../visionforge/solid/three/ThreeFactory.kt | 10 +--------- .../visionforge/solid/three/ThreeJsVision.kt | 17 +++++++++++++++-- .../solid/three/ThreeLabelFactory.kt | 2 +- .../visionforge/solid/three/ThreeLineFactory.kt | 10 +++++----- .../visionforge/solid/three/ThreeMeshFactory.kt | 2 +- .../solid/three/ThreeMeshLineFactory.kt | 2 +- .../visionforge/solid/three/ThreePlugin.kt | 3 +-- .../solid/three/ThreePointLightFactory.kt | 2 +- .../solid/three/ThreeReferenceFactory.kt | 2 +- .../solid/three/ThreeSmartLineFactory.kt | 2 +- .../kscience/visionforge/solid/three/three.kt | 4 ---- 16 files changed, 39 insertions(+), 37 deletions(-) diff --git a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt index 15e53129..701df81b 100644 --- a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt +++ b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt @@ -25,7 +25,7 @@ internal fun SolidGroup.varBox( internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision() { - override fun render(three: ThreePlugin): Object3D { + override suspend fun render(three: ThreePlugin): Object3D { val geometry = BoxGeometry(xSize, ySize, 1) val material = ThreeMaterials.DEFAULT.clone() diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt index 3f8e251c..f15f2c78 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt @@ -14,7 +14,7 @@ import kotlin.reflect.KClass public object ThreeAmbientLightFactory : ThreeFactory { override val type: KClass get() = AmbientLightSource::class - override fun build(three: ThreePlugin, vision: AmbientLightSource, observe: Boolean): AmbientLight { + override suspend fun build(three: ThreePlugin, vision: AmbientLightSource, observe: Boolean): AmbientLight { val res = AmbientLight().apply { color = vision.color.threeColor() ?: Color(0x404040) intensity = vision.intensity.toDouble() diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt index 4e6935a8..6ecdad78 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt @@ -1,6 +1,7 @@ package space.kscience.visionforge.solid.three import kotlinx.browser.window +import kotlinx.coroutines.launch import org.w3c.dom.Element import org.w3c.dom.HTMLCanvasElement import org.w3c.dom.Node @@ -264,11 +265,12 @@ public class ThreeCanvas( scene.findChild("@root".asName())?.let { scene.remove(it) } root?.dispose() } - - val object3D = three.buildObject3D(vision) - object3D.name = "@root" - scene.add(object3D) - root = object3D + three.context.launch { + val object3D = three.buildObject3D(vision) + object3D.name = "@root" + scene.add(object3D) + root = object3D + } } private var selected: Object3D? = null diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt index b9f2a7d2..93bf170b 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt @@ -22,7 +22,7 @@ import kotlin.reflect.KClass public object ThreeCanvasLabelFactory : ThreeFactory { override val type: KClass get() = SolidLabel::class - override fun build(three: ThreePlugin, vision: SolidLabel, observe: Boolean): Object3D { + override suspend fun build(three: ThreePlugin, vision: SolidLabel, observe: Boolean): Object3D { val canvas = document.createElement("canvas") as HTMLCanvasElement canvas.width = 200 canvas.height = 200 diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt index fe40022d..e6e9641c 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt @@ -38,7 +38,7 @@ public class ThreeCompositeFactory(public val three: ThreePlugin) : ThreeFactory override val type: KClass get() = Composite::class - override fun build(three: ThreePlugin, vision: Composite, observe: Boolean): Mesh { + override suspend fun build(three: ThreePlugin, vision: Composite, observe: Boolean): Mesh { val first = three.buildObject3D(vision.first, observe).takeIfMesh() ?: error("First part of composite is not a mesh") val second = three.buildObject3D(vision.second, observe).takeIfMesh() 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 ec42a3c7..7c87a0f3 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 @@ -26,7 +26,7 @@ public interface ThreeFactory { * Build an [Object3D] from [vision]. * @param observe if false, does not observe the changes in [vision] after render (useful for statics). */ - public fun build(three: ThreePlugin, vision: T, observe: Boolean = true): Object3D + public suspend fun build(three: ThreePlugin, vision: T, observe: Boolean = true): Object3D public companion object { public const val TYPE: String = "threeFactory" @@ -41,14 +41,6 @@ public fun Object3D.updatePosition(vision: Vision) { if (vision is Solid) { position.set(vision.x, vision.y, vision.z) -// val quaternion = obj.quaternion -// -// if (quaternion != null) { -// val (x, y, z, w) = quaternion -// setRotationFromQuaternion(Quaternion(x, y, z, w)) -// } else { -// setRotationFromEuler( Euler(obj.rotationX, obj.rotationY, obj.rotationZ, obj.rotationOrder.name)) -// } val quaternion = vision.quaternionValue if (quaternion != null) { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt index 3829698e..dcb328a1 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt @@ -1,11 +1,24 @@ package space.kscience.visionforge.solid.three -import three.core.Object3D +import org.w3c.dom.url.URL import space.kscience.visionforge.solid.SolidBase +import three.core.Object3D /** * A custom visual object that has its own Three.js renderer */ public abstract class ThreeJsVision : SolidBase() { - public abstract fun render(three: ThreePlugin): Object3D + public abstract suspend fun render(three: ThreePlugin): Object3D +} + +public class ThreeStlVision(val url: URL): ThreeJsVision(){ + override suspend fun render(three: ThreePlugin): Object3D { +// suspendCoroutine { +// +// } +// STLLoader() + + TODO() + } + } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt index e168c1d2..45068a3a 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt @@ -17,7 +17,7 @@ import kotlin.reflect.KClass public object ThreeLabelFactory : ThreeFactory { override val type: KClass get() = SolidLabel::class - override fun build(three: ThreePlugin, vision: SolidLabel, observe: Boolean): Object3D { + override suspend fun build(three: ThreePlugin, vision: SolidLabel, observe: Boolean): Object3D { val textGeo = TextBufferGeometry(vision.text, jso { font = vision.fontFamily size = 20 diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt index adf4ce0d..45325430 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt @@ -1,22 +1,22 @@ package space.kscience.visionforge.solid.three -import three.core.BufferGeometry -import three.core.Object3D -import three.math.Color -import three.objects.LineSegments import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.PolyLine import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.color import space.kscience.visionforge.solid.string import space.kscience.visionforge.solid.three.ThreeMaterials.DEFAULT_LINE_COLOR +import three.core.BufferGeometry +import three.core.Object3D +import three.math.Color +import three.objects.LineSegments import kotlin.math.ceil import kotlin.reflect.KClass public object ThreeLineFactory : ThreeFactory { override val type: KClass get() = PolyLine::class - override fun build(three: ThreePlugin, vision: PolyLine, observe: Boolean): Object3D { + override suspend fun build(three: ThreePlugin, vision: PolyLine, observe: Boolean): Object3D { val geometry = BufferGeometry().apply { setFromPoints(Array((vision.points.size - 1) * 2) { vision.points[ceil(it / 2.0).toInt()].toVector() diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt index 30f3034b..ab067326 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt @@ -26,7 +26,7 @@ public abstract class ThreeMeshFactory( */ public abstract fun buildGeometry(obj: T): BufferGeometry - override fun build(three: ThreePlugin, vision: T, observe: Boolean): Mesh { + override suspend fun build(three: ThreePlugin, vision: T, observe: Boolean): Mesh { val geometry = buildGeometry(vision) val mesh = Mesh(geometry, ThreeMaterials.DEFAULT).apply { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt index 3d9b4c3b..4a94823b 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt @@ -15,7 +15,7 @@ import kotlin.reflect.KClass public object ThreeMeshLineFactory : ThreeFactory { override val type: KClass get() = PolyLine::class - override fun build(three: ThreePlugin, vision: PolyLine, observe: Boolean): Object3D { + override suspend fun build(three: ThreePlugin, vision: PolyLine, observe: Boolean): Object3D { val geometry = MeshLine( Array((vision.points.size - 1) * 2) { vision.points[ceil(it / 2.0).toInt()].toVector() diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index 064597e6..17249648 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -6,7 +6,6 @@ import org.w3c.dom.Element import org.w3c.dom.HTMLElement import space.kscience.dataforge.context.* import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.update import space.kscience.dataforge.names.* import space.kscience.visionforge.ElementVisionRenderer import space.kscience.visionforge.Vision @@ -47,7 +46,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { as ThreeFactory? } - public fun buildObject3D(vision: Solid, observe: Boolean = true): Object3D = when (vision) { + public suspend fun buildObject3D(vision: Solid, observe: Boolean = true): Object3D = when (vision) { is ThreeJsVision -> vision.render(this) is SolidReference -> ThreeReferenceFactory.build(this, vision, observe) is SolidGroup -> { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt index fdd2e019..b0a0bfeb 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt @@ -13,7 +13,7 @@ public object ThreePointLightFactory : ThreeFactory { private val DEFAULT_COLOR = Color(0x404040) - override fun build(three: ThreePlugin, vision: PointLightSource, observe: Boolean): PointLight { + override suspend fun build(three: ThreePlugin, vision: PointLightSource, observe: Boolean): PointLight { val res = PointLight().apply { matrixAutoUpdate = false color = vision.color.threeColor() ?: DEFAULT_COLOR diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt index 405956f8..beb59df8 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt @@ -31,7 +31,7 @@ public object ThreeReferenceFactory : ThreeFactory { } } - override fun build(three: ThreePlugin, vision: SolidReference, observe: Boolean): Object3D { + override suspend fun build(three: ThreePlugin, vision: SolidReference, observe: Boolean): Object3D { val template = vision.prototype val cachedObject = cache.getOrPut(template) { three.buildObject3D(template) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt index 2e7329da..6f2ee1a5 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt @@ -7,7 +7,7 @@ import kotlin.reflect.KClass public object ThreeSmartLineFactory : ThreeFactory { override val type: KClass get() = PolyLine::class - override fun build(three: ThreePlugin, vision: PolyLine, observe: Boolean): Object3D { + override suspend fun build(three: ThreePlugin, vision: PolyLine, observe: Boolean): Object3D { return if (vision.thickness == 1.0) { ThreeLineFactory.build(three, vision, observe) } else { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt index 9c9d5b2b..f3fc0594 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt @@ -12,14 +12,10 @@ import three.math.Vector3 import three.objects.Mesh import three.textures.Texture import kotlin.contracts.contract -import kotlin.math.PI public val Meta.vector: Vector3 get() = Vector3(this["x"].float ?: 0f, this["y"].float ?: 0f, this["z"].float ?: 0f) -internal fun Double.toRadians() = this * PI / 180 - - internal fun Any.dispose() { when (this) { is BufferGeometry -> dispose()