forked from kscience/visionforge
Optimized materials allocation
This commit is contained in:
parent
eefc036dcb
commit
66ea23ad60
@ -11,7 +11,6 @@ import hep.dataforge.vision.solid.*
|
|||||||
import hep.dataforge.vision.solid.Solid.Companion.GEOMETRY_KEY
|
import hep.dataforge.vision.solid.Solid.Companion.GEOMETRY_KEY
|
||||||
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY
|
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY
|
||||||
import hep.dataforge.vision.solid.three.*
|
import hep.dataforge.vision.solid.three.*
|
||||||
import hep.dataforge.vision.solid.three.ThreeMaterials.getMaterial
|
|
||||||
import info.laht.threekt.core.BufferGeometry
|
import info.laht.threekt.core.BufferGeometry
|
||||||
import info.laht.threekt.core.Object3D
|
import info.laht.threekt.core.Object3D
|
||||||
import info.laht.threekt.geometries.BoxBufferGeometry
|
import info.laht.threekt.geometries.BoxBufferGeometry
|
||||||
@ -31,8 +30,8 @@ internal class VariableBox(xSize: Number, ySize: Number, zSize: Number) : ThreeV
|
|||||||
scaleX = xSize
|
scaleX = xSize
|
||||||
scaleY = ySize
|
scaleY = ySize
|
||||||
scaleZ = zSize
|
scaleZ = zSize
|
||||||
getProperty(MeshThreeFactory.EDGES_ENABLED_KEY, false)
|
// getProperty(MeshThreeFactory.EDGES_ENABLED_KEY, inherit = false, includeStyles = false)
|
||||||
getProperty(MeshThreeFactory.WIREFRAME_ENABLED_KEY, false)
|
// getProperty(MeshThreeFactory.WIREFRAME_ENABLED_KEY, inherit = false, includeStyles = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun render(three: ThreePlugin): Object3D {
|
override fun render(three: ThreePlugin): Object3D {
|
||||||
@ -44,9 +43,10 @@ internal class VariableBox(xSize: Number, ySize: Number, zSize: Number) : ThreeV
|
|||||||
//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, getMaterial(this@VariableBox, true)).apply {
|
val mesh = Mesh(geometry, ThreeMaterials.DEFAULT).apply {
|
||||||
|
updateMaterial(this@VariableBox)
|
||||||
applyEdges(this@VariableBox)
|
applyEdges(this@VariableBox)
|
||||||
applyWireFrame(this@VariableBox)
|
//applyWireFrame(this@VariableBox)
|
||||||
|
|
||||||
//set position for mesh
|
//set position for mesh
|
||||||
updatePosition(this@VariableBox)
|
updatePosition(this@VariableBox)
|
||||||
@ -69,10 +69,10 @@ internal class VariableBox(xSize: Number, ySize: Number, zSize: Number) : ThreeV
|
|||||||
mesh.scale.set(newXSize, newYSize, newZSize)
|
mesh.scale.set(newXSize, newYSize, newZSize)
|
||||||
mesh.updateMatrix()
|
mesh.updateMatrix()
|
||||||
}
|
}
|
||||||
name.startsWith(MeshThreeFactory.WIREFRAME_KEY) -> mesh.applyWireFrame(this@VariableBox)
|
//name.startsWith(MeshThreeFactory.WIREFRAME_KEY) -> mesh.applyWireFrame(this@VariableBox)
|
||||||
name.startsWith(MeshThreeFactory.EDGES_KEY) -> mesh.applyEdges(this@VariableBox)
|
name.startsWith(MeshThreeFactory.EDGES_KEY) -> mesh.applyEdges(this@VariableBox)
|
||||||
name.startsWith(MATERIAL_COLOR_KEY) -> {
|
name.startsWith(MATERIAL_COLOR_KEY) -> {
|
||||||
mesh.material = getMaterial(this, true)
|
mesh.updateMaterial(this)
|
||||||
}
|
}
|
||||||
else -> mesh.updateProperty(this@VariableBox, name)
|
else -> mesh.updateProperty(this@VariableBox, name)
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import hep.dataforge.meta.MetaItem
|
|||||||
import hep.dataforge.meta.MutableItemProvider
|
import hep.dataforge.meta.MutableItemProvider
|
||||||
import hep.dataforge.meta.descriptors.Described
|
import hep.dataforge.meta.descriptors.Described
|
||||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
|
import hep.dataforge.meta.descriptors.get
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
@ -45,8 +46,8 @@ public interface Vision : Described {
|
|||||||
*/
|
*/
|
||||||
public fun getProperty(
|
public fun getProperty(
|
||||||
name: Name,
|
name: Name,
|
||||||
inherit: Boolean? = null,
|
inherit: Boolean = false,
|
||||||
includeStyles: Boolean? = null,
|
includeStyles: Boolean = true,
|
||||||
includeDefaults: Boolean = true,
|
includeDefaults: Boolean = true,
|
||||||
): MetaItem<*>?
|
): MetaItem<*>?
|
||||||
|
|
||||||
@ -63,14 +64,15 @@ public interface Vision : Described {
|
|||||||
* if it should include inherited properties etc.
|
* if it should include inherited properties etc.
|
||||||
*/
|
*/
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
public val propertyChanges: Flow<Name> get() = callbackFlow<Name> {
|
public val propertyChanges: Flow<Name>
|
||||||
coroutineScope {
|
get() = callbackFlow<Name> {
|
||||||
onPropertyChange(this) {
|
coroutineScope {
|
||||||
send(it)
|
onPropertyChange(this) {
|
||||||
|
send(it)
|
||||||
|
}
|
||||||
|
awaitClose { cancel() }
|
||||||
}
|
}
|
||||||
awaitClose { cancel() }
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -93,7 +95,7 @@ public interface Vision : Described {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun Vision.asyncNotifyPropertyChange(propertyName: Name){
|
public fun Vision.asyncNotifyPropertyChange(propertyName: Name) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
notifyPropertyChanged(propertyName)
|
notifyPropertyChanged(propertyName)
|
||||||
}
|
}
|
||||||
@ -120,8 +122,8 @@ public fun Vision.allProperties(
|
|||||||
): MutableItemProvider = object : MutableItemProvider {
|
): MutableItemProvider = object : MutableItemProvider {
|
||||||
override fun getItem(name: Name): MetaItem<*>? = getProperty(
|
override fun getItem(name: Name): MetaItem<*>? = getProperty(
|
||||||
name,
|
name,
|
||||||
inherit = inherit,
|
inherit = inherit ?: (descriptor?.get(name)?.inherited != false),
|
||||||
includeStyles = includeStyles,
|
includeStyles = includeStyles ?: (descriptor?.get(name)?.usesStyles == true),
|
||||||
includeDefaults = includeDefaults
|
includeDefaults = includeDefaults
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -133,8 +135,8 @@ public fun Vision.allProperties(
|
|||||||
*/
|
*/
|
||||||
public fun Vision.getProperty(
|
public fun Vision.getProperty(
|
||||||
key: String,
|
key: String,
|
||||||
inherit: Boolean? = null,
|
inherit: Boolean = false,
|
||||||
includeStyles: Boolean? = null,
|
includeStyles: Boolean = true,
|
||||||
includeDefaults: Boolean = true,
|
includeDefaults: Boolean = true,
|
||||||
): MetaItem<*>? = getProperty(key.toName(), inherit, includeStyles, includeDefaults)
|
): MetaItem<*>? = getProperty(key.toName(), inherit, includeStyles, includeDefaults)
|
||||||
|
|
||||||
|
@ -65,15 +65,15 @@ public open class VisionBase : Vision {
|
|||||||
|
|
||||||
override fun getProperty(
|
override fun getProperty(
|
||||||
name: Name,
|
name: Name,
|
||||||
inherit: Boolean?,
|
inherit: Boolean,
|
||||||
includeStyles: Boolean?,
|
includeStyles: Boolean,
|
||||||
includeDefaults: Boolean,
|
includeDefaults: Boolean,
|
||||||
): MetaItem<*>? = sequence {
|
): MetaItem<*>? = sequence {
|
||||||
yield(getOwnProperty(name))
|
yield(getOwnProperty(name))
|
||||||
if (includeStyles ?: descriptor?.get(name)?.usesStyles != false) {
|
if (includeStyles) {
|
||||||
yieldAll(getStyleItems(name))
|
yieldAll(getStyleItems(name))
|
||||||
}
|
}
|
||||||
if (inherit ?: descriptor?.get(name)?.inherited == true) {
|
if (inherit) {
|
||||||
yield(parent?.getProperty(name, inherit, includeStyles, includeDefaults))
|
yield(parent?.getProperty(name, inherit, includeStyles, includeDefaults))
|
||||||
}
|
}
|
||||||
yield(descriptor?.get(name)?.defaultItem())
|
yield(descriptor?.get(name)?.defaultItem())
|
||||||
|
@ -6,15 +6,13 @@ import hep.dataforge.values.asValue
|
|||||||
@DslMarker
|
@DslMarker
|
||||||
public annotation class VisionBuilder
|
public annotation class VisionBuilder
|
||||||
|
|
||||||
public fun Sequence<MetaItem<*>?>.merge(): MetaItem<*>? {
|
public fun Sequence<MetaItem<*>?>.merge(): MetaItem<*>? = when (val first = firstOrNull { it != null }) {
|
||||||
return when (val first = firstOrNull { it != null }) {
|
null -> null
|
||||||
null -> null
|
is MetaItem.ValueItem -> first //fast search for first entry if it is value
|
||||||
is MetaItem.ValueItem -> first //fast search for first entry if it is value
|
is MetaItem.NodeItem -> {
|
||||||
is MetaItem.NodeItem -> {
|
//merge nodes if first encountered node is meta
|
||||||
//merge nodes if first encountered node is meta
|
val laminate: Laminate = Laminate(mapNotNull { it.node }.toList())
|
||||||
val laminate: Laminate = Laminate(mapNotNull { it.node }.toList())
|
MetaItem.NodeItem(laminate)
|
||||||
MetaItem.NodeItem(laminate)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,8 +109,8 @@ internal class Prototypes(
|
|||||||
|
|
||||||
override fun getProperty(
|
override fun getProperty(
|
||||||
name: Name,
|
name: Name,
|
||||||
inherit: Boolean?,
|
inherit: Boolean,
|
||||||
includeStyles: Boolean?,
|
includeStyles: Boolean,
|
||||||
includeDefaults: Boolean,
|
includeDefaults: Boolean,
|
||||||
): MetaItem<*>? = null
|
): MetaItem<*>? = null
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ package hep.dataforge.vision.solid
|
|||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
import hep.dataforge.meta.descriptors.get
|
|
||||||
import hep.dataforge.names.*
|
import hep.dataforge.names.*
|
||||||
import hep.dataforge.vision.*
|
import hep.dataforge.vision.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@ -15,17 +14,17 @@ public interface SolidReference : Vision {
|
|||||||
|
|
||||||
private fun SolidReference.getRefProperty(
|
private fun SolidReference.getRefProperty(
|
||||||
name: Name,
|
name: Name,
|
||||||
inherit: Boolean?,
|
inherit: Boolean,
|
||||||
includeStyles: Boolean?,
|
includeStyles: Boolean,
|
||||||
includeDefaults: Boolean,
|
includeDefaults: Boolean,
|
||||||
): MetaItem<*>? {
|
): MetaItem<*>? {
|
||||||
return sequence {
|
return sequence {
|
||||||
yield(getOwnProperty(name))
|
yield(getOwnProperty(name))
|
||||||
if (includeStyles ?: descriptor?.get(name)?.usesStyles != false) {
|
if (includeStyles) {
|
||||||
yieldAll(getStyleItems(name))
|
yieldAll(getStyleItems(name))
|
||||||
}
|
}
|
||||||
yield(prototype.getProperty(name, inherit, includeStyles, includeDefaults))
|
yield(prototype.getProperty(name, inherit, includeStyles, includeDefaults))
|
||||||
if (inherit ?: descriptor?.get(name)?.inherited == true) {
|
if (inherit) {
|
||||||
yield(parent?.getProperty(name, inherit))
|
yield(parent?.getProperty(name, inherit))
|
||||||
}
|
}
|
||||||
}.merge()
|
}.merge()
|
||||||
@ -77,8 +76,8 @@ public class SolidReferenceGroup(
|
|||||||
|
|
||||||
override fun getProperty(
|
override fun getProperty(
|
||||||
name: Name,
|
name: Name,
|
||||||
inherit: Boolean?,
|
inherit: Boolean,
|
||||||
includeStyles: Boolean?,
|
includeStyles: Boolean,
|
||||||
includeDefaults: Boolean,
|
includeDefaults: Boolean,
|
||||||
): MetaItem<*>? = getRefProperty(name, inherit, includeStyles, includeDefaults)
|
): MetaItem<*>? = getRefProperty(name, inherit, includeStyles, includeDefaults)
|
||||||
|
|
||||||
@ -108,8 +107,8 @@ public class SolidReferenceGroup(
|
|||||||
|
|
||||||
override fun getProperty(
|
override fun getProperty(
|
||||||
name: Name,
|
name: Name,
|
||||||
inherit: Boolean?,
|
inherit: Boolean,
|
||||||
includeStyles: Boolean?,
|
includeStyles: Boolean,
|
||||||
includeDefaults: Boolean,
|
includeDefaults: Boolean,
|
||||||
): MetaItem<*>? = getRefProperty(name, inherit, includeStyles, includeDefaults)
|
): MetaItem<*>? = getRefProperty(name, inherit, includeStyles, includeDefaults)
|
||||||
|
|
||||||
|
@ -9,10 +9,8 @@ import hep.dataforge.names.startsWith
|
|||||||
import hep.dataforge.vision.solid.Solid
|
import hep.dataforge.vision.solid.Solid
|
||||||
import hep.dataforge.vision.solid.SolidMaterial
|
import hep.dataforge.vision.solid.SolidMaterial
|
||||||
import hep.dataforge.vision.solid.layer
|
import hep.dataforge.vision.solid.layer
|
||||||
import hep.dataforge.vision.solid.three.ThreeMaterials.getMaterial
|
|
||||||
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.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
|
||||||
@ -36,7 +34,7 @@ public abstract class MeshThreeFactory<in T : Solid>(
|
|||||||
|
|
||||||
//val meshMeta: Meta = obj.properties[Material3D.MATERIAL_KEY]?.node ?: Meta.empty
|
//val meshMeta: Meta = obj.properties[Material3D.MATERIAL_KEY]?.node ?: Meta.empty
|
||||||
|
|
||||||
val mesh = Mesh(geometry, null).apply {
|
val mesh = Mesh(geometry, ThreeMaterials.DEFAULT).apply {
|
||||||
matrixAutoUpdate = false
|
matrixAutoUpdate = false
|
||||||
//set position for mesh
|
//set position for mesh
|
||||||
updatePosition(obj)
|
updatePosition(obj)
|
||||||
@ -49,11 +47,11 @@ public abstract class MeshThreeFactory<in T : Solid>(
|
|||||||
val oldGeometry = mesh.geometry as BufferGeometry
|
val oldGeometry = mesh.geometry as BufferGeometry
|
||||||
val newGeometry = buildGeometry(obj)
|
val newGeometry = buildGeometry(obj)
|
||||||
oldGeometry.attributes = newGeometry.attributes
|
oldGeometry.attributes = newGeometry.attributes
|
||||||
mesh.applyWireFrame(obj)
|
//mesh.applyWireFrame(obj)
|
||||||
mesh.applyEdges(obj)
|
mesh.applyEdges(obj)
|
||||||
newGeometry.dispose()
|
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)
|
||||||
}
|
}
|
||||||
@ -64,19 +62,19 @@ public abstract class MeshThreeFactory<in T : Solid>(
|
|||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
public val EDGES_KEY: Name = "edges".asName()
|
public val EDGES_KEY: Name = "edges".asName()
|
||||||
public val WIREFRAME_KEY: Name = "wireframe".asName()
|
//public val WIREFRAME_KEY: Name = "wireframe".asName()
|
||||||
public val ENABLED_KEY: Name = "enabled".asName()
|
public val ENABLED_KEY: Name = "enabled".asName()
|
||||||
public val EDGES_ENABLED_KEY: Name = EDGES_KEY + ENABLED_KEY
|
public val EDGES_ENABLED_KEY: Name = EDGES_KEY + ENABLED_KEY
|
||||||
public val EDGES_MATERIAL_KEY: Name = EDGES_KEY + SolidMaterial.MATERIAL_KEY
|
public val EDGES_MATERIAL_KEY: Name = EDGES_KEY + SolidMaterial.MATERIAL_KEY
|
||||||
public val WIREFRAME_ENABLED_KEY: Name = WIREFRAME_KEY + ENABLED_KEY
|
//public val WIREFRAME_ENABLED_KEY: Name = WIREFRAME_KEY + ENABLED_KEY
|
||||||
public val WIREFRAME_MATERIAL_KEY: Name = WIREFRAME_KEY + SolidMaterial.MATERIAL_KEY
|
//public val WIREFRAME_MATERIAL_KEY: Name = WIREFRAME_KEY + SolidMaterial.MATERIAL_KEY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Mesh.applyProperties(obj: Solid): Mesh = apply {
|
internal fun Mesh.applyProperties(obj: Solid): Mesh = apply {
|
||||||
material = getMaterial(obj, true)
|
updateMaterial(obj)
|
||||||
applyEdges(obj)
|
applyEdges(obj)
|
||||||
applyWireFrame(obj)
|
//applyWireFrame(obj)
|
||||||
layers.enable(obj.layer)
|
layers.enable(obj.layer)
|
||||||
children.forEach {
|
children.forEach {
|
||||||
it.layers.enable(obj.layer)
|
it.layers.enable(obj.layer)
|
||||||
@ -86,9 +84,16 @@ internal fun Mesh.applyProperties(obj: Solid): Mesh = apply {
|
|||||||
public fun Mesh.applyEdges(obj: Solid) {
|
public fun Mesh.applyEdges(obj: Solid) {
|
||||||
val edges = children.find { it.name == "@edges" } as? LineSegments
|
val edges = children.find { it.name == "@edges" } as? LineSegments
|
||||||
//inherited edges definition, enabled by default
|
//inherited edges definition, enabled by default
|
||||||
if (obj.getProperty(MeshThreeFactory.EDGES_ENABLED_KEY).boolean != false) {
|
if (obj.getProperty(MeshThreeFactory.EDGES_ENABLED_KEY, inherit = true, includeStyles = true).boolean != false) {
|
||||||
val bufferGeometry = geometry as? BufferGeometry ?: return
|
val bufferGeometry = geometry as? BufferGeometry ?: return
|
||||||
val material = ThreeMaterials.getLineMaterial(obj.getProperty(MeshThreeFactory.EDGES_MATERIAL_KEY).node, true)
|
val material = ThreeMaterials.getLineMaterial(
|
||||||
|
obj.getProperty(
|
||||||
|
MeshThreeFactory.EDGES_MATERIAL_KEY,
|
||||||
|
inherit = true,
|
||||||
|
includeStyles = true
|
||||||
|
).node,
|
||||||
|
true
|
||||||
|
)
|
||||||
if (edges == null) {
|
if (edges == null) {
|
||||||
add(
|
add(
|
||||||
LineSegments(
|
LineSegments(
|
||||||
@ -109,23 +114,23 @@ public fun Mesh.applyEdges(obj: Solid) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun Mesh.applyWireFrame(obj: Solid) {
|
//public fun Mesh.applyWireFrame(obj: Solid) {
|
||||||
children.find { it.name == "@wireframe" }?.let {
|
// children.find { it.name == "@wireframe" }?.let {
|
||||||
remove(it)
|
// remove(it)
|
||||||
(it as LineSegments).dispose()
|
// (it as LineSegments).dispose()
|
||||||
}
|
// }
|
||||||
//inherited wireframe definition, disabled by default
|
// //inherited wireframe definition, disabled by default
|
||||||
if (obj.getProperty(MeshThreeFactory.WIREFRAME_ENABLED_KEY).boolean == true) {
|
// if (obj.getProperty(MeshThreeFactory.WIREFRAME_ENABLED_KEY).boolean == true) {
|
||||||
val bufferGeometry = geometry as? BufferGeometry ?: return
|
// val bufferGeometry = geometry as? BufferGeometry ?: return
|
||||||
val material =
|
// val material =
|
||||||
ThreeMaterials.getLineMaterial(obj.getProperty(MeshThreeFactory.WIREFRAME_MATERIAL_KEY).node, true)
|
// ThreeMaterials.getLineMaterial(obj.getProperty(MeshThreeFactory.WIREFRAME_MATERIAL_KEY).node, true)
|
||||||
add(
|
// add(
|
||||||
LineSegments(
|
// LineSegments(
|
||||||
WireframeGeometry(bufferGeometry),
|
// WireframeGeometry(bufferGeometry),
|
||||||
material
|
// material
|
||||||
).apply {
|
// ).apply {
|
||||||
name = "@wireframe"
|
// name = "@wireframe"
|
||||||
}
|
// }
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
}
|
//}
|
@ -7,7 +7,6 @@ import hep.dataforge.vision.Vision
|
|||||||
import hep.dataforge.vision.solid.*
|
import hep.dataforge.vision.solid.*
|
||||||
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_KEY
|
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_KEY
|
||||||
import hep.dataforge.vision.solid.three.ThreeFactory.Companion.TYPE
|
import hep.dataforge.vision.solid.three.ThreeFactory.Companion.TYPE
|
||||||
import hep.dataforge.vision.solid.three.ThreeMaterials.getMaterial
|
|
||||||
import hep.dataforge.vision.visible
|
import hep.dataforge.vision.visible
|
||||||
import info.laht.threekt.core.BufferGeometry
|
import info.laht.threekt.core.BufferGeometry
|
||||||
import info.laht.threekt.core.Object3D
|
import info.laht.threekt.core.Object3D
|
||||||
@ -34,7 +33,7 @@ public interface ThreeFactory<in T : Vision> {
|
|||||||
*/
|
*/
|
||||||
public fun Object3D.updatePosition(obj: Vision) {
|
public fun Object3D.updatePosition(obj: Vision) {
|
||||||
visible = obj.visible ?: true
|
visible = obj.visible ?: true
|
||||||
if(obj is Solid) {
|
if (obj is Solid) {
|
||||||
position.set(obj.x, obj.y, obj.z)
|
position.set(obj.x, obj.y, obj.z)
|
||||||
setRotationFromEuler(obj.euler)
|
setRotationFromEuler(obj.euler)
|
||||||
scale.set(obj.scaleX, obj.scaleY, obj.scaleZ)
|
scale.set(obj.scaleX, obj.scaleY, obj.scaleZ)
|
||||||
@ -47,7 +46,7 @@ public fun Object3D.updatePosition(obj: Vision) {
|
|||||||
*/
|
*/
|
||||||
public fun Object3D.updateProperty(source: Vision, propertyName: Name) {
|
public fun Object3D.updateProperty(source: Vision, propertyName: Name) {
|
||||||
if (this is Mesh && propertyName.startsWith(MATERIAL_KEY)) {
|
if (this is Mesh && propertyName.startsWith(MATERIAL_KEY)) {
|
||||||
this.material = getMaterial(source, true)
|
updateMaterialProperty(source, propertyName)
|
||||||
} else if (
|
} else if (
|
||||||
propertyName.startsWith(Solid.POSITION_KEY)
|
propertyName.startsWith(Solid.POSITION_KEY)
|
||||||
|| propertyName.startsWith(Solid.ROTATION)
|
|| propertyName.startsWith(Solid.ROTATION)
|
||||||
|
@ -3,7 +3,6 @@ package hep.dataforge.vision.solid.three
|
|||||||
|
|
||||||
import hep.dataforge.context.logger
|
import hep.dataforge.context.logger
|
||||||
import hep.dataforge.vision.solid.SolidLabel
|
import hep.dataforge.vision.solid.SolidLabel
|
||||||
import hep.dataforge.vision.solid.three.ThreeMaterials.getMaterial
|
|
||||||
import info.laht.threekt.core.Object3D
|
import info.laht.threekt.core.Object3D
|
||||||
import info.laht.threekt.geometries.TextBufferGeometry
|
import info.laht.threekt.geometries.TextBufferGeometry
|
||||||
import info.laht.threekt.objects.Mesh
|
import info.laht.threekt.objects.Mesh
|
||||||
@ -23,11 +22,12 @@ public object ThreeLabelFactory : ThreeFactory<SolidLabel> {
|
|||||||
height = 1
|
height = 1
|
||||||
curveSegments = 1
|
curveSegments = 1
|
||||||
})
|
})
|
||||||
return Mesh(textGeo, getMaterial(obj, true)).apply {
|
return Mesh(textGeo, ThreeMaterials.DEFAULT).apply {
|
||||||
|
updateMaterial(obj)
|
||||||
updatePosition(obj)
|
updatePosition(obj)
|
||||||
obj.onPropertyChange(three.updateScope){ _ ->
|
obj.onPropertyChange(three.updateScope) { _ ->
|
||||||
//TODO
|
//TODO
|
||||||
three.logger.warn{"Label parameter change not implemented"}
|
three.logger.warn { "Label parameter change not implemented" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,28 @@
|
|||||||
package hep.dataforge.vision.solid.three
|
package hep.dataforge.vision.solid.three
|
||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.values.ValueType
|
import hep.dataforge.values.ValueType
|
||||||
import hep.dataforge.values.int
|
import hep.dataforge.values.int
|
||||||
import hep.dataforge.values.string
|
import hep.dataforge.values.string
|
||||||
import hep.dataforge.vision.Colors
|
import hep.dataforge.vision.Colors
|
||||||
import hep.dataforge.vision.Vision
|
import hep.dataforge.vision.Vision
|
||||||
|
import hep.dataforge.vision.allStyles
|
||||||
|
import hep.dataforge.vision.merge
|
||||||
import hep.dataforge.vision.solid.SolidMaterial
|
import hep.dataforge.vision.solid.SolidMaterial
|
||||||
import info.laht.threekt.materials.LineBasicMaterial
|
import info.laht.threekt.materials.LineBasicMaterial
|
||||||
import info.laht.threekt.materials.Material
|
import info.laht.threekt.materials.Material
|
||||||
import info.laht.threekt.materials.MeshBasicMaterial
|
import info.laht.threekt.materials.MeshBasicMaterial
|
||||||
import info.laht.threekt.materials.MeshPhongMaterial
|
import info.laht.threekt.materials.MeshPhongMaterial
|
||||||
import info.laht.threekt.math.Color
|
import info.laht.threekt.math.Color
|
||||||
|
import info.laht.threekt.objects.Mesh
|
||||||
|
|
||||||
|
|
||||||
public object ThreeMaterials {
|
public object ThreeMaterials {
|
||||||
public val DEFAULT_COLOR: Color = Color(Colors.darkgreen)
|
public val DEFAULT_COLOR: Color = Color(Colors.darkgreen)
|
||||||
public val DEFAULT: MeshBasicMaterial = MeshBasicMaterial().apply {
|
public val DEFAULT: MeshBasicMaterial = MeshBasicMaterial().apply {
|
||||||
color.set(DEFAULT_COLOR)
|
color.set(DEFAULT_COLOR)
|
||||||
|
cached = true
|
||||||
}
|
}
|
||||||
public val DEFAULT_LINE_COLOR: Color = Color(Colors.black)
|
public val DEFAULT_LINE_COLOR: Color = Color(Colors.black)
|
||||||
public val DEFAULT_LINE: LineBasicMaterial = LineBasicMaterial().apply {
|
public val DEFAULT_LINE: LineBasicMaterial = LineBasicMaterial().apply {
|
||||||
@ -54,7 +59,7 @@ public object ThreeMaterials {
|
|||||||
|
|
||||||
private val materialCache = HashMap<Meta, Material>()
|
private val materialCache = HashMap<Meta, Material>()
|
||||||
|
|
||||||
private fun buildMaterial(meta: Meta): Material {
|
internal fun buildMaterial(meta: Meta): Material {
|
||||||
return if (meta[SolidMaterial.SPECULAR_COLOR_KEY] != null) {
|
return if (meta[SolidMaterial.SPECULAR_COLOR_KEY] != null) {
|
||||||
MeshPhongMaterial().apply {
|
MeshPhongMaterial().apply {
|
||||||
color = meta[SolidMaterial.COLOR_KEY]?.getColor() ?: DEFAULT_COLOR
|
color = meta[SolidMaterial.COLOR_KEY]?.getColor() ?: DEFAULT_COLOR
|
||||||
@ -79,15 +84,26 @@ public object ThreeMaterials {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun getMaterial(vision3D: Vision, cache: Boolean): Material {
|
internal fun cacheMeta(meta: Meta): Material = materialCache.getOrPut(meta) {
|
||||||
val meta = vision3D.getProperty(SolidMaterial.MATERIAL_KEY, inherit = true).node ?: return DEFAULT
|
buildMaterial(meta).apply {
|
||||||
return if (cache) {
|
cached = true
|
||||||
materialCache.getOrPut(meta) { buildMaterial(meta) }
|
|
||||||
} else {
|
|
||||||
buildMaterial(meta)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// internal fun getMaterial(vision: Vision, cache: Boolean): Material {
|
||||||
|
// val meta = vision.getProperty(SolidMaterial.MATERIAL_KEY, inherit = true).node ?: return DEFAULT
|
||||||
|
// return if (cache) {
|
||||||
|
// materialCache.getOrPut(meta) {
|
||||||
|
// buildMaterial(meta).apply {
|
||||||
|
// cached = true
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// buildMaterial(meta)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -111,3 +127,74 @@ public fun MetaItem<*>.getColor(): Color {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var Material.cached: Boolean
|
||||||
|
get() = userData["cached"] == true
|
||||||
|
set(value) {
|
||||||
|
userData["cached"] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun Mesh.updateMaterial(vision: Vision) {
|
||||||
|
//val meta = vision.getProperty(SolidMaterial.MATERIAL_KEY, inherit = true).node
|
||||||
|
val ownMaterialMeta = vision.getOwnProperty(SolidMaterial.MATERIAL_KEY)
|
||||||
|
val stylesMaterialMeta = vision.allStyles[SolidMaterial.MATERIAL_KEY]
|
||||||
|
val parentMaterialMeta = vision.parent?.getProperty(
|
||||||
|
SolidMaterial.MATERIAL_KEY,
|
||||||
|
inherit = true,
|
||||||
|
includeStyles = false,
|
||||||
|
includeDefaults = false
|
||||||
|
)
|
||||||
|
material = when {
|
||||||
|
ownMaterialMeta == null && stylesMaterialMeta == null && parentMaterialMeta == null -> {
|
||||||
|
//use default is not material properties are defined
|
||||||
|
ThreeMaterials.DEFAULT
|
||||||
|
}
|
||||||
|
ownMaterialMeta == null && parentMaterialMeta == null -> {
|
||||||
|
//If material is style-based, use cached
|
||||||
|
ThreeMaterials.cacheMeta(stylesMaterialMeta.node ?: Meta.EMPTY)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
val merge = sequenceOf(ownMaterialMeta, stylesMaterialMeta, parentMaterialMeta).merge().node ?: Meta.EMPTY
|
||||||
|
ThreeMaterials.buildMaterial(merge)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) {
|
||||||
|
if (material.cached) {
|
||||||
|
//generate a new material since cached material should not be changed
|
||||||
|
updateMaterial(vision)
|
||||||
|
} else {
|
||||||
|
when (propertyName) {
|
||||||
|
SolidMaterial.MATERIAL_COLOR_KEY -> {
|
||||||
|
material.asDynamic().color = vision.getProperty(
|
||||||
|
SolidMaterial.MATERIAL_COLOR_KEY,
|
||||||
|
inherit = true,
|
||||||
|
includeStyles = true,
|
||||||
|
includeDefaults = false
|
||||||
|
)?.getColor() ?: ThreeMaterials.DEFAULT_COLOR
|
||||||
|
material.needsUpdate = true
|
||||||
|
}
|
||||||
|
SolidMaterial.MATERIAL_OPACITY_KEY -> {
|
||||||
|
val opacity = vision.getProperty(
|
||||||
|
SolidMaterial.MATERIAL_OPACITY_KEY,
|
||||||
|
inherit = true,
|
||||||
|
includeStyles = true,
|
||||||
|
includeDefaults = false
|
||||||
|
).double ?: 1.0
|
||||||
|
material.asDynamic().opacity = opacity
|
||||||
|
material.transparent = opacity < 1.0
|
||||||
|
material.needsUpdate = true
|
||||||
|
}
|
||||||
|
SolidMaterial.MATERIAL_WIREFRAME_KEY -> {
|
||||||
|
material.asDynamic().wireframe = vision.getProperty(
|
||||||
|
SolidMaterial.MATERIAL_WIREFRAME_KEY,
|
||||||
|
inherit = true,
|
||||||
|
includeStyles = true,
|
||||||
|
includeDefaults = false
|
||||||
|
).boolean ?: false
|
||||||
|
material.needsUpdate = true
|
||||||
|
}
|
||||||
|
else -> console.warn("Unrecognized material property: $propertyName")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -111,7 +111,7 @@ open external class Material {
|
|||||||
|
|
||||||
var visible: Boolean
|
var visible: Boolean
|
||||||
|
|
||||||
var userData: Map<String, Any>
|
var userData: dynamic
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies that the material needs to be updated at the WebGL level. Set it to true if you made changes that need to be reflected in WebGL.
|
* Specifies that the material needs to be updated at the WebGL level. Set it to true if you made changes that need to be reflected in WebGL.
|
||||||
|
Loading…
Reference in New Issue
Block a user