Compare commits
2 Commits
6a801f9999
...
ae12084dee
Author | SHA1 | Date | |
---|---|---|---|
ae12084dee | |||
92bfb173d8 |
@ -42,7 +42,7 @@ public open class DObject(public val meta: Meta, public val refCache: DObjectCac
|
||||
}
|
||||
|
||||
internal fun <T : DObject> tObjectArray(
|
||||
builder: (Meta, DObjectCache) -> T
|
||||
builder: (Meta, DObjectCache) -> T,
|
||||
): ReadOnlyProperty<Any?, List<T>> = ReadOnlyProperty { _, property ->
|
||||
meta.getIndexed(Name.of(property.name, "arr")).values.mapNotNull {
|
||||
resolve(builder, it)
|
||||
@ -51,9 +51,9 @@ public open class DObject(public val meta: Meta, public val refCache: DObjectCac
|
||||
|
||||
internal fun <T : DObject> dObject(
|
||||
builder: (Meta, DObjectCache) -> T,
|
||||
key: Name? = null
|
||||
key: Name? = null,
|
||||
): ReadOnlyProperty<Any?, T?> = ReadOnlyProperty { _, property ->
|
||||
meta[key ?: property.name.asName()]?.let { resolve(builder, it) }
|
||||
meta[key ?: property.name.asName()]?.takeIf { it.value != Null }?.let { resolve(builder, it) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,8 +62,7 @@ public open class DNamed(meta: Meta, refCache: DObjectCache) : DObject(meta, ref
|
||||
public val fTitle: String by meta.string("")
|
||||
}
|
||||
|
||||
public class DGeoMaterial(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache) {
|
||||
}
|
||||
public class DGeoMaterial(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache)
|
||||
|
||||
public class DGeoMedium(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache) {
|
||||
public val fMaterial: DGeoMaterial? by dObject(::DGeoMaterial)
|
||||
@ -90,27 +89,69 @@ public class DGeoNode(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCach
|
||||
public val fVolume: DGeoVolume? by dObject(::DGeoVolume)
|
||||
}
|
||||
|
||||
public open class DGeoMatrix(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache)
|
||||
public sealed class DGeoMatrix(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache)
|
||||
|
||||
public open class DGeoScale(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) {
|
||||
public class DGeoIdentity(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache)
|
||||
|
||||
public class DGeoScale(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) {
|
||||
public val fScale: DoubleArray by meta.doubleArray(1.0, 1.0, 1.0)
|
||||
public val x: Double get() = fScale[0]
|
||||
public val y: Double get() = fScale[1]
|
||||
public val z: Double get() = fScale[2]
|
||||
}
|
||||
|
||||
public class DGeoRotation(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) {
|
||||
public val fRotationMatrix: DoubleArray by meta.doubleArray()
|
||||
}
|
||||
|
||||
public class DGeoTranslation(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) {
|
||||
public val fTranslation: DoubleArray by meta.doubleArray()
|
||||
}
|
||||
|
||||
public open class DGeoCombiTrans(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) {
|
||||
public val fRotation: DGeoRotation? by dObject(::DGeoRotation)
|
||||
public val fTranslation: DoubleArray by meta.doubleArray()
|
||||
}
|
||||
|
||||
public class DGeoGenTrans(meta: Meta, refCache: DObjectCache) : DGeoCombiTrans(meta, refCache) {
|
||||
public val fScale: DoubleArray by meta.doubleArray()
|
||||
}
|
||||
|
||||
public class DGeoHMatrix(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) {
|
||||
public val fRotation: DGeoRotation? by dObject(::DGeoRotation)
|
||||
public val fTranslation: DoubleArray by meta.doubleArray()
|
||||
public val fScale: DoubleArray by meta.doubleArray()
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a specialized version of [DGeoMatrix]
|
||||
*/
|
||||
internal fun dGeoMatrix(
|
||||
meta: Meta,
|
||||
refCache: DObjectCache,
|
||||
): DGeoMatrix = when (val typename = meta["_typename"].string) {
|
||||
null -> error("Type name is undefined")
|
||||
"TGeoIdentity" -> DGeoIdentity(meta, refCache)
|
||||
"TGeoScale" -> DGeoScale(meta, refCache)
|
||||
"TGeoRotation" -> DGeoRotation(meta, refCache)
|
||||
"TGeoTranslation" -> DGeoTranslation(meta, refCache)
|
||||
"TGeoCombiTrans" -> DGeoCombiTrans(meta, refCache)
|
||||
"TGeoGenTrans" -> DGeoGenTrans(meta, refCache)
|
||||
"TGeoHMatrix" -> DGeoHMatrix(meta, refCache)
|
||||
else -> error("$typename is not a member of TGeoMatrix")
|
||||
}
|
||||
|
||||
public class DGeoBoolNode(meta: Meta, refCache: DObjectCache) : DObject(meta, refCache) {
|
||||
public val fLeft: DGeoShape? by dObject(::DGeoShape)
|
||||
public val fLeftMat: DGeoMatrix? by dObject(::DGeoMatrix)
|
||||
public val fLeftMat: DGeoMatrix? by dObject(::dGeoMatrix)
|
||||
|
||||
public val fRight: DGeoShape? by dObject(::DGeoShape)
|
||||
public val fRightMat: DGeoMatrix? by dObject(::DGeoMatrix)
|
||||
public val fRightMat: DGeoMatrix? by dObject(::dGeoMatrix)
|
||||
}
|
||||
|
||||
|
||||
public class DGeoManager(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache) {
|
||||
public val fMatrices: List<DGeoMatrix> by tObjectArray(::DGeoMatrix)
|
||||
public val fMatrices: List<DGeoMatrix> by tObjectArray(::dGeoMatrix)
|
||||
|
||||
public val fShapes: List<DGeoShape> by tObjectArray(::DGeoShape)
|
||||
|
||||
|
@ -1,16 +1,23 @@
|
||||
package ru.mipt.npm.root
|
||||
|
||||
import space.kscience.dataforge.meta.*
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.dataforge.meta.double
|
||||
import space.kscience.dataforge.meta.int
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.parseAsName
|
||||
import space.kscience.dataforge.names.plus
|
||||
import space.kscience.dataforge.names.withIndex
|
||||
import space.kscience.kmath.complex.Quaternion
|
||||
import space.kscience.kmath.geometry.fromRotationMatrix
|
||||
import space.kscience.kmath.linear.VirtualMatrix
|
||||
import space.kscience.visionforge.MutableVisionContainer
|
||||
import space.kscience.visionforge.isEmpty
|
||||
import space.kscience.visionforge.set
|
||||
import space.kscience.visionforge.solid.*
|
||||
import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY
|
||||
import kotlin.math.*
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
private val volumesName = Name.EMPTY //"volumes".asName()
|
||||
|
||||
@ -28,12 +35,10 @@ private data class RootToSolidContext(
|
||||
val colorCache: MutableMap<Meta, String> = mutableMapOf(),
|
||||
)
|
||||
|
||||
// converting to XYZ to Tait–Bryan angles according to https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
|
||||
// apply rotation from a matrix
|
||||
private fun Solid.rotate(rot: DoubleArray) {
|
||||
val xAngle = atan2(-rot[5], rot[8])
|
||||
val yAngle = atan2(rot[2], sqrt(1.0 - rot[2].pow(2)))
|
||||
val zAngle = atan2(-rot[1], rot[0])
|
||||
rotation = Float32Vector3D(xAngle, yAngle, zAngle)
|
||||
val matrix = VirtualMatrix(3, 3) { i, j -> rot[i * 3 + j] }
|
||||
quaternion = Quaternion.fromRotationMatrix(matrix)
|
||||
}
|
||||
|
||||
private fun Solid.translate(trans: DoubleArray) {
|
||||
@ -41,39 +46,32 @@ private fun Solid.translate(trans: DoubleArray) {
|
||||
position = Float32Vector3D(x, y, z)
|
||||
}
|
||||
|
||||
private fun Solid.useMatrix(matrix: DGeoMatrix?) {
|
||||
if (matrix == null) return
|
||||
when (matrix.typename) {
|
||||
"TGeoIdentity" -> {
|
||||
//do nothing
|
||||
private fun Solid.scale(s: DoubleArray) {
|
||||
scale = Float32Vector3D(s[0], s[1], s[2])
|
||||
}
|
||||
|
||||
private fun Solid.useMatrix(matrix: DGeoMatrix?): Unit {
|
||||
when (matrix) {
|
||||
null -> {}
|
||||
is DGeoIdentity -> {}
|
||||
is DGeoTranslation -> translate(matrix.fTranslation)
|
||||
is DGeoRotation -> rotate(matrix.fRotationMatrix)
|
||||
is DGeoScale -> scale(matrix.fScale)
|
||||
is DGeoGenTrans -> {
|
||||
translate(matrix.fTranslation)
|
||||
matrix.fRotation?.fRotationMatrix?.let { rotate(it) }
|
||||
scale(matrix.fScale)
|
||||
}
|
||||
|
||||
"TGeoTranslation" -> {
|
||||
val fTranslation by matrix.meta.doubleArray()
|
||||
translate(fTranslation)
|
||||
is DGeoCombiTrans -> {
|
||||
translate(matrix.fTranslation)
|
||||
matrix.fRotation?.fRotationMatrix?.let { rotate(it) }
|
||||
}
|
||||
|
||||
"TGeoRotation" -> {
|
||||
val fRotationMatrix by matrix.meta.doubleArray()
|
||||
rotate(fRotationMatrix)
|
||||
}
|
||||
|
||||
"TGeoCombiTrans" -> {
|
||||
val fTranslation by matrix.meta.doubleArray()
|
||||
|
||||
translate(fTranslation)
|
||||
matrix.meta["fRotation.fRotationMatrix"]?.value?.let {
|
||||
rotate(it.doubleArray)
|
||||
}
|
||||
}
|
||||
|
||||
"TGeoHMatrix" -> {
|
||||
val fTranslation by matrix.meta.doubleArray()
|
||||
val fRotationMatrix by matrix.meta.doubleArray()
|
||||
val fScale by matrix.meta.doubleArray()
|
||||
translate(fTranslation)
|
||||
rotate(fRotationMatrix)
|
||||
scale = Float32Vector3D(fScale[0], fScale[1], fScale[2])
|
||||
is DGeoHMatrix -> {
|
||||
translate(matrix.fTranslation)
|
||||
matrix.fRotation?.fRotationMatrix?.let { rotate(it) }
|
||||
scale(matrix.fScale)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -96,10 +94,10 @@ private fun SolidGroup.addShape(
|
||||
}
|
||||
smartComposite(compositeType, name = name) {
|
||||
addShape(node.fLeft!!, context, null) {
|
||||
this.useMatrix(node.fLeftMat)
|
||||
useMatrix(node.fLeftMat)
|
||||
}
|
||||
addShape(node.fRight!!, context, null) {
|
||||
this.useMatrix(node.fRightMat)
|
||||
useMatrix(node.fRightMat)
|
||||
}
|
||||
}.apply(block)
|
||||
}
|
||||
@ -283,7 +281,7 @@ private fun SolidGroup.addRootNode(obj: DGeoNode, context: RootToSolidContext) {
|
||||
addRootVolume(volume, context, obj.fName) {
|
||||
when (obj.typename) {
|
||||
"TGeoNodeMatrix" -> {
|
||||
val fMatrix by obj.dObject(::DGeoMatrix)
|
||||
val fMatrix by obj.dObject(::dGeoMatrix)
|
||||
this.useMatrix(fMatrix)
|
||||
}
|
||||
|
||||
|
@ -15,13 +15,13 @@ import kotlin.math.sin
|
||||
|
||||
fun main() = serve {
|
||||
|
||||
val azimuth = 60.degrees
|
||||
val inclination = 15.degrees
|
||||
// val azimuth = 60.degrees
|
||||
// val inclination = 15.degrees
|
||||
|
||||
val direction = with(QuaternionField) {
|
||||
Quaternion.fromRotation(-azimuth, Euclidean3DSpace.zAxis) *
|
||||
Quaternion.fromRotation(Angle.piDiv2 - inclination, Euclidean3DSpace.yAxis)
|
||||
}
|
||||
// val direction = with(QuaternionField) {
|
||||
// Quaternion.fromRotation(-azimuth, Euclidean3DSpace.zAxis) *
|
||||
// Quaternion.fromRotation(Angle.piDiv2 - inclination, Euclidean3DSpace.yAxis)
|
||||
// }
|
||||
|
||||
//val direction2 = Quaternion.fromEuler(Angle.zero, Angle.piDiv2 - inclination, -azimuth, RotationOrder.ZYX)
|
||||
|
||||
@ -43,7 +43,7 @@ fun main() = serve {
|
||||
solidGroup("frame") {
|
||||
z = 60
|
||||
|
||||
val antenna = solidGroup("antenna") {
|
||||
solidGroup("antenna") {
|
||||
axes(200)
|
||||
tube(40, 10, 30)
|
||||
sphereLayer(100, 95, theta = PI / 6) {
|
||||
|
Binary file not shown.
Binary file not shown.
@ -206,7 +206,7 @@ public var Solid.rotationZ: Number by float(Z_ROTATION_KEY, 0f)
|
||||
/**
|
||||
* Raw quaternion value defined in properties
|
||||
*/
|
||||
public var Solid.quaternionValue: Quaternion?
|
||||
public var Solid.quaternionOrNull: Quaternion?
|
||||
get() = properties.getValue(ROTATION_KEY)?.list?.let {
|
||||
require(it.size == 4) { "Quaternion must be a number array of 4 elements" }
|
||||
Quaternion(it[0].float, it[1].float, it[2].float, it[3].float)
|
||||
@ -229,14 +229,14 @@ public var Solid.quaternionValue: Quaternion?
|
||||
* Quaternion value including information from euler angles
|
||||
*/
|
||||
public var Solid.quaternion: Quaternion
|
||||
get() = quaternionValue ?: Quaternion.fromEuler(
|
||||
get() = quaternionOrNull ?: Quaternion.fromEuler(
|
||||
rotationX.radians,
|
||||
rotationY.radians,
|
||||
rotationZ.radians,
|
||||
rotationOrder
|
||||
)
|
||||
set(value) {
|
||||
quaternionValue = value
|
||||
quaternionOrNull = value
|
||||
}
|
||||
|
||||
public var Solid.scaleX: Number by float(X_SCALE_KEY, 1f)
|
||||
|
@ -41,7 +41,7 @@ public fun Object3D.updatePosition(vision: Vision) {
|
||||
if (vision is Solid) {
|
||||
position.set(vision.x, vision.y, vision.z)
|
||||
|
||||
val quaternion = vision.quaternionValue
|
||||
val quaternion = vision.quaternionOrNull
|
||||
|
||||
if (quaternion != null) {
|
||||
setRotationFromQuaternion(
|
||||
|
Loading…
Reference in New Issue
Block a user