From 67def6cdb52fb791681c346fde3cfc25fcd11165 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Fri, 5 Jul 2019 21:13:55 +0300 Subject: [PATCH] Added sphere geometry and proper opacity --- .../vis/spatial/demo/ThreeDemoApp.kt | 17 ++++++++-- .../dataforge/vis/spatial/three/Materials.kt | 6 ++-- .../vis/spatial/three/ThreeBoxFactory.kt | 14 ++++++++ .../vis/spatial/three/ThreeFactory.kt | 6 ---- .../vis/spatial/three/ThreePlugin.kt | 1 + .../vis/spatial/three/ThreeSphereFactory.kt | 30 +++++++++++++++++ .../kotlin/hep/dataforge/vis/spatial/Box.kt | 6 ++-- .../hep/dataforge/vis/spatial/Sphere.kt | 32 +++++++++++++++++++ .../dataforge/vis/spatial/displayObject3D.kt | 20 +++++++++--- 9 files changed, 113 insertions(+), 19 deletions(-) create mode 100644 dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreeBoxFactory.kt create mode 100644 dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreeSphereFactory.kt create mode 100644 dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Sphere.kt diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoApp.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoApp.kt index 0a63abb7..2dbc727d 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoApp.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoApp.kt @@ -29,7 +29,17 @@ class ThreeDemoApp : ApplicationBase() { }.build() context.plugins.load(ThreeDemoGrid()).run { - demo("dynamic", "Dynamic properties demo") { + demo("shapes", "Basic shapes"){ + box(100.0,100.0,100.0) { + z = 110.0 + } + sphere(50.0){ + x = 110 + detail = 200 + } + } + + demo("dynamic", "Dynamic properties") { val group = group { box { z = 110.0 @@ -97,7 +107,10 @@ class ThreeDemoApp : ApplicationBase() { rotationY = PI / 4 } box(100, 100, 100) - color(Colors.green) + color{ + "color" to Colors.lightgreen + "opacity" to 0.3 + } } composite(CompositeType.INTERSECT) { box(100, 100, 100) { diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/Materials.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/Materials.kt index 74c6021b..cb19f954 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/Materials.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/Materials.kt @@ -1,9 +1,6 @@ package hep.dataforge.vis.spatial.three -import hep.dataforge.meta.MetaItem -import hep.dataforge.meta.double -import hep.dataforge.meta.get -import hep.dataforge.meta.int +import hep.dataforge.meta.* import hep.dataforge.values.ValueType import hep.dataforge.vis.common.Colors import info.laht.threekt.materials.Material @@ -53,6 +50,7 @@ fun MetaItem<*>?.material(): Material { is MetaItem.NodeItem -> MeshPhongMaterial().apply { (node["color"] ?: this@material).let { color = it.color() } opacity = node["opacity"]?.double ?: 1.0 + transparent = node["transparent"].boolean ?: (opacity < 1.0) node["specularColor"]?.let { specular = it.color() } } } diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreeBoxFactory.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreeBoxFactory.kt new file mode 100644 index 00000000..3f9bd2d5 --- /dev/null +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreeBoxFactory.kt @@ -0,0 +1,14 @@ +package hep.dataforge.vis.spatial.three + +import hep.dataforge.vis.spatial.Box +import hep.dataforge.vis.spatial.detail +import info.laht.threekt.geometries.BoxBufferGeometry +import kotlin.math.pow + +object ThreeBoxFactory : MeshThreeFactory(Box::class) { + override fun buildGeometry(obj: Box) = + obj.detail?.let { + val segments = it.toDouble().pow(1.0 / 3.0).toInt() + BoxBufferGeometry(obj.xSize, obj.ySize, obj.zSize, segments, segments, segments) + } ?: BoxBufferGeometry(obj.xSize, obj.ySize, obj.zSize) +} \ No newline at end of file diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreeFactory.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreeFactory.kt index d42526db..f524a127 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreeFactory.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreeFactory.kt @@ -13,7 +13,6 @@ import hep.dataforge.vis.spatial.three.ThreeFactory.Companion.buildMesh import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.Object3D import info.laht.threekt.external.geometries.ConvexBufferGeometry -import info.laht.threekt.geometries.BoxBufferGeometry import info.laht.threekt.geometries.EdgesGeometry import info.laht.threekt.geometries.WireframeGeometry import info.laht.threekt.objects.LineSegments @@ -132,11 +131,6 @@ object ThreeShapeFactory : MeshThreeFactory(Shape::class) { } } -object ThreeBoxFactory : MeshThreeFactory(Box::class) { - override fun buildGeometry(obj: Box) = - BoxBufferGeometry(obj.xSize, obj.ySize, obj.zSize) -} - //FIXME not functional yet object ThreeConvexFactory : MeshThreeFactory(Convex::class) { override fun buildGeometry(obj: Convex): ConvexBufferGeometry { diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreePlugin.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreePlugin.kt index dc555446..4739c841 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreePlugin.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreePlugin.kt @@ -27,6 +27,7 @@ class ThreePlugin : AbstractPlugin() { //Add specialized factories here objectFactories[Box::class] = ThreeBoxFactory objectFactories[Convex::class] = ThreeConvexFactory + objectFactories[Sphere::class] = ThreeSphereFactory } private fun findObjectFactory(type: KClass): ThreeFactory<*>? { diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreeSphereFactory.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreeSphereFactory.kt new file mode 100644 index 00000000..074eb021 --- /dev/null +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreeSphereFactory.kt @@ -0,0 +1,30 @@ +package hep.dataforge.vis.spatial.three + +import hep.dataforge.vis.spatial.Sphere +import hep.dataforge.vis.spatial.detail +import info.laht.threekt.core.BufferGeometry +import info.laht.threekt.geometries.SphereBufferGeometry +import kotlin.math.pow + +object ThreeSphereFactory : MeshThreeFactory(Sphere::class) { + override fun buildGeometry(obj: Sphere): BufferGeometry { + return obj.detail?.let { + val segments = it.toDouble().pow(0.5).toInt() + SphereBufferGeometry( + radius = obj.radius, + phiStart = obj.phiStart, + phiLength = obj.phi, + thetaStart = obj.thetaStart, + thetaLength = obj.theta, + widthSegments = segments, + heightSegments = segments + ) + }?: SphereBufferGeometry( + radius = obj.radius, + phiStart = obj.phiStart, + phiLength = obj.phi, + thetaStart = obj.thetaStart, + thetaLength = obj.theta + ) + } +} \ No newline at end of file diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Box.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Box.kt index 64014656..9da53fbb 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Box.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Box.kt @@ -8,9 +8,9 @@ import hep.dataforge.vis.common.DisplayObject import hep.dataforge.vis.common.double class Box(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta), Shape { - var xSize by double(1.0) - var ySize by double(1.0) - var zSize by double(1.0) + var xSize by double(100.0) + var ySize by double(100.0) + var zSize by double(100.0) //TODO add helper for color configuration diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Sphere.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Sphere.kt new file mode 100644 index 00000000..ea75232c --- /dev/null +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Sphere.kt @@ -0,0 +1,32 @@ +package hep.dataforge.vis.spatial + +import hep.dataforge.meta.EmptyMeta +import hep.dataforge.meta.Meta +import hep.dataforge.vis.common.DisplayGroup +import hep.dataforge.vis.common.DisplayLeaf +import hep.dataforge.vis.common.DisplayObject +import hep.dataforge.vis.common.double +import kotlin.math.PI + +class Sphere(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta) { + var radius by double(50.0) + var phiStart by double(0.0) + var phi by double(2 * PI) + var thetaStart by double(0.0) + var theta by double(PI) +} + +fun DisplayGroup.sphere(meta: Meta = EmptyMeta, action: Sphere.() -> Unit = {}) = + Sphere(this, meta).apply(action).also { add(it) } + +fun DisplayGroup.sphere( + radius: Number, + phi: Number = 2 * PI, + theta: Number = PI, + meta: Meta = EmptyMeta, + action: Sphere.() -> Unit = {} +) = Sphere(this, meta).apply(action).apply { + this.radius = radius.toDouble() + this.phi = phi.toDouble() + this.theta = theta.toDouble() +}.also { add(it) } \ No newline at end of file diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/displayObject3D.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/displayObject3D.kt index 147fe952..0d1fb8f8 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/displayObject3D.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/displayObject3D.kt @@ -97,7 +97,7 @@ enum class RotationOrder { * Rotation order. Not inherited */ var DisplayObject.rotationOrder: RotationOrder - get() = properties["rotation.order"].enum() ?: RotationOrder.XYZ + get() = getProperty("rotation.order").enum() ?: RotationOrder.XYZ set(value) { properties["rotation.order"] = value } @@ -139,15 +139,27 @@ fun DisplayObject.color(meta: Meta) { this.properties["material"] = meta } -fun DisplayObject.color(r: Int, g: Int, b: Int) = color(buildMeta { +fun DisplayObject.color(builder: MetaBuilder.()->Unit) { + color(buildMeta(builder)) +} + +fun DisplayObject.color(r: Int, g: Int, b: Int) = color{ "red" to r "green" to g "blue" to b -}) - +} //TODO add inherited scale +/** + * Preferred number of polygons for displaying the object. If not defined, uses shape or renderer default + */ +var DisplayObject.detail: Int? + get() = properties["detail"]?.int + set(value) { + properties["detail"] = value + } + object World { const val CAMERA_INITIAL_DISTANCE = -500.0 const val CAMERA_INITIAL_X_ANGLE = -50.0