Fix light for GDML and ambient lighg updates
This commit is contained in:
parent
56d577453a
commit
f0a6e12358
@ -1,20 +1,13 @@
|
||||
package space.kscience.visionforge.examples
|
||||
|
||||
import space.kscience.gdml.GdmlShowCase
|
||||
import space.kscience.visionforge.Colors
|
||||
import space.kscience.visionforge.gdml.toVision
|
||||
import space.kscience.visionforge.html.ResourceLocation
|
||||
import space.kscience.visionforge.solid.Solids
|
||||
import space.kscience.visionforge.solid.ambientLight
|
||||
import space.kscience.visionforge.solid.set
|
||||
|
||||
fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) {
|
||||
vision("canvas") {
|
||||
requirePlugin(Solids)
|
||||
GdmlShowCase.cubes().toVision().also {
|
||||
it.ambientLight {
|
||||
color.set(Colors.white)
|
||||
}
|
||||
}
|
||||
GdmlShowCase.cubes().toVision()
|
||||
}
|
||||
}
|
@ -223,7 +223,7 @@ fun main() = makeVisionFile(Path.of("curves.html"), resourceLocation = ResourceL
|
||||
}
|
||||
}
|
||||
}.toVision {
|
||||
configure { _, solid, _ ->
|
||||
solids { _, solid, _ ->
|
||||
//disable visibility for the world box
|
||||
if(solid.name == "world"){
|
||||
visible = false
|
||||
|
@ -4,9 +4,7 @@ import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.dataforge.meta.MutableMeta
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.gdml.*
|
||||
import space.kscience.visionforge.solid.Solid
|
||||
import space.kscience.visionforge.solid.SolidMaterial
|
||||
import space.kscience.visionforge.solid.set
|
||||
import space.kscience.visionforge.solid.*
|
||||
import space.kscience.visionforge.useStyle
|
||||
import kotlin.random.Random
|
||||
|
||||
@ -70,7 +68,7 @@ public class GdmlLoaderOptions {
|
||||
}
|
||||
private set
|
||||
|
||||
public fun configure(block: Solid.(parent: GdmlVolume, solid: GdmlSolid, material: GdmlMaterial) -> Unit) {
|
||||
public fun solids(block: Solid.(parent: GdmlVolume, solid: GdmlSolid, material: GdmlMaterial) -> Unit) {
|
||||
val oldConfigure = configureSolid
|
||||
configureSolid = { parent: GdmlVolume, solid: GdmlSolid, material: GdmlMaterial ->
|
||||
oldConfigure(parent, solid, material)
|
||||
@ -79,6 +77,8 @@ public class GdmlLoaderOptions {
|
||||
}
|
||||
|
||||
|
||||
public var light: LightSource? = AmbientLightSource()
|
||||
|
||||
public companion object {
|
||||
private val random: Random = Random(222)
|
||||
|
||||
|
@ -27,10 +27,10 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
||||
/**
|
||||
* A special group for local templates
|
||||
*/
|
||||
private val proto = SolidGroup()
|
||||
private val templates = SolidGroup()
|
||||
|
||||
private val solids = proto.solidGroup(solidsName) {
|
||||
properties["edges.enabled"] = false
|
||||
private val solids = templates.solidGroup(solidsName) {
|
||||
edges(false)
|
||||
}
|
||||
|
||||
private val referenceStore = HashMap<Name, MutableList<SolidReference>>()
|
||||
@ -46,7 +46,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
||||
|
||||
private fun proxySolid(root: Gdml, group: SolidGroup, solid: GdmlSolid, name: String): SolidReference {
|
||||
val templateName = solidsName + name
|
||||
if (proto[templateName] == null) {
|
||||
if (templates[templateName] == null) {
|
||||
solids.addSolid(root, solid, name)
|
||||
}
|
||||
val ref = group.ref(templateName, name)
|
||||
@ -61,8 +61,8 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
||||
volume: GdmlGroup,
|
||||
): SolidReference {
|
||||
val templateName = volumesName + volume.name.asName()
|
||||
if (proto[templateName] == null) {
|
||||
proto.setChild(templateName, volume(root, volume))
|
||||
if (templates[templateName] == null) {
|
||||
templates.setChild(templateName, volume(root, volume))
|
||||
}
|
||||
val ref = group.ref(templateName, physVolume.name).withPosition(root, physVolume)
|
||||
referenceStore.getOrPut(templateName) { ArrayList() }.add(ref)
|
||||
@ -139,6 +139,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
||||
angle = solid.deltaphi * aScale,
|
||||
name = name
|
||||
)
|
||||
|
||||
is GdmlCone -> if (solid.rmin1.toDouble() == 0.0 && solid.rmin2.toDouble() == 0.0) {
|
||||
cone(
|
||||
bottomRadius = solid.rmax1 * lScale,
|
||||
@ -160,6 +161,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
||||
name = name
|
||||
)
|
||||
}
|
||||
|
||||
is GdmlXtru -> extruded(name) {
|
||||
shape {
|
||||
solid.vertices.forEach {
|
||||
@ -175,6 +177,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
is GdmlScaledSolid -> {
|
||||
//Add solid with modified scale
|
||||
val innerSolid: GdmlSolid = solid.solidref.resolve(root)
|
||||
@ -186,6 +189,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
||||
scaleZ = solid.scale.z.toFloat()
|
||||
}
|
||||
}
|
||||
|
||||
is GdmlSphere -> sphereLayer(
|
||||
outerRadius = solid.rmax * lScale,
|
||||
innerRadius = solid.rmin * lScale,
|
||||
@ -195,6 +199,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
||||
thetaStart = solid.starttheta * aScale,
|
||||
name = name,
|
||||
)
|
||||
|
||||
is GdmlOrb -> sphere(solid.r * lScale, name = name)
|
||||
is GdmlPolyhedra -> extruded(name) {
|
||||
//getting the radius of first
|
||||
@ -211,6 +216,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
||||
layer(plane.z * lScale, scale = plane.rmax * lScale / baseRadius)
|
||||
}
|
||||
}
|
||||
|
||||
is GdmlBoolSolid -> {
|
||||
val first: GdmlSolid = solid.first.resolve(root) ?: error("")
|
||||
val second: GdmlSolid = solid.second.resolve(root) ?: error("")
|
||||
@ -235,6 +241,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
is GdmlTrapezoid -> {
|
||||
val dxBottom = solid.x1.toDouble() / 2
|
||||
val dxTop = solid.x2.toDouble() / 2
|
||||
@ -251,6 +258,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
||||
val node8 = Point3D(-dxTop, dyTop, dz)
|
||||
hexagon(node1, node2, node3, node4, node5, node6, node7, node8, name)
|
||||
}
|
||||
|
||||
is GdmlEllipsoid -> TODO("Renderer for $solid not supported yet")
|
||||
is GdmlElTube -> TODO("Renderer for $solid not supported yet")
|
||||
is GdmlElCone -> TODO("Renderer for $solid not supported yet")
|
||||
@ -271,9 +279,11 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
||||
GdmlLoaderOptions.Action.ADD -> {
|
||||
addSolid(root, solid, name)
|
||||
}
|
||||
|
||||
GdmlLoaderOptions.Action.PROTOTYPE -> {
|
||||
proxySolid(root, this, solid, name ?: solid.name)
|
||||
}
|
||||
|
||||
GdmlLoaderOptions.Action.REJECT -> {
|
||||
//ignore
|
||||
null
|
||||
@ -304,9 +314,11 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
||||
val group: SolidGroup = volume(root, volume)
|
||||
this.setChild(physVolume.name, group.withPosition(root, physVolume))
|
||||
}
|
||||
|
||||
GdmlLoaderOptions.Action.PROTOTYPE -> {
|
||||
proxyVolume(root, this, physVolume, volume)
|
||||
}
|
||||
|
||||
GdmlLoaderOptions.Action.REJECT -> {
|
||||
//ignore
|
||||
}
|
||||
@ -348,35 +360,36 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun finalize(final: SolidGroup): SolidGroup {
|
||||
val rootStyle by final.style("gdml") {
|
||||
fun transform(root: Gdml): SolidGroup {
|
||||
val rootSolid = volume(root, root.world.resolve(root) ?: error("GDML root is not resolved"))
|
||||
|
||||
val rootStyle by rootSolid.style("gdml") {
|
||||
Solid.ROTATION_ORDER_KEY put RotationOrder.ZXY
|
||||
}
|
||||
final.useStyle(rootStyle, false)
|
||||
|
||||
final.prototypes {
|
||||
proto.items.forEach { (token, item) ->
|
||||
rootSolid.useStyle(rootStyle, false)
|
||||
|
||||
rootSolid.prototypes {
|
||||
templates.items.forEach { (token, item) ->
|
||||
item.parent = null
|
||||
setChild(token.asName(), item as? Solid)
|
||||
}
|
||||
}
|
||||
settings.styleCache.forEach {
|
||||
final.styleSheet {
|
||||
rootSolid.styleSheet {
|
||||
define(it.key.toString(), it.value)
|
||||
}
|
||||
}
|
||||
return final
|
||||
return rootSolid
|
||||
}
|
||||
|
||||
fun transform(root: Gdml): SolidGroup =
|
||||
finalize(volume(root, root.world.resolve(root) ?: error("GDML root is not resolved")))
|
||||
}
|
||||
|
||||
|
||||
public fun Gdml.toVision(block: GdmlLoaderOptions.() -> Unit = {}): SolidGroup {
|
||||
val settings = GdmlLoaderOptions().apply(block)
|
||||
val context = GdmlLoader(settings)
|
||||
return context.transform(this)
|
||||
return GdmlLoader(settings).transform(this).also {
|
||||
it.children["light"] = settings.light
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -28,8 +28,10 @@ public class ColorAccessor(
|
||||
}
|
||||
}
|
||||
|
||||
public fun Vision.color(): ReadOnlyProperty<Vision, ColorAccessor> = ReadOnlyProperty { _, property ->
|
||||
ColorAccessor(properties.root(true), property.name.asName())
|
||||
public fun Vision.color(
|
||||
propertyName: Name? = null,
|
||||
): ReadOnlyProperty<Vision, ColorAccessor> = ReadOnlyProperty { _, property ->
|
||||
ColorAccessor(properties.root(true), propertyName ?: property.name.asName())
|
||||
}
|
||||
|
||||
public var ColorAccessor?.string: String?
|
||||
|
@ -7,16 +7,20 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
||||
import space.kscience.dataforge.meta.descriptors.node
|
||||
import space.kscience.dataforge.meta.descriptors.value
|
||||
import space.kscience.dataforge.meta.number
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.asName
|
||||
import space.kscience.visionforge.*
|
||||
|
||||
@Serializable
|
||||
public abstract class LightSource : SolidBase<LightSource>() {
|
||||
override val descriptor: MetaDescriptor get() = LightSource.descriptor
|
||||
|
||||
public val color: ColorAccessor by color()
|
||||
public var intensity: Number by properties.root(includeStyles = false).number { 1.0 }
|
||||
public val color: ColorAccessor by color(SolidMaterial.COLOR_KEY)
|
||||
public var intensity: Number by properties.root(includeStyles = false).number(INTENSITY_KEY) { 1.0 }
|
||||
|
||||
public companion object {
|
||||
public val INTENSITY_KEY: Name = "intensity".asName()
|
||||
|
||||
public companion object{
|
||||
public val descriptor: MetaDescriptor by lazy {
|
||||
MetaDescriptor {
|
||||
value(Vision.VISIBLE_KEY, ValueType.BOOLEAN) {
|
||||
@ -27,6 +31,7 @@ public abstract class LightSource : SolidBase<LightSource>() {
|
||||
value(LightSource::color.name, ValueType.STRING, ValueType.NUMBER) {
|
||||
inherited = false
|
||||
widgetType = "color"
|
||||
default(Colors.white)
|
||||
}
|
||||
|
||||
value(LightSource::intensity.name, ValueType.NUMBER) {
|
||||
@ -34,11 +39,6 @@ public abstract class LightSource : SolidBase<LightSource>() {
|
||||
default(1.0)
|
||||
}
|
||||
|
||||
value(SolidMaterial.COLOR_KEY, ValueType.STRING, ValueType.NUMBER) {
|
||||
inherited = false
|
||||
widgetType = "color"
|
||||
}
|
||||
|
||||
node(Solid.POSITION_KEY) {
|
||||
hide()
|
||||
}
|
||||
|
@ -1,6 +1,12 @@
|
||||
package space.kscience.visionforge.solid.three
|
||||
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.visionforge.Vision
|
||||
import space.kscience.visionforge.onPropertyChange
|
||||
import space.kscience.visionforge.solid.AmbientLightSource
|
||||
import space.kscience.visionforge.solid.LightSource
|
||||
import space.kscience.visionforge.solid.SolidMaterial
|
||||
import space.kscience.visionforge.visible
|
||||
import three.lights.AmbientLight
|
||||
import three.math.Color
|
||||
import kotlin.reflect.KClass
|
||||
@ -14,6 +20,16 @@ public object ThreeAmbientLightFactory : ThreeFactory<AmbientLightSource> {
|
||||
intensity = vision.intensity.toDouble()
|
||||
}
|
||||
|
||||
if (observe) {
|
||||
vision.onPropertyChange(three.context) { propertyName: Name ->
|
||||
when (propertyName) {
|
||||
Vision.VISIBLE_KEY -> res.visible = vision.visible ?: true
|
||||
SolidMaterial.COLOR_KEY -> res.color = vision.color.threeColor() ?: Color(0x404040)
|
||||
LightSource.INTENSITY_KEY -> res.intensity = vision.intensity.toDouble()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
}
|
@ -29,8 +29,6 @@ public abstract class ThreeMeshFactory<in T : Solid>(
|
||||
override fun build(three: ThreePlugin, vision: T, observe: Boolean): Mesh {
|
||||
val geometry = buildGeometry(vision)
|
||||
|
||||
//val meshMeta: Meta = obj.properties[Material3D.MATERIAL_KEY]?.node ?: Meta.empty
|
||||
|
||||
val mesh = Mesh(geometry, ThreeMaterials.DEFAULT).apply {
|
||||
matrixAutoUpdate = false
|
||||
//set position for mesh
|
||||
@ -46,11 +44,10 @@ public abstract class ThreeMeshFactory<in T : Solid>(
|
||||
val oldGeometry = mesh.geometry
|
||||
val newGeometry = buildGeometry(vision)
|
||||
oldGeometry.attributes = newGeometry.attributes
|
||||
//mesh.applyWireFrame(obj)
|
||||
|
||||
mesh.applyEdges(vision)
|
||||
newGeometry.dispose()
|
||||
}
|
||||
//name.startsWith(WIREFRAME_KEY) -> mesh.applyWireFrame(obj)
|
||||
name.startsWith(EDGES_KEY) -> mesh.applyEdges(vision)
|
||||
else -> mesh.updateProperty(vision, name)
|
||||
}
|
||||
@ -62,18 +59,12 @@ public abstract class ThreeMeshFactory<in T : Solid>(
|
||||
|
||||
public companion object {
|
||||
internal const val EDGES_OBJECT_NAME: String = "@edges"
|
||||
|
||||
//public val WIREFRAME_KEY: Name = "wireframe".asName()
|
||||
|
||||
//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(vision: Solid): Mesh = apply {
|
||||
setMaterial(vision)
|
||||
applyEdges(vision)
|
||||
//applyWireFrame(obj)
|
||||
layers.set(vision.layer)
|
||||
children.forEach {
|
||||
it.layers.set(vision.layer)
|
||||
@ -104,24 +95,3 @@ public fun Mesh.applyEdges(vision: 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"
|
||||
// }
|
||||
// )
|
||||
// }
|
||||
//}
|
Loading…
Reference in New Issue
Block a user