From 546f7e1fd0d9d3c4397b9940002cb0654428b119 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 6 Nov 2019 17:01:30 +0300 Subject: [PATCH] Optimized dancing boxes --- .../vis/spatial/three/MeshThreeFactory.kt | 78 +++++++++---------- spatial-js-demo/build.gradle.kts | 18 ++--- .../dataforge/vis/spatial/demo/VariableBox.kt | 78 ++++++++++++++----- 3 files changed, 106 insertions(+), 68 deletions(-) diff --git a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/MeshThreeFactory.kt b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/MeshThreeFactory.kt index 35898398..e1101ab6 100644 --- a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/MeshThreeFactory.kt +++ b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/MeshThreeFactory.kt @@ -29,45 +29,6 @@ abstract class MeshThreeFactory( */ abstract fun buildGeometry(obj: T): BufferGeometry - private fun Mesh.applyEdges(obj: T) { - children.find { it.name == "edges" }?.let { - remove(it) - (it as LineSegments).dispose() - } - //inherited edges definition, enabled by default - if (obj.getProperty(EDGES_ENABLED_KEY).boolean != false) { - - val material = ThreeMaterials.getLineMaterial(obj.getProperty(EDGES_MATERIAL_KEY).node) - add( - LineSegments( - EdgesGeometry(geometry as BufferGeometry), - material - ).apply { - name = "edges" - } - ) - } - } - - private fun Mesh.applyWireFrame(obj: T) { - children.find { it.name == "wireframe" }?.let { - remove(it) - (it as LineSegments).dispose() - } - //inherited wireframe definition, disabled by default - if (obj.getProperty(WIREFRAME_ENABLED_KEY).boolean == true) { - val material = ThreeMaterials.getLineMaterial(obj.getProperty(WIREFRAME_MATERIAL_KEY).node) - add( - LineSegments( - WireframeGeometry(geometry as BufferGeometry), - material - ).apply { - name = "wireframe" - } - ) - } - } - override fun invoke(obj: T): Mesh { val geometry = buildGeometry(obj) @@ -121,4 +82,43 @@ abstract class MeshThreeFactory( val WIREFRAME_ENABLED_KEY = WIREFRAME_KEY + ENABLED_KEY val WIREFRAME_MATERIAL_KEY = WIREFRAME_KEY + Material3D.MATERIAL_KEY } +} + +fun Mesh.applyEdges(obj: VisualObject3D) { + children.find { it.name == "edges" }?.let { + remove(it) + (it as LineSegments).dispose() + } + //inherited edges definition, enabled by default + if (obj.getProperty(MeshThreeFactory.EDGES_ENABLED_KEY).boolean != false) { + + val material = ThreeMaterials.getLineMaterial(obj.getProperty(MeshThreeFactory.EDGES_MATERIAL_KEY).node) + add( + LineSegments( + EdgesGeometry(geometry as BufferGeometry), + material + ).apply { + name = "edges" + } + ) + } +} + +fun Mesh.applyWireFrame(obj: VisualObject3D) { + children.find { it.name == "wireframe" }?.let { + remove(it) + (it as LineSegments).dispose() + } + //inherited wireframe definition, disabled by default + if (obj.getProperty(MeshThreeFactory.WIREFRAME_ENABLED_KEY).boolean == true) { + val material = ThreeMaterials.getLineMaterial(obj.getProperty(MeshThreeFactory.WIREFRAME_MATERIAL_KEY).node) + add( + LineSegments( + WireframeGeometry(geometry as BufferGeometry), + material + ).apply { + name = "wireframe" + } + ) + } } \ No newline at end of file diff --git a/spatial-js-demo/build.gradle.kts b/spatial-js-demo/build.gradle.kts index e5021379..53f185b2 100644 --- a/spatial-js-demo/build.gradle.kts +++ b/spatial-js-demo/build.gradle.kts @@ -8,12 +8,12 @@ dependencies { testCompile(kotlin("test-js")) } -kotlin{ - target { - browser{ - webpackTask { - sourceMaps = false - } - } - } -} \ No newline at end of file +//kotlin{ +// target { +// browser{ +// webpackTask { +// sourceMaps = false +// } +// } +// } +//} \ No newline at end of file diff --git a/spatial-js-demo/src/main/kotlin/hep/dataforge/vis/spatial/demo/VariableBox.kt b/spatial-js-demo/src/main/kotlin/hep/dataforge/vis/spatial/demo/VariableBox.kt index c1d8be33..2827dcbd 100644 --- a/spatial-js-demo/src/main/kotlin/hep/dataforge/vis/spatial/demo/VariableBox.kt +++ b/spatial-js-demo/src/main/kotlin/hep/dataforge/vis/spatial/demo/VariableBox.kt @@ -5,26 +5,26 @@ package hep.dataforge.vis.spatial.demo import hep.dataforge.meta.int import hep.dataforge.meta.number import hep.dataforge.names.plus +import hep.dataforge.names.startsWith import hep.dataforge.vis.common.getProperty import hep.dataforge.vis.common.setProperty import hep.dataforge.vis.spatial.* import hep.dataforge.vis.spatial.VisualObject3D.Companion.GEOMETRY_KEY -import hep.dataforge.vis.spatial.demo.VariableBoxThreeFactory.X_SIZE_KEY -import hep.dataforge.vis.spatial.demo.VariableBoxThreeFactory.Y_SIZE_KEY import hep.dataforge.vis.spatial.demo.VariableBoxThreeFactory.Z_SIZE_KEY -import hep.dataforge.vis.spatial.three.CustomThreeVisualObject -import hep.dataforge.vis.spatial.three.MeshThreeFactory +import hep.dataforge.vis.spatial.three.* import info.laht.threekt.core.BufferGeometry +import info.laht.threekt.core.Object3D import info.laht.threekt.geometries.BoxBufferGeometry +import info.laht.threekt.materials.MeshBasicMaterial +import info.laht.threekt.objects.Mesh import kotlinx.serialization.UseSerializers import kotlin.math.max - -private val BOX_Z_SIZE_KEY = GEOMETRY_KEY + "zSize" +import kotlin.reflect.KClass internal var VisualObject3D.variableZSize: Number - get() = getProperty(BOX_Z_SIZE_KEY, false).number ?: 0f + get() = getProperty(Z_SIZE_KEY, false).number ?: 0f set(value) { - setProperty(BOX_Z_SIZE_KEY, value) + setProperty(Z_SIZE_KEY, value) } internal var VisualObject3D.value: Int @@ -32,7 +32,7 @@ internal var VisualObject3D.value: Int set(value) { setProperty("value", value) val size = value.toFloat() / 255f * 20f - variableZSize = size + scaleZ = size z = -size / 2 val b = max(0, 255 - value) @@ -48,22 +48,60 @@ fun VisualGroup3D.varBox( name: String = "", action: VisualObject3D.() -> Unit = {} ) = CustomThreeVisualObject(VariableBoxThreeFactory).apply { - setProperty(X_SIZE_KEY, xSize) - setProperty(Y_SIZE_KEY, ySize) - setProperty(Z_SIZE_KEY, zSize) + scaleX = xSize + scaleY = ySize + scaleZ = zSize }.apply(action).also { set(name, it) } -private object VariableBoxThreeFactory : MeshThreeFactory(VisualObject3D::class) { +private object VariableBoxThreeFactory : ThreeFactory { val X_SIZE_KEY = GEOMETRY_KEY + "xSize" val Y_SIZE_KEY = GEOMETRY_KEY + "ySize" val Z_SIZE_KEY = GEOMETRY_KEY + "zSize" - override fun buildGeometry(obj: VisualObject3D): BufferGeometry { - val xSize = obj.getProperty(X_SIZE_KEY, false).number ?: 0f - val ySize = obj.getProperty(Y_SIZE_KEY, false).number ?: 0f - val zSize = obj.getProperty(Z_SIZE_KEY, false).number ?: 0f - return obj.detail?.let { detail -> - BoxBufferGeometry(xSize, ySize, zSize, detail, detail, detail) - } ?: BoxBufferGeometry(xSize, ySize, zSize) + override val type: KClass get() = VisualObject3D::class + + override fun invoke(obj: VisualObject3D): Object3D { + val xSize = obj.getProperty(X_SIZE_KEY, false).number?.toDouble() ?: 1.0 + val ySize = obj.getProperty(Y_SIZE_KEY, false).number?.toDouble() ?: 1.0 + val zSize = obj.getProperty(Z_SIZE_KEY, false).number?.toDouble() ?: 1.0 + val geometry = BoxBufferGeometry(1, 1, 1) + + //JS sometimes tries to pass Geometry as BufferGeometry + @Suppress("USELESS_IS_CHECK") if (geometry !is BufferGeometry) error("BufferGeometry expected") + + val mesh = Mesh(geometry, MeshBasicMaterial()).apply { + applyEdges(obj) + applyWireFrame(obj) + + //set position for mesh + updatePosition(obj) + + //set color for mesh + updateMaterial(obj) + + layers.enable(obj.layer) + children.forEach { + it.layers.enable(obj.layer) + } + } + + mesh.scale.set(xSize, ySize, zSize) + + //add listener to object properties + obj.onPropertyChange(this) { name, _, _ -> + when { +// name.startsWith(GEOMETRY_KEY) -> { +// val newXSize = obj.getProperty(X_SIZE_KEY, false).number?.toDouble() ?: 1.0 +// val newYSize = obj.getProperty(Y_SIZE_KEY, false).number?.toDouble() ?: 1.0 +// val newZSize = obj.getProperty(Z_SIZE_KEY, false).number?.toDouble() ?: 1.0 +// mesh.scale.set(newXSize, newYSize, newZSize) +// mesh.updateMatrix() +// } + name.startsWith(MeshThreeFactory.WIREFRAME_KEY) -> mesh.applyWireFrame(obj) + name.startsWith(MeshThreeFactory.EDGES_KEY) -> mesh.applyEdges(obj) + else -> mesh.updateProperty(obj, name) + } + } + return mesh } } \ No newline at end of file