forked from kscience/visionforge
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() {
|
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 geometry = BoxGeometry(xSize, ySize, 1)
|
||||||
|
|
||||||
val material = ThreeMaterials.DEFAULT.clone()
|
val material = ThreeMaterials.DEFAULT.clone()
|
||||||
|
@ -14,7 +14,7 @@ import kotlin.reflect.KClass
|
|||||||
public object ThreeAmbientLightFactory : ThreeFactory<AmbientLightSource> {
|
public object ThreeAmbientLightFactory : ThreeFactory<AmbientLightSource> {
|
||||||
override val type: KClass<in AmbientLightSource> get() = AmbientLightSource::class
|
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 {
|
val res = AmbientLight().apply {
|
||||||
color = vision.color.threeColor() ?: Color(0x404040)
|
color = vision.color.threeColor() ?: Color(0x404040)
|
||||||
intensity = vision.intensity.toDouble()
|
intensity = vision.intensity.toDouble()
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package space.kscience.visionforge.solid.three
|
package space.kscience.visionforge.solid.three
|
||||||
|
|
||||||
import kotlinx.browser.window
|
import kotlinx.browser.window
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
import org.w3c.dom.HTMLCanvasElement
|
import org.w3c.dom.HTMLCanvasElement
|
||||||
import org.w3c.dom.Node
|
import org.w3c.dom.Node
|
||||||
@ -264,11 +265,12 @@ public class ThreeCanvas(
|
|||||||
scene.findChild("@root".asName())?.let { scene.remove(it) }
|
scene.findChild("@root".asName())?.let { scene.remove(it) }
|
||||||
root?.dispose()
|
root?.dispose()
|
||||||
}
|
}
|
||||||
|
three.context.launch {
|
||||||
val object3D = three.buildObject3D(vision)
|
val object3D = three.buildObject3D(vision)
|
||||||
object3D.name = "@root"
|
object3D.name = "@root"
|
||||||
scene.add(object3D)
|
scene.add(object3D)
|
||||||
root = object3D
|
root = object3D
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var selected: Object3D? = null
|
private var selected: Object3D? = null
|
||||||
|
@ -22,7 +22,7 @@ import kotlin.reflect.KClass
|
|||||||
public object ThreeCanvasLabelFactory : ThreeFactory<SolidLabel> {
|
public object ThreeCanvasLabelFactory : ThreeFactory<SolidLabel> {
|
||||||
override val type: KClass<in SolidLabel> get() = SolidLabel::class
|
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
|
val canvas = document.createElement("canvas") as HTMLCanvasElement
|
||||||
canvas.width = 200
|
canvas.width = 200
|
||||||
canvas.height = 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 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()
|
val first = three.buildObject3D(vision.first, observe).takeIfMesh()
|
||||||
?: error("First part of composite is not a mesh")
|
?: error("First part of composite is not a mesh")
|
||||||
val second = three.buildObject3D(vision.second, observe).takeIfMesh()
|
val second = three.buildObject3D(vision.second, observe).takeIfMesh()
|
||||||
|
@ -26,7 +26,7 @@ public interface ThreeFactory<in T : Vision> {
|
|||||||
* Build an [Object3D] from [vision].
|
* Build an [Object3D] from [vision].
|
||||||
* @param observe if false, does not observe the changes in [vision] after render (useful for statics).
|
* @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 companion object {
|
||||||
public const val TYPE: String = "threeFactory"
|
public const val TYPE: String = "threeFactory"
|
||||||
@ -41,14 +41,6 @@ public fun Object3D.updatePosition(vision: Vision) {
|
|||||||
if (vision is Solid) {
|
if (vision is Solid) {
|
||||||
position.set(vision.x, vision.y, vision.z)
|
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
|
val quaternion = vision.quaternionValue
|
||||||
|
|
||||||
if (quaternion != null) {
|
if (quaternion != null) {
|
||||||
|
@ -1,11 +1,24 @@
|
|||||||
package space.kscience.visionforge.solid.three
|
package space.kscience.visionforge.solid.three
|
||||||
|
|
||||||
import three.core.Object3D
|
import org.w3c.dom.url.URL
|
||||||
import space.kscience.visionforge.solid.SolidBase
|
import space.kscience.visionforge.solid.SolidBase
|
||||||
|
import three.core.Object3D
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A custom visual object that has its own Three.js renderer
|
* A custom visual object that has its own Three.js renderer
|
||||||
*/
|
*/
|
||||||
public abstract class ThreeJsVision : SolidBase<ThreeJsVision>() {
|
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> {
|
public object ThreeLabelFactory : ThreeFactory<SolidLabel> {
|
||||||
override val type: KClass<in SolidLabel> get() = SolidLabel::class
|
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 {
|
val textGeo = TextBufferGeometry(vision.text, jso {
|
||||||
font = vision.fontFamily
|
font = vision.fontFamily
|
||||||
size = 20
|
size = 20
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
package space.kscience.visionforge.solid.three
|
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.onPropertyChange
|
||||||
import space.kscience.visionforge.solid.PolyLine
|
import space.kscience.visionforge.solid.PolyLine
|
||||||
import space.kscience.visionforge.solid.SolidMaterial
|
import space.kscience.visionforge.solid.SolidMaterial
|
||||||
import space.kscience.visionforge.solid.color
|
import space.kscience.visionforge.solid.color
|
||||||
import space.kscience.visionforge.solid.string
|
import space.kscience.visionforge.solid.string
|
||||||
import space.kscience.visionforge.solid.three.ThreeMaterials.DEFAULT_LINE_COLOR
|
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.math.ceil
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
public object ThreeLineFactory : ThreeFactory<PolyLine> {
|
public object ThreeLineFactory : ThreeFactory<PolyLine> {
|
||||||
override val type: KClass<PolyLine> get() = PolyLine::class
|
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 {
|
val geometry = BufferGeometry().apply {
|
||||||
setFromPoints(Array((vision.points.size - 1) * 2) {
|
setFromPoints(Array((vision.points.size - 1) * 2) {
|
||||||
vision.points[ceil(it / 2.0).toInt()].toVector()
|
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
|
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 geometry = buildGeometry(vision)
|
||||||
|
|
||||||
val mesh = Mesh(geometry, ThreeMaterials.DEFAULT).apply {
|
val mesh = Mesh(geometry, ThreeMaterials.DEFAULT).apply {
|
||||||
|
@ -15,7 +15,7 @@ import kotlin.reflect.KClass
|
|||||||
public object ThreeMeshLineFactory : ThreeFactory<PolyLine> {
|
public object ThreeMeshLineFactory : ThreeFactory<PolyLine> {
|
||||||
override val type: KClass<in PolyLine> get() = PolyLine::class
|
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(
|
val geometry = MeshLine(
|
||||||
Array((vision.points.size - 1) * 2) {
|
Array((vision.points.size - 1) * 2) {
|
||||||
vision.points[ceil(it / 2.0).toInt()].toVector()
|
vision.points[ceil(it / 2.0).toInt()].toVector()
|
||||||
|
@ -6,7 +6,6 @@ import org.w3c.dom.Element
|
|||||||
import org.w3c.dom.HTMLElement
|
import org.w3c.dom.HTMLElement
|
||||||
import space.kscience.dataforge.context.*
|
import space.kscience.dataforge.context.*
|
||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
import space.kscience.dataforge.meta.update
|
|
||||||
import space.kscience.dataforge.names.*
|
import space.kscience.dataforge.names.*
|
||||||
import space.kscience.visionforge.ElementVisionRenderer
|
import space.kscience.visionforge.ElementVisionRenderer
|
||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
@ -47,7 +46,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
|
|||||||
as ThreeFactory<Solid>?
|
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 ThreeJsVision -> vision.render(this)
|
||||||
is SolidReference -> ThreeReferenceFactory.build(this, vision, observe)
|
is SolidReference -> ThreeReferenceFactory.build(this, vision, observe)
|
||||||
is SolidGroup -> {
|
is SolidGroup -> {
|
||||||
|
@ -13,7 +13,7 @@ public object ThreePointLightFactory : ThreeFactory<PointLightSource> {
|
|||||||
|
|
||||||
private val DEFAULT_COLOR = Color(0x404040)
|
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 {
|
val res = PointLight().apply {
|
||||||
matrixAutoUpdate = false
|
matrixAutoUpdate = false
|
||||||
color = vision.color.threeColor() ?: DEFAULT_COLOR
|
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 template = vision.prototype
|
||||||
val cachedObject = cache.getOrPut(template) {
|
val cachedObject = cache.getOrPut(template) {
|
||||||
three.buildObject3D(template)
|
three.buildObject3D(template)
|
||||||
|
@ -7,7 +7,7 @@ import kotlin.reflect.KClass
|
|||||||
public object ThreeSmartLineFactory : ThreeFactory<PolyLine> {
|
public object ThreeSmartLineFactory : ThreeFactory<PolyLine> {
|
||||||
override val type: KClass<in PolyLine> get() = PolyLine::class
|
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) {
|
return if (vision.thickness == 1.0) {
|
||||||
ThreeLineFactory.build(three, vision, observe)
|
ThreeLineFactory.build(three, vision, observe)
|
||||||
} else {
|
} else {
|
||||||
|
@ -12,14 +12,10 @@ import three.math.Vector3
|
|||||||
import three.objects.Mesh
|
import three.objects.Mesh
|
||||||
import three.textures.Texture
|
import three.textures.Texture
|
||||||
import kotlin.contracts.contract
|
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)
|
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() {
|
internal fun Any.dispose() {
|
||||||
when (this) {
|
when (this) {
|
||||||
is BufferGeometry -> dispose()
|
is BufferGeometry -> dispose()
|
||||||
|
Loading…
Reference in New Issue
Block a user