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.SolidMaterial.Companion.MATERIAL_COLOR_KEY
|
||||
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.Object3D
|
||||
import info.laht.threekt.geometries.BoxBufferGeometry
|
||||
@ -31,8 +30,8 @@ internal class VariableBox(xSize: Number, ySize: Number, zSize: Number) : ThreeV
|
||||
scaleX = xSize
|
||||
scaleY = ySize
|
||||
scaleZ = zSize
|
||||
getProperty(MeshThreeFactory.EDGES_ENABLED_KEY, false)
|
||||
getProperty(MeshThreeFactory.WIREFRAME_ENABLED_KEY, false)
|
||||
// getProperty(MeshThreeFactory.EDGES_ENABLED_KEY, inherit = false, includeStyles = false)
|
||||
// getProperty(MeshThreeFactory.WIREFRAME_ENABLED_KEY, inherit = false, includeStyles = false)
|
||||
}
|
||||
|
||||
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
|
||||
@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)
|
||||
applyWireFrame(this@VariableBox)
|
||||
//applyWireFrame(this@VariableBox)
|
||||
|
||||
//set position for mesh
|
||||
updatePosition(this@VariableBox)
|
||||
@ -69,10 +69,10 @@ internal class VariableBox(xSize: Number, ySize: Number, zSize: Number) : ThreeV
|
||||
mesh.scale.set(newXSize, newYSize, newZSize)
|
||||
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(MATERIAL_COLOR_KEY) -> {
|
||||
mesh.material = getMaterial(this, true)
|
||||
mesh.updateMaterial(this)
|
||||
}
|
||||
else -> mesh.updateProperty(this@VariableBox, name)
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import hep.dataforge.meta.MetaItem
|
||||
import hep.dataforge.meta.MutableItemProvider
|
||||
import hep.dataforge.meta.descriptors.Described
|
||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||
import hep.dataforge.meta.descriptors.get
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.toName
|
||||
@ -45,8 +46,8 @@ public interface Vision : Described {
|
||||
*/
|
||||
public fun getProperty(
|
||||
name: Name,
|
||||
inherit: Boolean? = null,
|
||||
includeStyles: Boolean? = null,
|
||||
inherit: Boolean = false,
|
||||
includeStyles: Boolean = true,
|
||||
includeDefaults: Boolean = true,
|
||||
): MetaItem<*>?
|
||||
|
||||
@ -63,14 +64,15 @@ public interface Vision : Described {
|
||||
* if it should include inherited properties etc.
|
||||
*/
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
public val propertyChanges: Flow<Name> get() = callbackFlow<Name> {
|
||||
coroutineScope {
|
||||
onPropertyChange(this) {
|
||||
send(it)
|
||||
public val propertyChanges: Flow<Name>
|
||||
get() = callbackFlow<Name> {
|
||||
coroutineScope {
|
||||
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 {
|
||||
notifyPropertyChanged(propertyName)
|
||||
}
|
||||
@ -120,8 +122,8 @@ public fun Vision.allProperties(
|
||||
): MutableItemProvider = object : MutableItemProvider {
|
||||
override fun getItem(name: Name): MetaItem<*>? = getProperty(
|
||||
name,
|
||||
inherit = inherit,
|
||||
includeStyles = includeStyles,
|
||||
inherit = inherit ?: (descriptor?.get(name)?.inherited != false),
|
||||
includeStyles = includeStyles ?: (descriptor?.get(name)?.usesStyles == true),
|
||||
includeDefaults = includeDefaults
|
||||
)
|
||||
|
||||
@ -133,8 +135,8 @@ public fun Vision.allProperties(
|
||||
*/
|
||||
public fun Vision.getProperty(
|
||||
key: String,
|
||||
inherit: Boolean? = null,
|
||||
includeStyles: Boolean? = null,
|
||||
inherit: Boolean = false,
|
||||
includeStyles: Boolean = true,
|
||||
includeDefaults: Boolean = true,
|
||||
): MetaItem<*>? = getProperty(key.toName(), inherit, includeStyles, includeDefaults)
|
||||
|
||||
|
@ -65,15 +65,15 @@ public open class VisionBase : Vision {
|
||||
|
||||
override fun getProperty(
|
||||
name: Name,
|
||||
inherit: Boolean?,
|
||||
includeStyles: Boolean?,
|
||||
inherit: Boolean,
|
||||
includeStyles: Boolean,
|
||||
includeDefaults: Boolean,
|
||||
): MetaItem<*>? = sequence {
|
||||
yield(getOwnProperty(name))
|
||||
if (includeStyles ?: descriptor?.get(name)?.usesStyles != false) {
|
||||
if (includeStyles) {
|
||||
yieldAll(getStyleItems(name))
|
||||
}
|
||||
if (inherit ?: descriptor?.get(name)?.inherited == true) {
|
||||
if (inherit) {
|
||||
yield(parent?.getProperty(name, inherit, includeStyles, includeDefaults))
|
||||
}
|
||||
yield(descriptor?.get(name)?.defaultItem())
|
||||
|
@ -6,15 +6,13 @@ import hep.dataforge.values.asValue
|
||||
@DslMarker
|
||||
public annotation class VisionBuilder
|
||||
|
||||
public fun Sequence<MetaItem<*>?>.merge(): MetaItem<*>? {
|
||||
return when (val first = firstOrNull { it != null }) {
|
||||
null -> null
|
||||
is MetaItem.ValueItem -> first //fast search for first entry if it is value
|
||||
is MetaItem.NodeItem -> {
|
||||
//merge nodes if first encountered node is meta
|
||||
val laminate: Laminate = Laminate(mapNotNull { it.node }.toList())
|
||||
MetaItem.NodeItem(laminate)
|
||||
}
|
||||
public fun Sequence<MetaItem<*>?>.merge(): MetaItem<*>? = when (val first = firstOrNull { it != null }) {
|
||||
null -> null
|
||||
is MetaItem.ValueItem -> first //fast search for first entry if it is value
|
||||
is MetaItem.NodeItem -> {
|
||||
//merge nodes if first encountered node is meta
|
||||
val laminate: Laminate = Laminate(mapNotNull { it.node }.toList())
|
||||
MetaItem.NodeItem(laminate)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,8 +109,8 @@ internal class Prototypes(
|
||||
|
||||
override fun getProperty(
|
||||
name: Name,
|
||||
inherit: Boolean?,
|
||||
includeStyles: Boolean?,
|
||||
inherit: Boolean,
|
||||
includeStyles: Boolean,
|
||||
includeDefaults: Boolean,
|
||||
): MetaItem<*>? = null
|
||||
|
||||
|
@ -2,7 +2,6 @@ package hep.dataforge.vision.solid
|
||||
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||
import hep.dataforge.meta.descriptors.get
|
||||
import hep.dataforge.names.*
|
||||
import hep.dataforge.vision.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@ -15,17 +14,17 @@ public interface SolidReference : Vision {
|
||||
|
||||
private fun SolidReference.getRefProperty(
|
||||
name: Name,
|
||||
inherit: Boolean?,
|
||||
includeStyles: Boolean?,
|
||||
inherit: Boolean,
|
||||
includeStyles: Boolean,
|
||||
includeDefaults: Boolean,
|
||||
): MetaItem<*>? {
|
||||
return sequence {
|
||||
yield(getOwnProperty(name))
|
||||
if (includeStyles ?: descriptor?.get(name)?.usesStyles != false) {
|
||||
if (includeStyles) {
|
||||
yieldAll(getStyleItems(name))
|
||||
}
|
||||
yield(prototype.getProperty(name, inherit, includeStyles, includeDefaults))
|
||||
if (inherit ?: descriptor?.get(name)?.inherited == true) {
|
||||
if (inherit) {
|
||||
yield(parent?.getProperty(name, inherit))
|
||||
}
|
||||
}.merge()
|
||||
@ -77,8 +76,8 @@ public class SolidReferenceGroup(
|
||||
|
||||
override fun getProperty(
|
||||
name: Name,
|
||||
inherit: Boolean?,
|
||||
includeStyles: Boolean?,
|
||||
inherit: Boolean,
|
||||
includeStyles: Boolean,
|
||||
includeDefaults: Boolean,
|
||||
): MetaItem<*>? = getRefProperty(name, inherit, includeStyles, includeDefaults)
|
||||
|
||||
@ -108,8 +107,8 @@ public class SolidReferenceGroup(
|
||||
|
||||
override fun getProperty(
|
||||
name: Name,
|
||||
inherit: Boolean?,
|
||||
includeStyles: Boolean?,
|
||||
inherit: Boolean,
|
||||
includeStyles: Boolean,
|
||||
includeDefaults: Boolean,
|
||||
): 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.SolidMaterial
|
||||
import hep.dataforge.vision.solid.layer
|
||||
import hep.dataforge.vision.solid.three.ThreeMaterials.getMaterial
|
||||
import info.laht.threekt.core.BufferGeometry
|
||||
import info.laht.threekt.geometries.EdgesGeometry
|
||||
import info.laht.threekt.geometries.WireframeGeometry
|
||||
import info.laht.threekt.objects.LineSegments
|
||||
import info.laht.threekt.objects.Mesh
|
||||
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 mesh = Mesh(geometry, null).apply {
|
||||
val mesh = Mesh(geometry, ThreeMaterials.DEFAULT).apply {
|
||||
matrixAutoUpdate = false
|
||||
//set position for mesh
|
||||
updatePosition(obj)
|
||||
@ -49,11 +47,11 @@ public abstract class MeshThreeFactory<in T : Solid>(
|
||||
val oldGeometry = mesh.geometry as BufferGeometry
|
||||
val newGeometry = buildGeometry(obj)
|
||||
oldGeometry.attributes = newGeometry.attributes
|
||||
mesh.applyWireFrame(obj)
|
||||
//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)
|
||||
else -> mesh.updateProperty(obj, name)
|
||||
}
|
||||
@ -64,19 +62,19 @@ public abstract class MeshThreeFactory<in T : Solid>(
|
||||
|
||||
public companion object {
|
||||
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 EDGES_ENABLED_KEY: Name = EDGES_KEY + ENABLED_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_MATERIAL_KEY: Name = WIREFRAME_KEY + SolidMaterial.MATERIAL_KEY
|
||||
//public val WIREFRAME_ENABLED_KEY: Name = WIREFRAME_KEY + ENABLED_KEY
|
||||
//public val WIREFRAME_MATERIAL_KEY: Name = WIREFRAME_KEY + SolidMaterial.MATERIAL_KEY
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Mesh.applyProperties(obj: Solid): Mesh = apply {
|
||||
material = getMaterial(obj, true)
|
||||
updateMaterial(obj)
|
||||
applyEdges(obj)
|
||||
applyWireFrame(obj)
|
||||
//applyWireFrame(obj)
|
||||
layers.enable(obj.layer)
|
||||
children.forEach {
|
||||
it.layers.enable(obj.layer)
|
||||
@ -86,9 +84,16 @@ internal fun Mesh.applyProperties(obj: Solid): Mesh = apply {
|
||||
public fun Mesh.applyEdges(obj: Solid) {
|
||||
val edges = children.find { it.name == "@edges" } as? LineSegments
|
||||
//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 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) {
|
||||
add(
|
||||
LineSegments(
|
||||
@ -109,23 +114,23 @@ public fun Mesh.applyEdges(obj: Solid) {
|
||||
}
|
||||
}
|
||||
|
||||
public fun Mesh.applyWireFrame(obj: Solid) {
|
||||
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 bufferGeometry = geometry as? BufferGeometry ?: return
|
||||
val material =
|
||||
ThreeMaterials.getLineMaterial(obj.getProperty(MeshThreeFactory.WIREFRAME_MATERIAL_KEY).node, true)
|
||||
add(
|
||||
LineSegments(
|
||||
WireframeGeometry(bufferGeometry),
|
||||
material
|
||||
).apply {
|
||||
name = "@wireframe"
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
//public fun Mesh.applyWireFrame(obj: Solid) {
|
||||
// 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 bufferGeometry = geometry as? BufferGeometry ?: return
|
||||
// val material =
|
||||
// ThreeMaterials.getLineMaterial(obj.getProperty(MeshThreeFactory.WIREFRAME_MATERIAL_KEY).node, true)
|
||||
// add(
|
||||
// LineSegments(
|
||||
// WireframeGeometry(bufferGeometry),
|
||||
// material
|
||||
// ).apply {
|
||||
// name = "@wireframe"
|
||||
// }
|
||||
// )
|
||||
// }
|
||||
//}
|
@ -7,7 +7,6 @@ import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.solid.*
|
||||
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_KEY
|
||||
import hep.dataforge.vision.solid.three.ThreeFactory.Companion.TYPE
|
||||
import hep.dataforge.vision.solid.three.ThreeMaterials.getMaterial
|
||||
import hep.dataforge.vision.visible
|
||||
import info.laht.threekt.core.BufferGeometry
|
||||
import info.laht.threekt.core.Object3D
|
||||
@ -34,7 +33,7 @@ public interface ThreeFactory<in T : Vision> {
|
||||
*/
|
||||
public fun Object3D.updatePosition(obj: Vision) {
|
||||
visible = obj.visible ?: true
|
||||
if(obj is Solid) {
|
||||
if (obj is Solid) {
|
||||
position.set(obj.x, obj.y, obj.z)
|
||||
setRotationFromEuler(obj.euler)
|
||||
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) {
|
||||
if (this is Mesh && propertyName.startsWith(MATERIAL_KEY)) {
|
||||
this.material = getMaterial(source, true)
|
||||
updateMaterialProperty(source, propertyName)
|
||||
} else if (
|
||||
propertyName.startsWith(Solid.POSITION_KEY)
|
||||
|| propertyName.startsWith(Solid.ROTATION)
|
||||
|
@ -3,7 +3,6 @@ package hep.dataforge.vision.solid.three
|
||||
|
||||
import hep.dataforge.context.logger
|
||||
import hep.dataforge.vision.solid.SolidLabel
|
||||
import hep.dataforge.vision.solid.three.ThreeMaterials.getMaterial
|
||||
import info.laht.threekt.core.Object3D
|
||||
import info.laht.threekt.geometries.TextBufferGeometry
|
||||
import info.laht.threekt.objects.Mesh
|
||||
@ -23,11 +22,12 @@ public object ThreeLabelFactory : ThreeFactory<SolidLabel> {
|
||||
height = 1
|
||||
curveSegments = 1
|
||||
})
|
||||
return Mesh(textGeo, getMaterial(obj, true)).apply {
|
||||
return Mesh(textGeo, ThreeMaterials.DEFAULT).apply {
|
||||
updateMaterial(obj)
|
||||
updatePosition(obj)
|
||||
obj.onPropertyChange(three.updateScope){ _ ->
|
||||
obj.onPropertyChange(three.updateScope) { _ ->
|
||||
//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
|
||||
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.values.ValueType
|
||||
import hep.dataforge.values.int
|
||||
import hep.dataforge.values.string
|
||||
import hep.dataforge.vision.Colors
|
||||
import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.allStyles
|
||||
import hep.dataforge.vision.merge
|
||||
import hep.dataforge.vision.solid.SolidMaterial
|
||||
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
|
||||
|
||||
|
||||
public object ThreeMaterials {
|
||||
public val DEFAULT_COLOR: Color = Color(Colors.darkgreen)
|
||||
public val DEFAULT: MeshBasicMaterial = MeshBasicMaterial().apply {
|
||||
color.set(DEFAULT_COLOR)
|
||||
cached = true
|
||||
}
|
||||
public val DEFAULT_LINE_COLOR: Color = Color(Colors.black)
|
||||
public val DEFAULT_LINE: LineBasicMaterial = LineBasicMaterial().apply {
|
||||
@ -54,7 +59,7 @@ public object ThreeMaterials {
|
||||
|
||||
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) {
|
||||
MeshPhongMaterial().apply {
|
||||
color = meta[SolidMaterial.COLOR_KEY]?.getColor() ?: DEFAULT_COLOR
|
||||
@ -79,15 +84,26 @@ public object ThreeMaterials {
|
||||
}
|
||||
}
|
||||
|
||||
public fun getMaterial(vision3D: Vision, cache: Boolean): Material {
|
||||
val meta = vision3D.getProperty(SolidMaterial.MATERIAL_KEY, inherit = true).node ?: return DEFAULT
|
||||
return if (cache) {
|
||||
materialCache.getOrPut(meta) { buildMaterial(meta) }
|
||||
} else {
|
||||
buildMaterial(meta)
|
||||
internal fun cacheMeta(meta: Meta): Material = materialCache.getOrPut(meta) {
|
||||
buildMaterial(meta).apply {
|
||||
cached = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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 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.
|
||||
|
Loading…
Reference in New Issue
Block a user