Resizable boxes and optimizations
This commit is contained in:
parent
58e396f50c
commit
3b6fd66920
@ -2,7 +2,7 @@ val dataforgeVersion by extra("0.1.4")
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
val kotlinVersion = "1.3.50"
|
val kotlinVersion = "1.3.50"
|
||||||
val toolsVersion = "0.2.1"
|
val toolsVersion = "0.2.2"
|
||||||
|
|
||||||
kotlin("jvm") version kotlinVersion apply false
|
kotlin("jvm") version kotlinVersion apply false
|
||||||
id("kotlin-dce-js") version kotlinVersion apply false
|
id("kotlin-dce-js") version kotlinVersion apply false
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package hep.dataforge.vis.common
|
package hep.dataforge.vis.common
|
||||||
|
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.meta.MetaBuilder
|
|
||||||
import hep.dataforge.meta.MetaItem
|
import hep.dataforge.meta.MetaItem
|
||||||
import hep.dataforge.names.*
|
import hep.dataforge.names.*
|
||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
@ -145,17 +144,4 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup
|
|||||||
} else {
|
} else {
|
||||||
set(key.asName(), child)
|
set(key.asName(), child)
|
||||||
}
|
}
|
||||||
|
|
||||||
// operator fun set(key: String?, child: VisualObject?) = set(key ?: "", child)
|
|
||||||
|
|
||||||
protected fun MetaBuilder.updateChildren() {
|
|
||||||
//adding named children
|
|
||||||
children.forEach {
|
|
||||||
"children[${it.key}]" put it.value.toMeta()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun MetaBuilder.updateMeta() {
|
|
||||||
updateChildren()
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -82,14 +82,6 @@ abstract class AbstractVisualObject : VisualObject {
|
|||||||
properties?.get(name) ?: mergedStyles[name]
|
properties?.get(name) ?: mergedStyles[name]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun MetaBuilder.updateMeta() {}
|
|
||||||
|
|
||||||
override fun toMeta(): Meta = buildMeta {
|
|
||||||
"type" putValue this::class.simpleName
|
|
||||||
"properties" put properties
|
|
||||||
updateMeta()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun VisualObject.findStyle(styleName: Name): Meta? {
|
fun VisualObject.findStyle(styleName: Name): Meta? {
|
||||||
|
@ -3,7 +3,11 @@ package hep.dataforge.vis.spatial
|
|||||||
|
|
||||||
import hep.dataforge.context.Context
|
import hep.dataforge.context.Context
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
import hep.dataforge.io.serialization.ConfigSerializer
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.io.toMeta
|
||||||
|
import hep.dataforge.meta.Config
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
|
import hep.dataforge.meta.float
|
||||||
|
import hep.dataforge.meta.get
|
||||||
import hep.dataforge.vis.common.AbstractVisualObject
|
import hep.dataforge.vis.common.AbstractVisualObject
|
||||||
import hep.dataforge.vis.common.VisualFactory
|
import hep.dataforge.vis.common.VisualFactory
|
||||||
import hep.dataforge.vis.common.VisualObject
|
import hep.dataforge.vis.common.VisualObject
|
||||||
@ -27,9 +31,9 @@ class Box(
|
|||||||
|
|
||||||
//TODO add helper for color configuration
|
//TODO add helper for color configuration
|
||||||
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
|
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
|
||||||
val dx = xSize.toFloat() / 2
|
val dx = xSize / 2
|
||||||
val dy = ySize.toFloat() / 2
|
val dy = ySize / 2
|
||||||
val dz = zSize.toFloat() / 2
|
val dz = zSize / 2
|
||||||
val node1 = Point3D(-dx, -dy, -dz)
|
val node1 = Point3D(-dx, -dy, -dz)
|
||||||
val node2 = Point3D(dx, -dy, -dz)
|
val node2 = Point3D(dx, -dy, -dz)
|
||||||
val node3 = Point3D(dx, dy, -dz)
|
val node3 = Point3D(dx, dy, -dz)
|
||||||
@ -46,16 +50,7 @@ class Box(
|
|||||||
geometryBuilder.face4(node8, node5, node6, node7)
|
geometryBuilder.face4(node8, node5, node6, node7)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun MetaBuilder.updateMeta() {
|
override fun toMeta(): Meta = Visual3DPlugin.json.toJson(serializer(), this).toMeta()
|
||||||
"xSize" put xSize
|
|
||||||
"ySize" put ySize
|
|
||||||
"zSize" put ySize
|
|
||||||
updatePosition()
|
|
||||||
}
|
|
||||||
|
|
||||||
// override fun toMeta(): Meta {
|
|
||||||
// return (Visual3DPlugin.json.toJson(Box.serializer(), this) as JsonObject).toMeta()
|
|
||||||
// }
|
|
||||||
|
|
||||||
companion object : VisualFactory<Box> {
|
companion object : VisualFactory<Box> {
|
||||||
const val TYPE = "geometry.3d.box"
|
const val TYPE = "geometry.3d.box"
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
import hep.dataforge.io.serialization.ConfigSerializer
|
||||||
|
import hep.dataforge.io.toMeta
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.meta.MetaBuilder
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.meta.update
|
import hep.dataforge.meta.update
|
||||||
import hep.dataforge.vis.common.AbstractVisualObject
|
import hep.dataforge.vis.common.AbstractVisualObject
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
@ -34,12 +35,7 @@ class Composite(
|
|||||||
@Serializable(ConfigSerializer::class)
|
@Serializable(ConfigSerializer::class)
|
||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
|
|
||||||
override fun MetaBuilder.updateMeta() {
|
override fun toMeta(): Meta = Visual3DPlugin.json.toJson(serializer(), this).toMeta()
|
||||||
"compositeType" put compositeType
|
|
||||||
"first" put first.toMeta()
|
|
||||||
"second" put second.toMeta()
|
|
||||||
updatePosition()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun VisualGroup3D.composite(
|
inline fun VisualGroup3D.composite(
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
import hep.dataforge.io.serialization.ConfigSerializer
|
||||||
|
import hep.dataforge.io.toMeta
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.vis.common.AbstractVisualObject
|
import hep.dataforge.vis.common.AbstractVisualObject
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
@ -26,6 +28,8 @@ class ConeSegment(
|
|||||||
override var position: Point3D? = null
|
override var position: Point3D? = null
|
||||||
override var rotation: Point3D? = null
|
override var rotation: Point3D? = null
|
||||||
override var scale: Point3D? = null
|
override var scale: Point3D? = null
|
||||||
|
|
||||||
|
override fun toMeta(): Meta = Visual3DPlugin.json.toJson(serializer(), this).toMeta()
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun VisualGroup3D.cylinder(
|
inline fun VisualGroup3D.cylinder(
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
import hep.dataforge.io.serialization.ConfigSerializer
|
||||||
|
import hep.dataforge.io.toMeta
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.meta.MetaBuilder
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.vis.common.AbstractVisualObject
|
import hep.dataforge.vis.common.AbstractVisualObject
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
@ -19,12 +20,7 @@ class Convex(val points: List<Point3D>) : AbstractVisualObject(), VisualObject3D
|
|||||||
override var rotation: Point3D? = null
|
override var rotation: Point3D? = null
|
||||||
override var scale: Point3D? = null
|
override var scale: Point3D? = null
|
||||||
|
|
||||||
override fun MetaBuilder.updateMeta() {
|
override fun toMeta(): Meta = Visual3DPlugin.json.toJson(serializer(), this).toMeta()
|
||||||
"points" put {
|
|
||||||
"point" put points.map { it.toMeta() }
|
|
||||||
}
|
|
||||||
updatePosition()
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TYPE = "geometry.3d.convex"
|
const val TYPE = "geometry.3d.convex"
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
import hep.dataforge.io.serialization.ConfigSerializer
|
||||||
|
import hep.dataforge.io.toMeta
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.vis.common.AbstractVisualObject
|
import hep.dataforge.vis.common.AbstractVisualObject
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
@ -105,6 +107,8 @@ class Extruded(
|
|||||||
geometryBuilder.cap(layers.last())
|
geometryBuilder.cap(layers.last())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun toMeta(): Meta = Visual3DPlugin.json.toJson(serializer(), this).toMeta()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TYPE = "geometry.3d.extruded"
|
const val TYPE = "geometry.3d.extruded"
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ fun VisualObject.color(rgb: String) {
|
|||||||
|
|
||||||
fun VisualObject.color(rgb: Int) = color(Colors.rgbToString(rgb))
|
fun VisualObject.color(rgb: Int) = color(Colors.rgbToString(rgb))
|
||||||
|
|
||||||
fun VisualObject.color(r: UByte, g: UByte, b: UByte) = color( Colors.rgbToString(r,g,b))
|
fun VisualObject.color(r: UByte, g: UByte, b: UByte) = color(Colors.rgbToString(r, g, b))
|
||||||
|
|
||||||
var VisualObject.color: String?
|
var VisualObject.color: String?
|
||||||
get() = getProperty(COLOR_KEY).string
|
get() = getProperty(COLOR_KEY).string
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
import hep.dataforge.io.serialization.ConfigSerializer
|
||||||
|
import hep.dataforge.io.toMeta
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.vis.common.AbstractVisualObject
|
import hep.dataforge.vis.common.AbstractVisualObject
|
||||||
import hep.dataforge.vis.common.number
|
import hep.dataforge.vis.common.number
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
@ -20,6 +22,8 @@ class PolyLine(var points: List<Point3D>) : AbstractVisualObject(), VisualObject
|
|||||||
|
|
||||||
//var lineType by string()
|
//var lineType by string()
|
||||||
var thickness by number(1.0, key = "material.thickness")
|
var thickness by number(1.0, key = "material.thickness")
|
||||||
|
|
||||||
|
override fun toMeta(): Meta = Visual3DPlugin.json.toJson(serializer(), this).toMeta()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun VisualGroup3D.polyline(vararg points: Point3D, name: String = "", action: PolyLine.() -> Unit = {}) =
|
fun VisualGroup3D.polyline(vararg points: Point3D, name: String = "", action: PolyLine.() -> Unit = {}) =
|
||||||
|
@ -3,9 +3,12 @@
|
|||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
import hep.dataforge.io.serialization.ConfigSerializer
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.NameSerializer
|
import hep.dataforge.io.serialization.NameSerializer
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.io.toMeta
|
||||||
|
import hep.dataforge.meta.Config
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
|
import hep.dataforge.meta.MetaItem
|
||||||
|
import hep.dataforge.meta.get
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
@ -61,10 +64,7 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun MetaBuilder.updateMeta() {
|
override fun toMeta(): Meta = Visual3DPlugin.json.toJson(serializer(), this).toMeta()
|
||||||
//TODO add reference to child
|
|
||||||
updatePosition()
|
|
||||||
}
|
|
||||||
|
|
||||||
override val children: Map<NameToken, ProxyChild>
|
override val children: Map<NameToken, ProxyChild>
|
||||||
get() = (prototype as? MutableVisualGroup)?.children
|
get() = (prototype as? MutableVisualGroup)?.children
|
||||||
@ -94,6 +94,7 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua
|
|||||||
|
|
||||||
//override fun findAllStyles(): Laminate = Laminate((styles + prototype.styles).mapNotNull { findStyle(it) })
|
//override fun findAllStyles(): Laminate = Laminate((styles + prototype.styles).mapNotNull { findStyle(it) })
|
||||||
|
|
||||||
|
@Serializable
|
||||||
inner class ProxyChild(val name: Name) : AbstractVisualObject(), VisualGroup {
|
inner class ProxyChild(val name: Name) : AbstractVisualObject(), VisualGroup {
|
||||||
|
|
||||||
val prototype: VisualObject by lazy {
|
val prototype: VisualObject by lazy {
|
||||||
@ -143,6 +144,8 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun toMeta(): Meta = Visual3DPlugin.json.toJson(serializer(), this).toMeta()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
import hep.dataforge.io.serialization.ConfigSerializer
|
||||||
|
import hep.dataforge.io.toMeta
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.vis.common.AbstractVisualObject
|
import hep.dataforge.vis.common.AbstractVisualObject
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
@ -24,6 +26,8 @@ class Sphere(
|
|||||||
override var position: Point3D? = null
|
override var position: Point3D? = null
|
||||||
override var rotation: Point3D? = null
|
override var rotation: Point3D? = null
|
||||||
override var scale: Point3D? = null
|
override var scale: Point3D? = null
|
||||||
|
|
||||||
|
override fun toMeta(): Meta = Visual3DPlugin.json.toJson(serializer(), this).toMeta()
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun VisualGroup3D.sphere(
|
inline fun VisualGroup3D.sphere(
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
import hep.dataforge.io.serialization.ConfigSerializer
|
||||||
|
import hep.dataforge.io.toMeta
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.vis.common.AbstractVisualObject
|
import hep.dataforge.vis.common.AbstractVisualObject
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
@ -123,6 +125,8 @@ class Tube(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun toMeta(): Meta = Visual3DPlugin.json.toJson(serializer(), this).toMeta()
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun VisualGroup3D.tube(
|
inline fun VisualGroup3D.tube(
|
||||||
|
@ -11,10 +11,9 @@ package hep.dataforge.vis.spatial
|
|||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
import hep.dataforge.io.serialization.ConfigSerializer
|
||||||
import hep.dataforge.io.serialization.MetaSerializer
|
import hep.dataforge.io.serialization.MetaSerializer
|
||||||
import hep.dataforge.io.serialization.NameSerializer
|
import hep.dataforge.io.serialization.NameSerializer
|
||||||
|
import hep.dataforge.io.toMeta
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.meta.MetaBuilder
|
|
||||||
import hep.dataforge.meta.set
|
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
@ -98,11 +97,7 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun MetaBuilder.updateMeta() {
|
override fun toMeta(): Meta = Visual3DPlugin.json.toJson(serializer(), this).toMeta()
|
||||||
set(PROTOTYPES_KEY, prototypes?.toMeta())
|
|
||||||
updatePosition()
|
|
||||||
updateChildren()
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val PROTOTYPES_KEY = "templates"
|
const val PROTOTYPES_KEY = "templates"
|
||||||
|
@ -40,7 +40,7 @@ interface VisualObject3D : VisualObject {
|
|||||||
val LAYER_KEY = "layer".asName()
|
val LAYER_KEY = "layer".asName()
|
||||||
val IGNORE_KEY = "ignore".asName()
|
val IGNORE_KEY = "ignore".asName()
|
||||||
|
|
||||||
val GEOMETRY_KEY = "geometey".asName()
|
val GEOMETRY_KEY = "geometry".asName()
|
||||||
|
|
||||||
val x = "x".asName()
|
val x = "x".asName()
|
||||||
val y = "y".asName()
|
val y = "y".asName()
|
||||||
|
@ -1,96 +0,0 @@
|
|||||||
package hep.dataforge.vis.spatial.three
|
|
||||||
|
|
||||||
import hep.dataforge.meta.*
|
|
||||||
import hep.dataforge.values.ValueType
|
|
||||||
import hep.dataforge.vis.common.Colors
|
|
||||||
import hep.dataforge.vis.spatial.Material3D
|
|
||||||
import info.laht.threekt.materials.LineBasicMaterial
|
|
||||||
import info.laht.threekt.materials.Material
|
|
||||||
import info.laht.threekt.materials.MeshBasicMaterial
|
|
||||||
import info.laht.threekt.materials.MeshPhongMaterial
|
|
||||||
import info.laht.threekt.math.Color
|
|
||||||
|
|
||||||
|
|
||||||
object Materials {
|
|
||||||
val DEFAULT_COLOR = Color(Colors.darkgreen)
|
|
||||||
val DEFAULT = MeshPhongMaterial().apply {
|
|
||||||
color.set(DEFAULT_COLOR)
|
|
||||||
}
|
|
||||||
val DEFAULT_LINE_COLOR = Color(Colors.black)
|
|
||||||
val DEFAULT_LINE = LineBasicMaterial().apply {
|
|
||||||
color.set(DEFAULT_LINE_COLOR)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private val materialCache = HashMap<Meta, Material>()
|
|
||||||
private val lineMaterialCache = HashMap<Meta, Material>()
|
|
||||||
|
|
||||||
fun getMaterial(meta: Meta): Material = materialCache.getOrPut(meta) {
|
|
||||||
MeshBasicMaterial().apply {
|
|
||||||
color = meta["color"]?.color() ?: DEFAULT_COLOR
|
|
||||||
opacity = meta["opacity"]?.double ?: 1.0
|
|
||||||
transparent = meta["transparent"].boolean ?: (opacity < 1.0)
|
|
||||||
//node["specularColor"]?.let { specular = it.color() }
|
|
||||||
//side = 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getLineMaterial(meta: Meta): Material = lineMaterialCache.getOrPut(meta) {
|
|
||||||
LineBasicMaterial().apply {
|
|
||||||
color = meta["color"]?.color() ?: DEFAULT_LINE_COLOR
|
|
||||||
opacity = meta["opacity"].double ?: 1.0
|
|
||||||
transparent = meta["transparent"].boolean ?: (opacity < 1.0)
|
|
||||||
linewidth = meta["thickness"].double ?: 1.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Infer color based on meta item
|
|
||||||
*/
|
|
||||||
fun MetaItem<*>.color(): Color {
|
|
||||||
return when (this) {
|
|
||||||
is MetaItem.ValueItem -> if (this.value.type == ValueType.STRING) {
|
|
||||||
Color(this.value.string)
|
|
||||||
} else {
|
|
||||||
val int = value.number.toInt()
|
|
||||||
// val red = int and 0x00ff0000 shr 16
|
|
||||||
// val green = int and 0x0000ff00 shr 8
|
|
||||||
// val blue = int and 0x000000ff
|
|
||||||
Color(int)
|
|
||||||
}
|
|
||||||
is MetaItem.NodeItem -> {
|
|
||||||
Color(
|
|
||||||
node["red"]?.int ?: 0,
|
|
||||||
node["green"]?.int ?: 0,
|
|
||||||
node["blue"]?.int ?: 0
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Infer Three material based on meta item
|
|
||||||
*/
|
|
||||||
fun Meta?.jsMaterial(): Material {
|
|
||||||
return if (this == null) {
|
|
||||||
Materials.DEFAULT
|
|
||||||
} else {
|
|
||||||
Materials.getMaterial(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Meta?.jsLineMaterial(): Material {
|
|
||||||
return if (this == null) {
|
|
||||||
Materials.DEFAULT_LINE
|
|
||||||
} else{
|
|
||||||
Materials.getLineMaterial(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun Material3D?.jsMaterial(): Material = this?.config.jsMaterial()
|
|
||||||
fun Material3D?.jsLineMaterial(): Material = this?.config.jsLineMaterial()
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
|||||||
package hep.dataforge.vis.spatial.three
|
package hep.dataforge.vis.spatial.three
|
||||||
|
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.meta.boolean
|
import hep.dataforge.meta.boolean
|
||||||
|
import hep.dataforge.meta.get
|
||||||
import hep.dataforge.meta.node
|
import hep.dataforge.meta.node
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
@ -8,10 +10,10 @@ import hep.dataforge.names.startsWith
|
|||||||
import hep.dataforge.vis.spatial.Material3D
|
import hep.dataforge.vis.spatial.Material3D
|
||||||
import hep.dataforge.vis.spatial.VisualObject3D
|
import hep.dataforge.vis.spatial.VisualObject3D
|
||||||
import hep.dataforge.vis.spatial.layer
|
import hep.dataforge.vis.spatial.layer
|
||||||
import hep.dataforge.vis.spatial.material
|
|
||||||
import info.laht.threekt.core.BufferGeometry
|
import info.laht.threekt.core.BufferGeometry
|
||||||
import info.laht.threekt.geometries.EdgesGeometry
|
import info.laht.threekt.geometries.EdgesGeometry
|
||||||
import info.laht.threekt.geometries.WireframeGeometry
|
import info.laht.threekt.geometries.WireframeGeometry
|
||||||
|
import info.laht.threekt.materials.MeshBasicMaterial
|
||||||
import info.laht.threekt.objects.LineSegments
|
import info.laht.threekt.objects.LineSegments
|
||||||
import info.laht.threekt.objects.Mesh
|
import info.laht.threekt.objects.Mesh
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
@ -28,47 +30,63 @@ abstract class MeshThreeFactory<in T : VisualObject3D>(
|
|||||||
abstract fun buildGeometry(obj: T): BufferGeometry
|
abstract fun buildGeometry(obj: T): BufferGeometry
|
||||||
|
|
||||||
private fun Mesh.applyEdges(obj: T) {
|
private fun Mesh.applyEdges(obj: T) {
|
||||||
children.find { it.name == "edges" }?.let { remove(it) }
|
children.find { it.name == "edges" }?.let {
|
||||||
|
remove(it)
|
||||||
|
(it as LineSegments).dispose()
|
||||||
|
}
|
||||||
//inherited edges definition, enabled by default
|
//inherited edges definition, enabled by default
|
||||||
if (obj.getProperty(EDGES_ENABLED_KEY).boolean != false) {
|
if (obj.getProperty(EDGES_ENABLED_KEY).boolean != false) {
|
||||||
val material = obj.getProperty(EDGES_MATERIAL_KEY).node.jsLineMaterial()
|
|
||||||
|
val material = ThreeMaterials.getLineMaterial(obj.getProperty(EDGES_MATERIAL_KEY).node)
|
||||||
add(
|
add(
|
||||||
LineSegments(
|
LineSegments(
|
||||||
EdgesGeometry(geometry as BufferGeometry),
|
EdgesGeometry(geometry as BufferGeometry),
|
||||||
material
|
material
|
||||||
)
|
).apply {
|
||||||
|
name = "edges"
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Mesh.applyWireFrame(obj: T) {
|
private fun Mesh.applyWireFrame(obj: T) {
|
||||||
children.find { it.name == "wireframe" }?.let { remove(it) }
|
children.find { it.name == "wireframe" }?.let {
|
||||||
|
remove(it)
|
||||||
|
(it as LineSegments).dispose()
|
||||||
|
}
|
||||||
//inherited wireframe definition, disabled by default
|
//inherited wireframe definition, disabled by default
|
||||||
if (obj.getProperty(WIREFRAME_ENABLED_KEY).boolean == true) {
|
if (obj.getProperty(WIREFRAME_ENABLED_KEY).boolean == true) {
|
||||||
val material = obj.getProperty(WIREFRAME_MATERIAL_KEY).node.jsLineMaterial()
|
val material = ThreeMaterials.getLineMaterial(obj.getProperty(WIREFRAME_MATERIAL_KEY).node)
|
||||||
add(
|
add(
|
||||||
LineSegments(
|
LineSegments(
|
||||||
WireframeGeometry(geometry as BufferGeometry),
|
WireframeGeometry(geometry as BufferGeometry),
|
||||||
material
|
material
|
||||||
)
|
).apply {
|
||||||
|
name = "wireframe"
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun invoke(obj: T): Mesh {
|
override fun invoke(obj: T): Mesh {
|
||||||
//TODO add caching for geometries using templates
|
|
||||||
val geometry = buildGeometry(obj)
|
val geometry = buildGeometry(obj)
|
||||||
|
|
||||||
//JS sometimes tries to pass Geometry as BufferGeometry
|
//JS sometimes tries to pass Geometry as BufferGeometry
|
||||||
@Suppress("USELESS_IS_CHECK") if (geometry !is BufferGeometry) error("BufferGeometry expected")
|
@Suppress("USELESS_IS_CHECK") if (geometry !is BufferGeometry) error("BufferGeometry expected")
|
||||||
|
|
||||||
val mesh = Mesh(geometry, obj.material.jsMaterial()).apply {
|
val meshMeta: Meta = obj.properties[Material3D.MATERIAL_KEY]?.node ?: Meta.empty
|
||||||
|
|
||||||
|
val mesh = Mesh(geometry, MeshBasicMaterial()).apply {
|
||||||
matrixAutoUpdate = false
|
matrixAutoUpdate = false
|
||||||
applyEdges(obj)
|
applyEdges(obj)
|
||||||
applyWireFrame(obj)
|
applyWireFrame(obj)
|
||||||
|
|
||||||
//set position for mesh
|
//set position for mesh
|
||||||
updatePosition(obj)
|
updatePosition(obj)
|
||||||
|
|
||||||
|
//set color for mesh
|
||||||
|
updateMaterial(obj)
|
||||||
|
|
||||||
layers.enable(obj.layer)
|
layers.enable(obj.layer)
|
||||||
children.forEach {
|
children.forEach {
|
||||||
it.layers.enable(obj.layer)
|
it.layers.enable(obj.layer)
|
||||||
@ -78,7 +96,14 @@ abstract class MeshThreeFactory<in T : VisualObject3D>(
|
|||||||
//add listener to object properties
|
//add listener to object properties
|
||||||
obj.onPropertyChange(this) { name, _, _ ->
|
obj.onPropertyChange(this) { name, _, _ ->
|
||||||
when {
|
when {
|
||||||
name.startsWith(VisualObject3D.GEOMETRY_KEY) -> mesh.geometry = buildGeometry(obj)
|
name.startsWith(VisualObject3D.GEOMETRY_KEY) -> {
|
||||||
|
val oldGeometry = mesh.geometry as BufferGeometry
|
||||||
|
val newGeometry = buildGeometry(obj)
|
||||||
|
oldGeometry.attributes = newGeometry.attributes
|
||||||
|
mesh.applyWireFrame(obj)
|
||||||
|
mesh.applyEdges(obj)
|
||||||
|
newGeometry.dispose()
|
||||||
|
}
|
||||||
name.startsWith(WIREFRAME_KEY) -> mesh.applyWireFrame(obj)
|
name.startsWith(WIREFRAME_KEY) -> mesh.applyWireFrame(obj)
|
||||||
name.startsWith(EDGES_KEY) -> mesh.applyEdges(obj)
|
name.startsWith(EDGES_KEY) -> mesh.applyEdges(obj)
|
||||||
else -> mesh.updateProperty(obj, name)
|
else -> mesh.updateProperty(obj, name)
|
||||||
|
@ -55,8 +55,7 @@ operator fun <T : VisualObject3D> ThreeFactory<T>.invoke(obj: Any): Object3D {
|
|||||||
*/
|
*/
|
||||||
fun Object3D.updateProperty(source: VisualObject, propertyName: Name) {
|
fun Object3D.updateProperty(source: VisualObject, propertyName: Name) {
|
||||||
if (this is Mesh && propertyName.startsWith(MATERIAL_KEY)) {
|
if (this is Mesh && propertyName.startsWith(MATERIAL_KEY)) {
|
||||||
//updated material
|
updateMaterial(source)
|
||||||
material = source.material.jsMaterial()
|
|
||||||
} else if (
|
} else if (
|
||||||
source is VisualObject3D &&
|
source is VisualObject3D &&
|
||||||
(propertyName.startsWith(VisualObject3D.position)
|
(propertyName.startsWith(VisualObject3D.position)
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package hep.dataforge.vis.spatial.three
|
package hep.dataforge.vis.spatial.three
|
||||||
|
|
||||||
|
import hep.dataforge.meta.node
|
||||||
import hep.dataforge.vis.spatial.PolyLine
|
import hep.dataforge.vis.spatial.PolyLine
|
||||||
import hep.dataforge.vis.spatial.layer
|
import hep.dataforge.vis.spatial.layer
|
||||||
import hep.dataforge.vis.spatial.material
|
|
||||||
import info.laht.threekt.core.Geometry
|
import info.laht.threekt.core.Geometry
|
||||||
import info.laht.threekt.core.Object3D
|
import info.laht.threekt.core.Object3D
|
||||||
import info.laht.threekt.objects.LineSegments
|
import info.laht.threekt.objects.LineSegments
|
||||||
@ -16,7 +16,8 @@ object ThreeLineFactory : ThreeFactory<PolyLine> {
|
|||||||
vertices = obj.points.toTypedArray()
|
vertices = obj.points.toTypedArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
val material = obj.material.jsLineMaterial()
|
val material =
|
||||||
|
ThreeMaterials.getLineMaterial(obj.getProperty(MeshThreeFactory.EDGES_MATERIAL_KEY).node)
|
||||||
return LineSegments(geometry, material).apply {
|
return LineSegments(geometry, material).apply {
|
||||||
|
|
||||||
updatePosition(obj)
|
updatePosition(obj)
|
||||||
|
@ -0,0 +1,103 @@
|
|||||||
|
package hep.dataforge.vis.spatial.three
|
||||||
|
|
||||||
|
import hep.dataforge.meta.*
|
||||||
|
import hep.dataforge.values.ValueType
|
||||||
|
import hep.dataforge.vis.common.Colors
|
||||||
|
import hep.dataforge.vis.common.VisualObject
|
||||||
|
import hep.dataforge.vis.spatial.Material3D
|
||||||
|
import info.laht.threekt.materials.LineBasicMaterial
|
||||||
|
import info.laht.threekt.materials.Material
|
||||||
|
import info.laht.threekt.materials.MeshBasicMaterial
|
||||||
|
import info.laht.threekt.materials.MeshPhongMaterial
|
||||||
|
import info.laht.threekt.math.Color
|
||||||
|
import info.laht.threekt.objects.Mesh
|
||||||
|
|
||||||
|
|
||||||
|
object ThreeMaterials {
|
||||||
|
val DEFAULT_COLOR = Color(Colors.darkgreen)
|
||||||
|
val DEFAULT = MeshPhongMaterial().apply {
|
||||||
|
color.set(DEFAULT_COLOR)
|
||||||
|
}
|
||||||
|
val DEFAULT_LINE_COLOR = Color(Colors.black)
|
||||||
|
val DEFAULT_LINE = LineBasicMaterial().apply {
|
||||||
|
color.set(DEFAULT_LINE_COLOR)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// private val materialCache = HashMap<Meta, Material>()
|
||||||
|
private val lineMaterialCache = HashMap<Meta?, Material>()
|
||||||
|
|
||||||
|
|
||||||
|
// fun buildMaterial(meta: Meta): Material =
|
||||||
|
// MeshBasicMaterial().apply {
|
||||||
|
// color = meta["color"]?.color() ?: DEFAULT_COLOR
|
||||||
|
// opacity = meta["opacity"]?.double ?: 1.0
|
||||||
|
// transparent = meta["transparent"].boolean ?: (opacity < 1.0)
|
||||||
|
// //node["specularColor"]?.let { specular = it.color() }
|
||||||
|
// //side = 2
|
||||||
|
// }
|
||||||
|
|
||||||
|
fun getLineMaterial(meta: Meta?): Material = lineMaterialCache.getOrPut(meta) {
|
||||||
|
LineBasicMaterial().apply {
|
||||||
|
color = meta["color"]?.color() ?: DEFAULT_LINE_COLOR
|
||||||
|
opacity = meta["opacity"].double ?: 1.0
|
||||||
|
transparent = meta["transparent"].boolean ?: (opacity < 1.0)
|
||||||
|
linewidth = meta["thickness"].double ?: 1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Infer color based on meta item
|
||||||
|
*/
|
||||||
|
fun MetaItem<*>.color(): Color {
|
||||||
|
return when (this) {
|
||||||
|
is MetaItem.ValueItem -> if (this.value.type == ValueType.STRING) {
|
||||||
|
Color(this.value.string)
|
||||||
|
} else {
|
||||||
|
val int = value.number.toInt()
|
||||||
|
Color(int)
|
||||||
|
}
|
||||||
|
is MetaItem.NodeItem -> {
|
||||||
|
Color(
|
||||||
|
node["red"]?.int ?: 0,
|
||||||
|
node["green"]?.int ?: 0,
|
||||||
|
node["blue"]?.int ?: 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///**
|
||||||
|
// * Infer Three material based on meta item
|
||||||
|
// */
|
||||||
|
//fun Meta?.jsMaterial(): Material {
|
||||||
|
// return if (this == null) {
|
||||||
|
// ThreeMaterials.DEFAULT
|
||||||
|
// } else {
|
||||||
|
// ThreeMaterials.buildMaterial(this)
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//fun Meta?.jsLineMaterial(): Material {
|
||||||
|
// return if (this == null) {
|
||||||
|
// ThreeMaterials.DEFAULT_LINE
|
||||||
|
// } else {
|
||||||
|
// ThreeMaterials.buildLineMaterial(this)
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
//fun Material3D?.jsMaterial(): Material = this?.config.jsMaterial()
|
||||||
|
//fun Material3D?.jsLineMaterial(): Material = this?.config.jsLineMaterial()
|
||||||
|
|
||||||
|
fun Mesh.updateMaterial(obj: VisualObject) {
|
||||||
|
val meta = obj.properties[Material3D.MATERIAL_KEY].node?:EmptyMeta
|
||||||
|
material = (material as? MeshBasicMaterial ?: MeshBasicMaterial()).apply {
|
||||||
|
color = meta["color"]?.color() ?: ThreeMaterials.DEFAULT_COLOR
|
||||||
|
opacity = meta["opacity"]?.double ?: 1.0
|
||||||
|
transparent = meta["transparent"].boolean ?: (opacity < 1.0)
|
||||||
|
needsUpdate = true
|
||||||
|
}
|
||||||
|
}
|
@ -36,6 +36,7 @@ class ThreePlugin : AbstractPlugin() {
|
|||||||
|
|
||||||
fun buildObject3D(obj: VisualObject3D): Object3D {
|
fun buildObject3D(obj: VisualObject3D): Object3D {
|
||||||
return when (obj) {
|
return when (obj) {
|
||||||
|
is ThreeVisualObject -> obj.toObject3D()
|
||||||
is Proxy -> proxyFactory(obj)
|
is Proxy -> proxyFactory(obj)
|
||||||
is VisualGroup3D -> {
|
is VisualGroup3D -> {
|
||||||
val group = ThreeGroup()
|
val group = ThreeGroup()
|
||||||
@ -85,7 +86,7 @@ class ThreePlugin : AbstractPlugin() {
|
|||||||
companion object : PluginFactory<ThreePlugin> {
|
companion object : PluginFactory<ThreePlugin> {
|
||||||
override val tag = PluginTag("visual.three", PluginTag.DATAFORGE_GROUP)
|
override val tag = PluginTag("visual.three", PluginTag.DATAFORGE_GROUP)
|
||||||
override val type = ThreePlugin::class
|
override val type = ThreePlugin::class
|
||||||
override fun invoke(meta: Meta,context: Context) = ThreePlugin()
|
override fun invoke(meta: Meta, context: Context) = ThreePlugin()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
@file:UseSerializers(Point3DSerializer::class)
|
||||||
|
|
||||||
|
package hep.dataforge.vis.spatial.three
|
||||||
|
|
||||||
|
import hep.dataforge.io.serialization.ConfigSerializer
|
||||||
|
import hep.dataforge.io.toMeta
|
||||||
|
import hep.dataforge.meta.Config
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
|
import hep.dataforge.vis.common.AbstractVisualObject
|
||||||
|
import hep.dataforge.vis.spatial.Point3D
|
||||||
|
import hep.dataforge.vis.spatial.Point3DSerializer
|
||||||
|
import hep.dataforge.vis.spatial.Visual3DPlugin
|
||||||
|
import hep.dataforge.vis.spatial.VisualObject3D
|
||||||
|
import info.laht.threekt.core.Object3D
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.UseSerializers
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A custom visual object that has its own Three.js renderer
|
||||||
|
*/
|
||||||
|
interface ThreeVisualObject : VisualObject3D {
|
||||||
|
fun toObject3D(): Object3D
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class CustomThreeVisualObject(val threeFactory: ThreeFactory<VisualObject3D>) : AbstractVisualObject(),
|
||||||
|
ThreeVisualObject {
|
||||||
|
override var position: Point3D? = null
|
||||||
|
override var rotation: Point3D? = null
|
||||||
|
override var scale: Point3D? = null
|
||||||
|
|
||||||
|
@Serializable(ConfigSerializer::class)
|
||||||
|
override var properties: Config? = null
|
||||||
|
|
||||||
|
override fun toMeta(): Meta = Visual3DPlugin.json.toJson(serializer(), this).toMeta()
|
||||||
|
|
||||||
|
override fun toObject3D(): Object3D = threeFactory(this)
|
||||||
|
|
||||||
|
}
|
@ -5,12 +5,13 @@ import hep.dataforge.meta.float
|
|||||||
import hep.dataforge.meta.get
|
import hep.dataforge.meta.get
|
||||||
import hep.dataforge.meta.node
|
import hep.dataforge.meta.node
|
||||||
import hep.dataforge.vis.spatial.*
|
import hep.dataforge.vis.spatial.*
|
||||||
import info.laht.threekt.core.BufferGeometry
|
import info.laht.threekt.core.*
|
||||||
import info.laht.threekt.core.Face3
|
import info.laht.threekt.external.controls.OrbitControls
|
||||||
import info.laht.threekt.core.Geometry
|
import info.laht.threekt.materials.Material
|
||||||
import info.laht.threekt.core.Object3D
|
|
||||||
import info.laht.threekt.math.Euler
|
import info.laht.threekt.math.Euler
|
||||||
import info.laht.threekt.math.Vector3
|
import info.laht.threekt.math.Vector3
|
||||||
|
import info.laht.threekt.objects.Mesh
|
||||||
|
import info.laht.threekt.textures.Texture
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility methods for three.kt.
|
* Utility methods for three.kt.
|
||||||
@ -65,3 +66,18 @@ fun CSG.toGeometry(): Geometry {
|
|||||||
geom.computeBoundingBox()
|
geom.computeBoundingBox()
|
||||||
return geom
|
return geom
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun Any.dispose() {
|
||||||
|
when (this) {
|
||||||
|
is Geometry -> dispose()
|
||||||
|
is BufferGeometry -> dispose()
|
||||||
|
is DirectGeometry -> dispose()
|
||||||
|
is Material -> dispose()
|
||||||
|
is Mesh -> {
|
||||||
|
geometry.dispose()
|
||||||
|
material.dispose()
|
||||||
|
}
|
||||||
|
is OrbitControls -> dispose()
|
||||||
|
is Texture -> dispose()
|
||||||
|
}
|
||||||
|
}
|
@ -7,3 +7,13 @@ dependencies {
|
|||||||
api(project(":dataforge-vis-spatial"))
|
api(project(":dataforge-vis-spatial"))
|
||||||
testCompile(kotlin("test-js"))
|
testCompile(kotlin("test-js"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kotlin{
|
||||||
|
target {
|
||||||
|
browser{
|
||||||
|
webpackTask {
|
||||||
|
sourceMaps = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,8 @@ import hep.dataforge.js.Application
|
|||||||
import hep.dataforge.js.startApplication
|
import hep.dataforge.js.startApplication
|
||||||
import hep.dataforge.vis.common.Colors
|
import hep.dataforge.vis.common.Colors
|
||||||
import hep.dataforge.vis.spatial.*
|
import hep.dataforge.vis.spatial.*
|
||||||
|
import hep.dataforge.vis.spatial.three.MeshThreeFactory.Companion.EDGES_ENABLED_KEY
|
||||||
|
import hep.dataforge.vis.spatial.three.MeshThreeFactory.Companion.WIREFRAME_ENABLED_KEY
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.isActive
|
import kotlinx.coroutines.isActive
|
||||||
@ -14,7 +16,6 @@ import kotlin.math.cos
|
|||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
|
||||||
private class ThreeDemoApp : Application {
|
private class ThreeDemoApp : Application {
|
||||||
|
|
||||||
override fun start(state: Map<String, Any>) {
|
override fun start(state: Map<String, Any>) {
|
||||||
@ -143,6 +144,28 @@ private class ThreeDemoApp : Application {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
demo("dynamicBox", "Dancing boxes") {
|
||||||
|
val boxes = (-10..10).flatMap { i ->
|
||||||
|
(-10..10).map { j ->
|
||||||
|
varBox(10, 10, 0, name = "cell_${i}_${j}") {
|
||||||
|
x = i * 10
|
||||||
|
y = j * 10
|
||||||
|
value = 128
|
||||||
|
setProperty(EDGES_ENABLED_KEY, false)
|
||||||
|
setProperty(WIREFRAME_ENABLED_KEY, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GlobalScope.launch {
|
||||||
|
while (isActive) {
|
||||||
|
delay(200)
|
||||||
|
boxes.forEach { box ->
|
||||||
|
box.value = (box.value + Random.nextInt(-15, 15)).coerceIn(0..255)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,69 @@
|
|||||||
|
@file:UseSerializers(Point3DSerializer::class)
|
||||||
|
|
||||||
|
package hep.dataforge.vis.spatial.demo
|
||||||
|
|
||||||
|
import hep.dataforge.meta.int
|
||||||
|
import hep.dataforge.meta.number
|
||||||
|
import hep.dataforge.names.plus
|
||||||
|
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 info.laht.threekt.core.BufferGeometry
|
||||||
|
import info.laht.threekt.geometries.BoxBufferGeometry
|
||||||
|
import kotlinx.serialization.UseSerializers
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
|
private val BOX_Z_SIZE_KEY = GEOMETRY_KEY + "zSize"
|
||||||
|
|
||||||
|
internal var VisualObject3D.variableZSize: Number
|
||||||
|
get() = getProperty(BOX_Z_SIZE_KEY, false).number ?: 0f
|
||||||
|
set(value) {
|
||||||
|
setProperty(BOX_Z_SIZE_KEY, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal var VisualObject3D.value: Int
|
||||||
|
get() = getProperty("value", false).int ?: 0
|
||||||
|
set(value) {
|
||||||
|
setProperty("value", value)
|
||||||
|
val size = value.toFloat() / 255f * 20f
|
||||||
|
variableZSize = size
|
||||||
|
z = -size / 2
|
||||||
|
|
||||||
|
val b = max(0, 255 - value)
|
||||||
|
val r = max(0, value - 255)
|
||||||
|
val g = 255 - b - r
|
||||||
|
color(r.toUByte(), g.toUByte(), b.toUByte())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun VisualGroup3D.varBox(
|
||||||
|
xSize: Number,
|
||||||
|
ySize: Number,
|
||||||
|
zSize: Number,
|
||||||
|
name: String = "",
|
||||||
|
action: VisualObject3D.() -> Unit = {}
|
||||||
|
) = CustomThreeVisualObject(VariableBoxThreeFactory).apply {
|
||||||
|
setProperty(X_SIZE_KEY, xSize)
|
||||||
|
setProperty(Y_SIZE_KEY, ySize)
|
||||||
|
setProperty(Z_SIZE_KEY, zSize)
|
||||||
|
}.apply(action).also { set(name, it) }
|
||||||
|
|
||||||
|
private object VariableBoxThreeFactory : MeshThreeFactory<VisualObject3D>(VisualObject3D::class) {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user