diff --git a/demo/solid-showcase/build.gradle.kts b/demo/solid-showcase/build.gradle.kts index 05a02260..f4a9820d 100644 --- a/demo/solid-showcase/build.gradle.kts +++ b/demo/solid-showcase/build.gradle.kts @@ -8,6 +8,16 @@ kscience { jvm() js{ binaries.executable() + browser{ + commonWebpackConfig{ + cssSupport{ + enabled = true + } + scssSupport{ + enabled = true + } + } + } } dependencies { implementation(projects.visionforgeSolid) diff --git a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt index 9e2ecedb..698cc846 100644 --- a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt +++ b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt @@ -24,6 +24,11 @@ fun VisionLayout.demo(name: String, title: String = name, block: SolidGro block() ambientLight { color(Colors.white) + intensity = 0.5 + } + pointLight(0, 0, 1000) { + color(Colors.white) + intensity = 10.0 } } render(Name.parse(name), vision, meta) @@ -111,7 +116,7 @@ fun VisionLayout.showcase() { GlobalScope.launch(Dispatchers.Main) { while (isActive) { delay(100) - rotate((PI/20).radians,Euclidean3DSpace.yAxis) + rotate((PI / 20).radians, Euclidean3DSpace.yAxis) } } color(Colors.red) @@ -122,13 +127,16 @@ fun VisionLayout.showcase() { demo("extrude", "extruded shape") { extruded { shape { - polygon(8, 50) + polygon(32, 50) } for (i in 0..100) { layer(i * 5, 20 * sin(2 * PI / 100 * i), 20 * cos(2 * PI / 100 * i)) } - color(Colors.teal) - rotationX = -PI / 2 + rotationY = -PI / 2 + material { + type = "lambert" + color(Colors.teal) + } } } @@ -161,7 +169,15 @@ fun VisionLayout.showcase() { } demo("STL", "STL loaded from URL") { - stl("https://ozeki.hu/attachments/116/Menger_sponge_sample.stl") + stl("Menger_sponge_sample.stl") { + scale(100f) + material { + type = "phong" + color("red") + specularColor("blue") + } + } + //stl("https://ozeki.hu/attachments/116/Menger_sponge_sample.stl") } } diff --git a/demo/solid-showcase/src/jsMain/resources/Menger_sponge_sample.stl b/demo/solid-showcase/src/jsMain/resources/Menger_sponge_sample.stl new file mode 100644 index 00000000..dfebb0a3 Binary files /dev/null and b/demo/solid-showcase/src/jsMain/resources/Menger_sponge_sample.stl differ 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 aab583a0..db2c0948 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,10 @@ public var Solid.position: Float32Vector3D? by float32Vector(POSITION_KEY, 0f) public var Solid.rotation: Float32Vector3D? by float32Vector(ROTATION_KEY, 0f) public var Solid.scale: Float32Vector3D? by float32Vector(SCALE_KEY, 1f) +public fun Solid.scale(scaleFactor: Number) { + scale = Float32Vector3D(scaleFactor, scaleFactor, scaleFactor) +} + public var Solid.x: Number by float32(X_POSITION_KEY, 0f) public var Solid.y: Number by float32(Y_POSITION_KEY, 0f) public var Solid.z: Number by float32(Z_POSITION_KEY, 0f) @@ -255,5 +259,5 @@ public var Solid.scaleZ: Number by float32(Z_SCALE_KEY, 1f) * Add rotation with given [angle] relative to given [axis] */ public fun Solid.rotate(angle: Angle, axis: DoubleVector3D): Unit = with(QuaternionField) { - quaternion = Quaternion.fromRotation(angle, axis)*quaternion + quaternion = Quaternion.fromRotation(angle, axis) * quaternion } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt index c411cf4c..e45c18dd 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt @@ -18,6 +18,8 @@ import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_OPACITY @VisionBuilder public class SolidMaterial : Scheme() { + public var type: String by string("default", key = TYPE_KEY) + /** * Primary web-color for the material */ @@ -65,9 +67,9 @@ public class SolidMaterial : Scheme() { MetaDescriptor { inherited = true - value(TYPE_KEY, ValueType.STRING){ + value(TYPE_KEY, ValueType.STRING) { inherited = true - allowedValues = listOf("default".asValue(), "simple".asValue()) + allowedValues = listOf("default", "basic", "lambert", "phong").map { it.asValue() } default("default") } diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt index 8e1b2e3f..34cbbde0 100644 --- a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt @@ -10,10 +10,7 @@ import space.kscience.visionforge.getStyleNodes import space.kscience.visionforge.solid.ColorAccessor import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.SolidReference -import three.materials.LineBasicMaterial -import three.materials.Material -import three.materials.MeshBasicMaterial -import three.materials.MeshStandardMaterial +import three.materials.* import three.math.Color import three.objects.Mesh @@ -56,11 +53,23 @@ public object ThreeMaterials { } internal fun buildMaterial(meta: Meta): Material = when (meta[SolidMaterial.TYPE_KEY]?.string) { - "simple" -> MeshBasicMaterial().apply { + "basic" -> MeshBasicMaterial().apply { color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false } + "lambert" -> MeshLambertMaterial().apply { + color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR + emissive = meta[SolidMaterial.EMISSIVE_COLOR_KEY]?.threeColor() ?: DEFAULT_EMISSIVE_COLOR + wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false + } + + "phong" -> MeshPhongMaterial().apply { + color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR + emissive = meta[SolidMaterial.EMISSIVE_COLOR_KEY]?.threeColor() ?: DEFAULT_EMISSIVE_COLOR + wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false + } + else -> MeshStandardMaterial().apply { color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR emissive = meta[SolidMaterial.EMISSIVE_COLOR_KEY]?.threeColor() ?: DEFAULT_EMISSIVE_COLOR diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index 026c9b18..b00f3c31 100644 --- a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -44,16 +44,15 @@ public class ThreePlugin : AbstractPlugin(), ComposeVisionRenderer { objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory objectFactories[AmbientLightSource::class] = ThreeAmbientLightFactory objectFactories[PointLightSource::class] = ThreePointLightFactory - objectFactories[StlSolid::class] = ThreeStlFactory + objectFactories[StlUrlSolid::class] = ThreeStlFactory + objectFactories[StlBinarySolid::class] = ThreeStlFactory objectFactories[AxesSolid::class] = ThreeAxesFactory } @Suppress("UNCHECKED_CAST") - private fun findObjectFactory(type: KClass): ThreeFactory? { - return (objectFactories[type] - ?: context.gather>(ThreeFactory.TYPE).values.find { it.type == type }) + private fun findObjectFactory(type: KClass): ThreeFactory? = + (objectFactories[type] ?: context.gather>(ThreeFactory.TYPE).values.find { it.type == type }) as ThreeFactory? - } /** * Build an Object3D representation of the given [Solid]. diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeStlFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeStlFactory.kt index e3fb676f..d8ba0a3a 100644 --- a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeStlFactory.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeStlFactory.kt @@ -16,7 +16,9 @@ fun ArrayBuffer.toByteArray(): ByteArray = Int8Array(this).unsafeCast public object ThreeStlFactory : ThreeMeshFactory(StlSolid::class) { private val loader = STLLoader().apply { - requestHeader = listOf("Access-Control-Allow-Origin: *") + requestHeader = listOf( + "Access-Control-Allow-Origin: *", + ) } override suspend fun buildGeometry(obj: StlSolid): BufferGeometry = when (obj) { @@ -25,6 +27,7 @@ public object ThreeStlFactory : ThreeMeshFactory(StlSolid::class) { loader.load( url = obj.url, onLoad = { + console.info("Loaded STL from ${obj.url}") continuation.resume(it) }, onError = {