Make threeJS object generation suspend
This commit is contained in:
parent
442fcb6c5b
commit
8204eb63c3
@ -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()
|
||||
|
@ -14,7 +14,7 @@ import kotlin.reflect.KClass
|
||||
public object ThreeAmbientLightFactory : ThreeFactory<AmbientLightSource> {
|
||||
override val type: KClass<in AmbientLightSource> 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()
|
||||
|
@ -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,12 +265,13 @@ public class ThreeCanvas(
|
||||
scene.findChild("@root".asName())?.let { scene.remove(it) }
|
||||
root?.dispose()
|
||||
}
|
||||
|
||||
three.context.launch {
|
||||
val object3D = three.buildObject3D(vision)
|
||||
object3D.name = "@root"
|
||||
scene.add(object3D)
|
||||
root = object3D
|
||||
}
|
||||
}
|
||||
|
||||
private var selected: Object3D? = null
|
||||
|
||||
|
@ -22,7 +22,7 @@ import kotlin.reflect.KClass
|
||||
public object ThreeCanvasLabelFactory : ThreeFactory<SolidLabel> {
|
||||
override val type: KClass<in SolidLabel> 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
|
||||
|
@ -38,7 +38,7 @@ public class ThreeCompositeFactory(public val three: ThreePlugin) : ThreeFactory
|
||||
|
||||
override val type: KClass<in Composite> 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()
|
||||
|
@ -26,7 +26,7 @@ public interface ThreeFactory<in T : Vision> {
|
||||
* 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) {
|
||||
|
@ -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<ThreeJsVision>() {
|
||||
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()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import kotlin.reflect.KClass
|
||||
public object ThreeLabelFactory : ThreeFactory<SolidLabel> {
|
||||
override val type: KClass<in SolidLabel> 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
|
||||
|
@ -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<PolyLine> {
|
||||
override val type: KClass<PolyLine> 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()
|
||||
|
@ -26,7 +26,7 @@ public abstract class ThreeMeshFactory<in T : Solid>(
|
||||
*/
|
||||
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 {
|
||||
|
@ -15,7 +15,7 @@ import kotlin.reflect.KClass
|
||||
public object ThreeMeshLineFactory : ThreeFactory<PolyLine> {
|
||||
override val type: KClass<in PolyLine> 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()
|
||||
|
@ -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<Solid>?
|
||||
}
|
||||
|
||||
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 -> {
|
||||
|
@ -13,7 +13,7 @@ public object ThreePointLightFactory : ThreeFactory<PointLightSource> {
|
||||
|
||||
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
|
||||
|
@ -31,7 +31,7 @@ public object ThreeReferenceFactory : ThreeFactory<SolidReference> {
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -7,7 +7,7 @@ import kotlin.reflect.KClass
|
||||
public object ThreeSmartLineFactory : ThreeFactory<PolyLine> {
|
||||
override val type: KClass<in PolyLine> 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 {
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user