forked from kscience/visionforge
Suspended renderers and property change listeners
This commit is contained in:
parent
8204eb63c3
commit
2b70afdb86
@ -8,7 +8,7 @@ kscience{
|
||||
|
||||
kotlin{
|
||||
explicitApi = null
|
||||
js(IR){
|
||||
js{
|
||||
useCommonJs()
|
||||
browser {
|
||||
binaries.executable()
|
||||
|
@ -1,14 +1,14 @@
|
||||
plugins {
|
||||
id("space.kscience.gradle.mpp")
|
||||
application
|
||||
// application
|
||||
}
|
||||
|
||||
kscience {
|
||||
useCoroutines()
|
||||
jvm {
|
||||
withJava()
|
||||
jvm()
|
||||
js{
|
||||
binaries.executable()
|
||||
}
|
||||
js()
|
||||
dependencies {
|
||||
implementation(projects.visionforgeSolid)
|
||||
implementation(projects.visionforgeGdml)
|
||||
@ -21,6 +21,6 @@ kscience {
|
||||
|
||||
kotlin.explicitApi = null
|
||||
|
||||
application {
|
||||
mainClass.set("space.kscience.visionforge.solid.demo.FXDemoAppKt")
|
||||
}
|
||||
//application {
|
||||
// mainClass.set("space.kscience.visionforge.solid.demo.FXDemoAppKt")
|
||||
//}
|
@ -150,6 +150,10 @@ fun VisionLayout<Solid>.showcase() {
|
||||
z = 26
|
||||
}
|
||||
}
|
||||
|
||||
demo("STL", "STL loaded from URL"){
|
||||
stl("https://ozeki.hu/attachments/116/Menger_sponge_sample.stl")
|
||||
}
|
||||
}
|
||||
|
||||
fun VisionLayout<Solid>.showcaseCSG() {
|
||||
|
@ -67,7 +67,7 @@ public var Vision.visible: Boolean?
|
||||
*/
|
||||
public fun Vision.onPropertyChange(
|
||||
scope: CoroutineScope? = manager?.context,
|
||||
callback: (Name) -> Unit
|
||||
callback: suspend (Name) -> Unit
|
||||
): Job = properties.changes.onEach {
|
||||
callback(it)
|
||||
}.launchIn(scope ?: error("Orphan Vision can't observe properties"))
|
@ -0,0 +1,25 @@
|
||||
package space.kscience.visionforge.solid
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import space.kscience.visionforge.MutableVisionContainer
|
||||
import space.kscience.visionforge.VisionBuilder
|
||||
import space.kscience.visionforge.setChild
|
||||
|
||||
|
||||
public sealed class StlVision: SolidBase<StlVision>()
|
||||
|
||||
@Serializable
|
||||
@SerialName("solid.stl.url")
|
||||
public class StlUrlVision(public val url: String) : StlVision()
|
||||
|
||||
@Serializable
|
||||
@SerialName("solid.stl.binary")
|
||||
public class StlBinaryVision(public val data: ByteArray) : StlVision()
|
||||
|
||||
@VisionBuilder
|
||||
public inline fun MutableVisionContainer<Solid>.stl(
|
||||
url: String,
|
||||
name: String? = null,
|
||||
action: StlVision.() -> Unit = {},
|
||||
): StlVision = StlUrlVision(url).apply(action).also { setChild(name, it) }
|
@ -5,7 +5,7 @@ import space.kscience.visionforge.solid.detail
|
||||
import three.geometries.BoxGeometry
|
||||
|
||||
public object ThreeBoxFactory : ThreeMeshFactory<Box>(Box::class) {
|
||||
override fun buildGeometry(obj: Box): BoxGeometry =
|
||||
override suspend fun buildGeometry(obj: Box): BoxGeometry =
|
||||
obj.detail?.let { detail ->
|
||||
BoxGeometry(obj.xSize, obj.ySize, obj.zSize, detail, detail, detail)
|
||||
} ?: BoxGeometry(obj.xSize, obj.ySize, obj.zSize)
|
||||
|
@ -8,7 +8,7 @@ import kotlin.math.PI
|
||||
import kotlin.math.pow
|
||||
|
||||
public object ThreeConeFactory : ThreeMeshFactory<ConeSegment>(ConeSegment::class) {
|
||||
override fun buildGeometry(obj: ConeSegment): BufferGeometry {
|
||||
override suspend fun buildGeometry(obj: ConeSegment): BufferGeometry {
|
||||
val cylinder = obj.detail?.let {
|
||||
val segments = it.toDouble().pow(0.5).toInt()
|
||||
CylinderGeometry(
|
||||
|
@ -4,7 +4,7 @@ import space.kscience.visionforge.solid.Convex
|
||||
import three.external.geometries.ConvexBufferGeometry
|
||||
|
||||
public object ThreeConvexFactory : ThreeMeshFactory<Convex>(Convex::class) {
|
||||
override fun buildGeometry(obj: Convex): ConvexBufferGeometry {
|
||||
override suspend fun buildGeometry(obj: Convex): ConvexBufferGeometry {
|
||||
val vectors = obj.points.map { it.toVector() }.toTypedArray()
|
||||
return ConvexBufferGeometry(vectors)
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ public fun Object3D.updateProperty(source: Vision, propertyName: Name) {
|
||||
* Generic factory for elements which provide inside geometry builder
|
||||
*/
|
||||
public object ThreeShapeFactory : ThreeMeshFactory<GeometrySolid>(GeometrySolid::class) {
|
||||
override fun buildGeometry(obj: GeometrySolid): BufferGeometry = ThreeGeometryBuilder().apply {
|
||||
override suspend fun buildGeometry(obj: GeometrySolid): BufferGeometry = ThreeGeometryBuilder().apply {
|
||||
obj.toGeometry(this)
|
||||
}.build()
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
package space.kscience.visionforge.solid.three
|
||||
|
||||
import org.w3c.dom.url.URL
|
||||
import space.kscience.visionforge.solid.SolidBase
|
||||
import three.core.Object3D
|
||||
|
||||
@ -10,15 +9,3 @@ import three.core.Object3D
|
||||
public abstract class ThreeJsVision : SolidBase<ThreeJsVision>() {
|
||||
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()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,10 +21,11 @@ import kotlin.reflect.KClass
|
||||
public abstract class ThreeMeshFactory<in T : Solid>(
|
||||
override val type: KClass<in T>,
|
||||
) : ThreeFactory<T> {
|
||||
|
||||
/**
|
||||
* Build a geometry for an object
|
||||
*/
|
||||
public abstract fun buildGeometry(obj: T): BufferGeometry
|
||||
public abstract suspend fun buildGeometry(obj: T): BufferGeometry
|
||||
|
||||
override suspend fun build(three: ThreePlugin, vision: T, observe: Boolean): Mesh {
|
||||
val geometry = buildGeometry(vision)
|
||||
|
@ -37,6 +37,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
|
||||
objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory
|
||||
objectFactories[AmbientLightSource::class] = ThreeAmbientLightFactory
|
||||
objectFactories[PointLightSource::class] = ThreePointLightFactory
|
||||
objectFactories[StlVision::class] = ThreeStlFactory
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
@ -6,7 +6,7 @@ import three.core.BufferGeometry
|
||||
import three.geometries.SphereGeometry
|
||||
|
||||
public object ThreeSphereFactory : ThreeMeshFactory<Sphere>(Sphere::class) {
|
||||
override fun buildGeometry(obj: Sphere): BufferGeometry {
|
||||
override suspend fun buildGeometry(obj: Sphere): BufferGeometry {
|
||||
return obj.detail?.let { detail ->
|
||||
SphereGeometry(
|
||||
radius = obj.radius,
|
||||
|
@ -0,0 +1,38 @@
|
||||
package space.kscience.visionforge.solid.three
|
||||
|
||||
import org.khronos.webgl.ArrayBuffer
|
||||
import org.khronos.webgl.Int8Array
|
||||
import space.kscience.visionforge.solid.StlBinaryVision
|
||||
import space.kscience.visionforge.solid.StlUrlVision
|
||||
import space.kscience.visionforge.solid.StlVision
|
||||
import three.core.BufferGeometry
|
||||
import three.external.loaders.STLLoader
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.resumeWithException
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
fun ArrayBuffer.toByteArray(): ByteArray = Int8Array(this).unsafeCast<ByteArray>()
|
||||
|
||||
public object ThreeStlFactory : ThreeMeshFactory<StlVision>(StlVision::class) {
|
||||
|
||||
private val loader = STLLoader().apply {
|
||||
requestHeader = listOf("Access-Control-Allow-Origin: *")
|
||||
}
|
||||
|
||||
override suspend fun buildGeometry(obj: StlVision): BufferGeometry = when (obj) {
|
||||
is StlBinaryVision -> loader.parse(obj.data)
|
||||
is StlUrlVision -> suspendCoroutine { continuation ->
|
||||
loader.load(
|
||||
url = obj.url,
|
||||
onLoad = {
|
||||
continuation.resume(it)
|
||||
},
|
||||
onError = {
|
||||
continuation.resumeWithException(RuntimeException("Failed to load STL object from ${obj.url}"))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -22,17 +22,19 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
@file:JsModule("three")
|
||||
@file:JsModule("three/examples/jsm/loaders/STLLoader.js")
|
||||
@file:JsNonModule
|
||||
|
||||
package three.external.loaders
|
||||
|
||||
import org.khronos.webgl.ArrayBuffer
|
||||
import org.w3c.xhr.XMLHttpRequest
|
||||
import three.core.BufferGeometry
|
||||
import three.core.Object3D
|
||||
|
||||
external class STLLoader {
|
||||
|
||||
var requestHeader: List<String>
|
||||
|
||||
fun load(
|
||||
url: String,
|
||||
onLoad: (BufferGeometry) -> Unit,
|
||||
@ -40,7 +42,10 @@ external class STLLoader {
|
||||
onError: () -> Unit = definedExternally
|
||||
)
|
||||
|
||||
fun parse(data: String): Object3D
|
||||
fun parse(data: ByteArray): Object3D
|
||||
fun parse(data: String): BufferGeometry
|
||||
|
||||
fun parse(data: ByteArray): BufferGeometry
|
||||
|
||||
fun parse(data: ArrayBuffer): BufferGeometry
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user