Optimized dancing boxes

This commit is contained in:
Alexander Nozik 2019-11-06 17:01:30 +03:00
parent 3b6fd66920
commit 546f7e1fd0
3 changed files with 106 additions and 68 deletions

View File

@ -29,45 +29,6 @@ abstract class MeshThreeFactory<in T : VisualObject3D>(
*/ */
abstract fun buildGeometry(obj: T): BufferGeometry 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 { override fun invoke(obj: T): Mesh {
val geometry = buildGeometry(obj) val geometry = buildGeometry(obj)
@ -121,4 +82,43 @@ abstract class MeshThreeFactory<in T : VisualObject3D>(
val WIREFRAME_ENABLED_KEY = WIREFRAME_KEY + ENABLED_KEY val WIREFRAME_ENABLED_KEY = WIREFRAME_KEY + ENABLED_KEY
val WIREFRAME_MATERIAL_KEY = WIREFRAME_KEY + Material3D.MATERIAL_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"
}
)
}
} }

View File

@ -8,12 +8,12 @@ dependencies {
testCompile(kotlin("test-js")) testCompile(kotlin("test-js"))
} }
kotlin{ //kotlin{
target { // target {
browser{ // browser{
webpackTask { // webpackTask {
sourceMaps = false // sourceMaps = false
} // }
} // }
} // }
} //}

View File

@ -5,26 +5,26 @@ package hep.dataforge.vis.spatial.demo
import hep.dataforge.meta.int import hep.dataforge.meta.int
import hep.dataforge.meta.number import hep.dataforge.meta.number
import hep.dataforge.names.plus import hep.dataforge.names.plus
import hep.dataforge.names.startsWith
import hep.dataforge.vis.common.getProperty import hep.dataforge.vis.common.getProperty
import hep.dataforge.vis.common.setProperty import hep.dataforge.vis.common.setProperty
import hep.dataforge.vis.spatial.* import hep.dataforge.vis.spatial.*
import hep.dataforge.vis.spatial.VisualObject3D.Companion.GEOMETRY_KEY 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.demo.VariableBoxThreeFactory.Z_SIZE_KEY
import hep.dataforge.vis.spatial.three.CustomThreeVisualObject import hep.dataforge.vis.spatial.three.*
import hep.dataforge.vis.spatial.three.MeshThreeFactory
import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.core.Object3D
import info.laht.threekt.geometries.BoxBufferGeometry import info.laht.threekt.geometries.BoxBufferGeometry
import info.laht.threekt.materials.MeshBasicMaterial
import info.laht.threekt.objects.Mesh
import kotlinx.serialization.UseSerializers import kotlinx.serialization.UseSerializers
import kotlin.math.max import kotlin.math.max
import kotlin.reflect.KClass
private val BOX_Z_SIZE_KEY = GEOMETRY_KEY + "zSize"
internal var VisualObject3D.variableZSize: Number internal var VisualObject3D.variableZSize: Number
get() = getProperty(BOX_Z_SIZE_KEY, false).number ?: 0f get() = getProperty(Z_SIZE_KEY, false).number ?: 0f
set(value) { set(value) {
setProperty(BOX_Z_SIZE_KEY, value) setProperty(Z_SIZE_KEY, value)
} }
internal var VisualObject3D.value: Int internal var VisualObject3D.value: Int
@ -32,7 +32,7 @@ internal var VisualObject3D.value: Int
set(value) { set(value) {
setProperty("value", value) setProperty("value", value)
val size = value.toFloat() / 255f * 20f val size = value.toFloat() / 255f * 20f
variableZSize = size scaleZ = size
z = -size / 2 z = -size / 2
val b = max(0, 255 - value) val b = max(0, 255 - value)
@ -48,22 +48,60 @@ fun VisualGroup3D.varBox(
name: String = "", name: String = "",
action: VisualObject3D.() -> Unit = {} action: VisualObject3D.() -> Unit = {}
) = CustomThreeVisualObject(VariableBoxThreeFactory).apply { ) = CustomThreeVisualObject(VariableBoxThreeFactory).apply {
setProperty(X_SIZE_KEY, xSize) scaleX = xSize
setProperty(Y_SIZE_KEY, ySize) scaleY = ySize
setProperty(Z_SIZE_KEY, zSize) scaleZ = zSize
}.apply(action).also { set(name, it) } }.apply(action).also { set(name, it) }
private object VariableBoxThreeFactory : MeshThreeFactory<VisualObject3D>(VisualObject3D::class) { private object VariableBoxThreeFactory : ThreeFactory<VisualObject3D> {
val X_SIZE_KEY = GEOMETRY_KEY + "xSize" val X_SIZE_KEY = GEOMETRY_KEY + "xSize"
val Y_SIZE_KEY = GEOMETRY_KEY + "ySize" val Y_SIZE_KEY = GEOMETRY_KEY + "ySize"
val Z_SIZE_KEY = GEOMETRY_KEY + "zSize" val Z_SIZE_KEY = GEOMETRY_KEY + "zSize"
override fun buildGeometry(obj: VisualObject3D): BufferGeometry { override val type: KClass<in VisualObject3D> get() = VisualObject3D::class
val xSize = obj.getProperty(X_SIZE_KEY, false).number ?: 0f
val ySize = obj.getProperty(Y_SIZE_KEY, false).number ?: 0f override fun invoke(obj: VisualObject3D): Object3D {
val zSize = obj.getProperty(Z_SIZE_KEY, false).number ?: 0f val xSize = obj.getProperty(X_SIZE_KEY, false).number?.toDouble() ?: 1.0
return obj.detail?.let { detail -> val ySize = obj.getProperty(Y_SIZE_KEY, false).number?.toDouble() ?: 1.0
BoxBufferGeometry(xSize, ySize, zSize, detail, detail, detail) val zSize = obj.getProperty(Z_SIZE_KEY, false).number?.toDouble() ?: 1.0
} ?: BoxBufferGeometry(xSize, ySize, zSize) 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
} }
} }