forked from kscience/visionforge
Reimplemented coordinates as properties
This commit is contained in:
parent
ba637413c7
commit
2b6942b827
@ -1,7 +1,5 @@
|
||||
import kotlinx.browser.document
|
||||
import kotlinx.css.height
|
||||
import kotlinx.css.pct
|
||||
import kotlinx.css.width
|
||||
import kotlinx.css.*
|
||||
import react.child
|
||||
import react.dom.render
|
||||
import space.kscience.dataforge.context.Context
|
||||
@ -31,8 +29,10 @@ private class JsPlaygroundApp : Application {
|
||||
render(element) {
|
||||
styledDiv {
|
||||
css{
|
||||
height = 100.pct
|
||||
width = 100.pct
|
||||
padding(0.pt)
|
||||
margin(0.pt)
|
||||
height = 100.vh
|
||||
width = 100.vw
|
||||
}
|
||||
child(ThreeCanvasWithControls) {
|
||||
attrs {
|
||||
|
@ -11,22 +11,14 @@ public expect class Counter() {
|
||||
public fun incrementAndGet(): Int
|
||||
}
|
||||
|
||||
private fun Point3D?.safePlus(other: Point3D?): Point3D? = if (this == null && other == null) {
|
||||
null
|
||||
} else {
|
||||
(this ?: Point3D(0, 0, 0)) + (other ?: Point3D(0, 0, 0))
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
internal fun Vision.updateFrom(other: Vision): Vision {
|
||||
if (this is Solid && other is Solid) {
|
||||
position = position.safePlus(other.position)
|
||||
rotation = rotation.safePlus(other.rotation)
|
||||
if (this.scale != null || other.scale != null) {
|
||||
position += other.position
|
||||
rotation += other.rotation
|
||||
scaleX = scaleX.toDouble() * other.scaleX.toDouble()
|
||||
scaleY = scaleY.toDouble() * other.scaleY.toDouble()
|
||||
scaleZ = scaleZ.toDouble() * other.scaleZ.toDouble()
|
||||
}
|
||||
other.meta.itemSequence().forEach { (name, item) ->
|
||||
if (getProperty(name) == null) {
|
||||
setProperty(name, item)
|
||||
|
@ -1,9 +1,7 @@
|
||||
package space.kscience.visionforge.solid
|
||||
|
||||
import space.kscience.dataforge.meta.boolean
|
||||
import space.kscience.dataforge.meta.*
|
||||
import space.kscience.dataforge.meta.descriptors.NodeDescriptor
|
||||
import space.kscience.dataforge.meta.enum
|
||||
import space.kscience.dataforge.meta.int
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.asName
|
||||
import space.kscience.dataforge.names.plus
|
||||
@ -14,15 +12,28 @@ import space.kscience.visionforge.Vision.Companion.VISIBLE_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.DETAIL_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.IGNORE_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.LAYER_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.POSITION_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.ROTATION_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.SCALE_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.X_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.X_POSITION_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.X_ROTATION_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.X_SCALE_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.Y_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.Y_POSITION_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.Y_ROTATION_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.Y_SCALE_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.Z_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.Z_POSITION_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.Z_ROTATION_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.Z_SCALE_KEY
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
/**
|
||||
* Interface for 3-dimensional [Vision]
|
||||
*/
|
||||
public interface Solid : Vision {
|
||||
public var position: Point3D?
|
||||
public var rotation: Point3D?
|
||||
public var scale: Point3D?
|
||||
|
||||
override val descriptor: NodeDescriptor get() = Companion.descriptor
|
||||
|
||||
public companion object {
|
||||
@ -72,7 +83,7 @@ public interface Solid : Vision {
|
||||
hide()
|
||||
}
|
||||
|
||||
value(DETAIL_KEY){
|
||||
value(DETAIL_KEY) {
|
||||
type(ValueType.NUMBER)
|
||||
hide()
|
||||
}
|
||||
@ -84,22 +95,6 @@ public interface Solid : Vision {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun solidEquals(first: Solid, second: Solid): Boolean {
|
||||
if (first.position != second.position) return false
|
||||
if (first.rotation != second.rotation) return false
|
||||
if (first.scale != second.scale) return false
|
||||
if (first.meta != second.meta) return false
|
||||
return true
|
||||
}
|
||||
|
||||
internal fun solidHashCode(solid: Solid): Int {
|
||||
var result = +(solid.position?.hashCode() ?: 0)
|
||||
result = 31 * result + (solid.rotation?.hashCode() ?: 0)
|
||||
result = 31 * result + (solid.scale?.hashCode() ?: 0)
|
||||
result = 31 * result + solid.allProperties().hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,74 +145,44 @@ public var Vision.ignore: Boolean?
|
||||
// get() = getProperty(SELECTED_KEY).boolean
|
||||
// set(value) = setProperty(SELECTED_KEY, value)
|
||||
|
||||
private fun Solid.position(): Point3D =
|
||||
position ?: Point3D(0.0, 0.0, 0.0).also { position = it }
|
||||
|
||||
public var Solid.x: Number
|
||||
get() = position?.x ?: 0f
|
||||
set(value) {
|
||||
position().x = value.toFloat()
|
||||
invalidateProperty(Solid.X_POSITION_KEY)
|
||||
internal fun number(name: Name, default: Number): ReadWriteProperty<Solid, Number> =
|
||||
object : ReadWriteProperty<Solid, Number> {
|
||||
override fun getValue(thisRef: Solid, property: KProperty<*>): Number {
|
||||
return thisRef.getOwnProperty(name)?.number ?: default
|
||||
}
|
||||
|
||||
public var Solid.y: Number
|
||||
get() = position?.y ?: 0f
|
||||
set(value) {
|
||||
position().y = value.toFloat()
|
||||
invalidateProperty(Solid.Y_POSITION_KEY)
|
||||
override fun setValue(thisRef: Solid, property: KProperty<*>, value: Number) {
|
||||
thisRef.setProperty(name, value)
|
||||
}
|
||||
}
|
||||
|
||||
public var Solid.z: Number
|
||||
get() = position?.z ?: 0f
|
||||
set(value) {
|
||||
position().z = value.toFloat()
|
||||
invalidateProperty(Solid.Z_POSITION_KEY)
|
||||
internal fun point(name: Name, default: Float): ReadWriteProperty<Solid, Point3D> =
|
||||
object : ReadWriteProperty<Solid, Point3D> {
|
||||
override fun getValue(thisRef: Solid, property: KProperty<*>): Point3D = object : Point3D {
|
||||
override val x: Float get() = thisRef.getOwnProperty(name + X_KEY)?.float ?: default
|
||||
override val y: Float get() = thisRef.getOwnProperty(name + Y_KEY)?.float ?: default
|
||||
override val z: Float get() = thisRef.getOwnProperty(name + Z_KEY)?.float ?: default
|
||||
}
|
||||
|
||||
private fun Solid.rotation(): Point3D =
|
||||
rotation ?: Point3D(0.0, 0.0, 0.0).also { rotation = it }
|
||||
|
||||
public var Solid.rotationX: Number
|
||||
get() = rotation?.x ?: 0f
|
||||
set(value) {
|
||||
rotation().x = value.toFloat()
|
||||
invalidateProperty(Solid.X_ROTATION_KEY)
|
||||
override fun setValue(thisRef: Solid, property: KProperty<*>, value: Point3D) {
|
||||
thisRef.setProperty(name + X_KEY, value.x)
|
||||
thisRef.setProperty(name + Y_KEY, value.y)
|
||||
thisRef.setProperty(name + Z_KEY, value.z)
|
||||
}
|
||||
}
|
||||
|
||||
public var Solid.rotationY: Number
|
||||
get() = rotation?.y ?: 0f
|
||||
set(value) {
|
||||
rotation().y = value.toFloat()
|
||||
invalidateProperty(Solid.Y_ROTATION_KEY)
|
||||
}
|
||||
public var Solid.position: Point3D by point(POSITION_KEY, 0f)
|
||||
public var Solid.rotation: Point3D by point(ROTATION_KEY, 0f)
|
||||
public var Solid.scale: Point3D by point(SCALE_KEY, 1f)
|
||||
|
||||
public var Solid.rotationZ: Number
|
||||
get() = rotation?.z ?: 0f
|
||||
set(value) {
|
||||
rotation().z = value.toFloat()
|
||||
invalidateProperty(Solid.Z_ROTATION_KEY)
|
||||
}
|
||||
public var Solid.x: Number by number(X_POSITION_KEY, 0f)
|
||||
public var Solid.y: Number by number(Y_POSITION_KEY, 0f)
|
||||
public var Solid.z: Number by number(Z_POSITION_KEY, 0f)
|
||||
|
||||
private fun Solid.scale(): Point3D =
|
||||
scale ?: Point3D(1.0, 1.0, 1.0).also { scale = it }
|
||||
public var Solid.rotationX: Number by number(X_ROTATION_KEY, 0f)
|
||||
public var Solid.rotationY: Number by number(Y_ROTATION_KEY, 0f)
|
||||
public var Solid.rotationZ: Number by number(Z_ROTATION_KEY, 0f)
|
||||
|
||||
public var Solid.scaleX: Number
|
||||
get() = scale?.x ?: 1f
|
||||
set(value) {
|
||||
scale().x = value.toFloat()
|
||||
invalidateProperty(Solid.X_SCALE_KEY)
|
||||
}
|
||||
|
||||
public var Solid.scaleY: Number
|
||||
get() = scale?.y ?: 1f
|
||||
set(value) {
|
||||
scale().y = value.toFloat()
|
||||
invalidateProperty(Solid.Y_SCALE_KEY)
|
||||
}
|
||||
|
||||
public var Solid.scaleZ: Number
|
||||
get() = scale?.z ?: 1f
|
||||
set(value) {
|
||||
scale().z = value.toFloat()
|
||||
invalidateProperty(Solid.Z_SCALE_KEY)
|
||||
}
|
||||
public var Solid.scaleX: Number by number(X_SCALE_KEY, 1f)
|
||||
public var Solid.scaleY: Number by number(Y_SCALE_KEY, 1f)
|
||||
public var Solid.scaleZ: Number by number(Z_SCALE_KEY, 1f)
|
@ -13,9 +13,9 @@ import space.kscience.visionforge.VisionChange
|
||||
@Serializable
|
||||
@SerialName("solid")
|
||||
public open class SolidBase(
|
||||
override var position: Point3D? = null,
|
||||
override var rotation: Point3D? = null,
|
||||
override var scale: Point3D? = null,
|
||||
// override var position: Point3D? = null,
|
||||
// override var rotation: Point3D? = null,
|
||||
// override var scale: Point3D? = null,
|
||||
) : VisionBase(), Solid {
|
||||
override val descriptor: NodeDescriptor get() = Solid.descriptor
|
||||
|
||||
|
@ -29,9 +29,9 @@ public interface PrototypeHolder {
|
||||
@SerialName("group.solid")
|
||||
public class SolidGroup(
|
||||
@Serializable(PrototypeSerializer::class) internal var prototypes: MutableVisionGroup? = null,
|
||||
override var position: Point3D? = null,
|
||||
override var rotation: Point3D? = null,
|
||||
override var scale: Point3D? = null,
|
||||
// override var position: Point3D? = null,
|
||||
// override var rotation: Point3D? = null,
|
||||
// override var scale: Point3D? = null,
|
||||
) : VisionGroupBase(), Solid, PrototypeHolder {
|
||||
|
||||
init {
|
||||
|
@ -96,22 +96,22 @@ public class SolidReferenceGroup(
|
||||
*/
|
||||
private inner class ReferenceChild(private val childName: Name) : SolidReference, VisionGroup {
|
||||
|
||||
//TODO replace by properties
|
||||
override var position: Point3D?
|
||||
get() = prototype.position
|
||||
set(_) {
|
||||
error("Can't set position of reference")
|
||||
}
|
||||
override var rotation: Point3D?
|
||||
get() = prototype.rotation
|
||||
set(_) {
|
||||
error("Can't set position of reference")
|
||||
}
|
||||
override var scale: Point3D?
|
||||
get() = prototype.scale
|
||||
set(_) {
|
||||
error("Can't set position of reference")
|
||||
}
|
||||
// //TODO replace by properties
|
||||
// override var position: Point3D?
|
||||
// get() = prototype.position
|
||||
// set(_) {
|
||||
// error("Can't set position of reference")
|
||||
// }
|
||||
// override var rotation: Point3D?
|
||||
// get() = prototype.rotation
|
||||
// set(_) {
|
||||
// error("Can't set position of reference")
|
||||
// }
|
||||
// override var scale: Point3D?
|
||||
// get() = prototype.scale
|
||||
// set(_) {
|
||||
// error("Can't set position of reference")
|
||||
// }
|
||||
override val prototype: Solid get() = prototypeFor(childName)
|
||||
|
||||
override val children: Map<NameToken, Vision>
|
||||
|
@ -1,10 +1,14 @@
|
||||
package space.kscience.visionforge.solid
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.dataforge.meta.MetaBuilder
|
||||
import space.kscience.dataforge.meta.float
|
||||
import space.kscience.dataforge.meta.get
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import space.kscience.dataforge.meta.*
|
||||
import space.kscience.visionforge.solid.Solid.Companion.X_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.Y_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.Z_KEY
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.sqrt
|
||||
@ -17,25 +21,48 @@ public data class Point2D(public var x: Float, public var y: Float)
|
||||
public fun Point2D(x: Number, y: Number): Point2D = Point2D(x.toFloat(), y.toFloat())
|
||||
|
||||
public fun Point2D.toMeta(): Meta = Meta {
|
||||
Solid.X_KEY put x
|
||||
Solid.Y_KEY put y
|
||||
X_KEY put x
|
||||
Y_KEY put y
|
||||
}
|
||||
|
||||
internal fun Meta.point2D(): Point2D = Point2D(this["x"].float ?: 0f, this["y"].float ?: 0f)
|
||||
|
||||
@Serializable
|
||||
public data class Point3D(
|
||||
public var x: Float,
|
||||
public var y: Float,
|
||||
public var z: Float,
|
||||
) {
|
||||
@Serializable(Point3DSerializer::class)
|
||||
public interface Point3D {
|
||||
public val x: Float
|
||||
public val y: Float
|
||||
public val z: Float
|
||||
|
||||
public companion object {
|
||||
public val ZERO: Point3D = Point3D(0.0, 0.0, 0.0)
|
||||
public val ONE: Point3D = Point3D(1.0, 1.0, 1.0)
|
||||
}
|
||||
}
|
||||
|
||||
public fun Point3D(x: Number, y: Number, z: Number): Point3D = Point3D(x.toFloat(), y.toFloat(), z.toFloat())
|
||||
@Serializable(Point3DSerializer::class)
|
||||
public interface MutablePoint3D : Point3D {
|
||||
override var x: Float
|
||||
override var y: Float
|
||||
override var z: Float
|
||||
}
|
||||
|
||||
@Serializable
|
||||
private class Point3DImpl(override var x: Float, override var y: Float, override var z: Float) : MutablePoint3D
|
||||
|
||||
internal object Point3DSerializer : KSerializer<Point3D> {
|
||||
|
||||
override val descriptor: SerialDescriptor = Point3DImpl.serializer().descriptor
|
||||
|
||||
|
||||
override fun deserialize(decoder: Decoder): Point3D = decoder.decodeSerializableValue(Point3DImpl.serializer())
|
||||
|
||||
override fun serialize(encoder: Encoder, value: Point3D) {
|
||||
val impl: Point3DImpl = (value as? Point3DImpl) ?: Point3DImpl(value.x, value.y, value.z)
|
||||
encoder.encodeSerializableValue(Point3DImpl.serializer(), impl)
|
||||
}
|
||||
}
|
||||
|
||||
public fun Point3D(x: Number, y: Number, z: Number): Point3D = Point3DImpl(x.toFloat(), y.toFloat(), z.toFloat())
|
||||
|
||||
public operator fun Point3D.plus(other: Point3D): Point3D = Point3D(
|
||||
this.x + other.x,
|
||||
@ -61,17 +88,21 @@ public infix fun Point3D.cross(other: Point3D): Point3D = Point3D(
|
||||
x * other.y - y * other.x
|
||||
)
|
||||
|
||||
public fun Point3D.normalizeInPlace(){
|
||||
public fun MutablePoint3D.normalizeInPlace() {
|
||||
val norm = sqrt(x.pow(2) + y.pow(2) + z.pow(2))
|
||||
x /= norm
|
||||
y /= norm
|
||||
z /= norm
|
||||
}
|
||||
|
||||
internal fun Meta.point3D() = Point3D(this["x"].float ?: 0.0, this["y"].float ?: 0.0, this["y"].float ?: 0.0)
|
||||
internal fun ItemProvider.point3D(default: Float = 0f) = object : Point3D {
|
||||
override val x: Float by float(default)
|
||||
override val y: Float by float(default)
|
||||
override val z: Float by float(default)
|
||||
}
|
||||
|
||||
public fun Point3D.toMeta(): MetaBuilder = Meta {
|
||||
Solid.X_KEY put x
|
||||
Solid.Y_KEY put y
|
||||
Solid.Z_KEY put z
|
||||
X_KEY put x
|
||||
Y_KEY put y
|
||||
Z_KEY put z
|
||||
}
|
@ -14,18 +14,14 @@ internal fun mergeChild(parent: VisionGroup, child: Vision): Vision {
|
||||
//parent.properties?.let { config.update(it) }
|
||||
|
||||
if (this is Solid && parent is Solid) {
|
||||
position = (position ?: Point3D.ZERO) + (parent.position ?: Point3D.ZERO)
|
||||
rotation = (parent.rotation ?: Point3D.ZERO) + (parent.rotation ?: Point3D.ZERO)
|
||||
scale = when {
|
||||
scale == null && parent.scale == null -> null
|
||||
scale == null -> parent.scale
|
||||
parent.scale == null -> scale
|
||||
else -> Point3D(
|
||||
scale!!.x * parent.scale!!.x,
|
||||
scale!!.y * parent.scale!!.y,
|
||||
scale!!.z * parent.scale!!.z
|
||||
position += parent.position
|
||||
rotation += parent.rotation
|
||||
scale = Point3D(
|
||||
scale.x * parent.scale.x,
|
||||
scale.y * parent.scale.y,
|
||||
scale.z * parent.scale.z
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
@file:Suppress("NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "unused")
|
||||
@file:JsModule("three")
|
||||
@file:JsNonModule
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user