Make Axes a separate object
This commit is contained in:
parent
2b70afdb86
commit
20851baaf5
22
demo/playground/src/jvmMain/kotlin/axes.kt
Normal file
22
demo/playground/src/jvmMain/kotlin/axes.kt
Normal file
@ -0,0 +1,22 @@
|
||||
package space.kscience.visionforge.examples
|
||||
|
||||
import space.kscience.kmath.geometry.Euclidean3DSpace
|
||||
import space.kscience.kmath.geometry.radians
|
||||
import space.kscience.visionforge.html.ResourceLocation
|
||||
import space.kscience.visionforge.solid.*
|
||||
import kotlin.math.PI
|
||||
|
||||
fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) {
|
||||
vision("canvas") {
|
||||
requirePlugin(Solids)
|
||||
solid {
|
||||
axes(100, "root-axes")
|
||||
solidGroup("group") {
|
||||
z = 100
|
||||
rotate((PI / 4).radians, Euclidean3DSpace.vector(1, 1, 1))
|
||||
axes(100, "local-axes")
|
||||
box(50, 50, 50, "box")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package space.kscience.visionforge.solid
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import space.kscience.visionforge.MutableVisionContainer
|
||||
import space.kscience.visionforge.VisionBuilder
|
||||
import space.kscience.visionforge.setChild
|
||||
|
||||
public abstract class MiscSolid: SolidBase<MiscSolid>()
|
||||
|
||||
@Serializable
|
||||
@SerialName("solid.axes")
|
||||
public class AxesSolid(public val size: Double): MiscSolid(){
|
||||
public companion object{
|
||||
public const val AXES_NAME: String = "@xes"
|
||||
}
|
||||
}
|
||||
|
||||
@VisionBuilder
|
||||
public fun MutableVisionContainer<Solid>.axes(
|
||||
size: Number,
|
||||
name: String = "@axes",
|
||||
block: AxesSolid.() -> Unit = {},
|
||||
): AxesSolid = AxesSolid(size.toDouble()).apply(block).also {
|
||||
setChild(name, it)
|
||||
}
|
@ -9,9 +9,7 @@ import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.asName
|
||||
import space.kscience.dataforge.names.plus
|
||||
import space.kscience.kmath.complex.Quaternion
|
||||
import space.kscience.kmath.geometry.RotationOrder
|
||||
import space.kscience.kmath.geometry.fromEuler
|
||||
import space.kscience.kmath.geometry.radians
|
||||
import space.kscience.kmath.geometry.*
|
||||
import space.kscience.visionforge.*
|
||||
import space.kscience.visionforge.Vision.Companion.VISIBLE_KEY
|
||||
import space.kscience.visionforge.solid.Solid.Companion.DETAIL_KEY
|
||||
@ -242,14 +240,13 @@ public var Solid.quaternion: Quaternion
|
||||
quaternionValue = value
|
||||
}
|
||||
|
||||
|
||||
//public var Solid.quaternion: Quaternion?
|
||||
// get() = meta[Solid::quaternion.name]?.value?.doubleArray?.let { Quaternion(it) }
|
||||
// set(value) {
|
||||
// meta[Solid::quaternion.name] = value?.values?.asValue()
|
||||
// }
|
||||
|
||||
|
||||
public var Solid.scaleX: Number by float(X_SCALE_KEY, 1f)
|
||||
public var Solid.scaleY: Number by float(Y_SCALE_KEY, 1f)
|
||||
public var Solid.scaleZ: Number by float(Z_SCALE_KEY, 1f)
|
||||
public var Solid.scaleZ: Number by float(Z_SCALE_KEY, 1f)
|
||||
|
||||
/**
|
||||
* Add rotation with given [angle] relative to given [axis]
|
||||
*/
|
||||
public fun Solid.rotate(angle: Angle, axis: DoubleVector3D) {
|
||||
quaternion = Quaternion.fromRotation(angle, axis)
|
||||
}
|
@ -48,6 +48,8 @@ public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer<Sol
|
||||
|
||||
subclass(AmbientLightSource.serializer())
|
||||
subclass(PointLightSource.serializer())
|
||||
|
||||
subclass(AxesSolid.serializer())
|
||||
}
|
||||
|
||||
public val serializersModuleForSolids: SerializersModule = SerializersModule {
|
||||
|
@ -7,19 +7,19 @@ import space.kscience.visionforge.VisionBuilder
|
||||
import space.kscience.visionforge.setChild
|
||||
|
||||
|
||||
public sealed class StlVision: SolidBase<StlVision>()
|
||||
public sealed class StlSolid: SolidBase<StlSolid>()
|
||||
|
||||
@Serializable
|
||||
@SerialName("solid.stl.url")
|
||||
public class StlUrlVision(public val url: String) : StlVision()
|
||||
public class StlUrlSolid(public val url: String) : StlSolid()
|
||||
|
||||
@Serializable
|
||||
@SerialName("solid.stl.binary")
|
||||
public class StlBinaryVision(public val data: ByteArray) : StlVision()
|
||||
public class StlBinarySolid(public val data: ByteArray) : StlSolid()
|
||||
|
||||
@VisionBuilder
|
||||
public inline fun MutableVisionContainer<Solid>.stl(
|
||||
url: String,
|
||||
name: String? = null,
|
||||
action: StlVision.() -> Unit = {},
|
||||
): StlVision = StlUrlVision(url).apply(action).also { setChild(name, it) }
|
||||
action: StlSolid.() -> Unit = {},
|
||||
): StlSolid = StlUrlSolid(url).apply(action).also { setChild(name, it) }
|
@ -7,11 +7,13 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
||||
import space.kscience.dataforge.meta.descriptors.value
|
||||
import space.kscience.dataforge.meta.double
|
||||
|
||||
@Deprecated("Use separate axes object instead")
|
||||
public class AxesScheme : Scheme() {
|
||||
public var visible: Boolean by boolean(false)
|
||||
public var size: Double by double(AXIS_SIZE)
|
||||
public var width: Double by double(AXIS_WIDTH)
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
public companion object : SchemeSpec<AxesScheme>(::AxesScheme) {
|
||||
public const val AXIS_SIZE: Double = 1000.0
|
||||
public const val AXIS_WIDTH: Double = 3.0
|
||||
|
@ -59,6 +59,7 @@ public class CanvasSize : Scheme() {
|
||||
}
|
||||
|
||||
public class Canvas3DOptions : Scheme() {
|
||||
@Suppress("DEPRECATION")
|
||||
public var axes: AxesScheme by spec(AxesScheme)
|
||||
public var camera: CameraScheme by spec(CameraScheme)
|
||||
public var controls: ControlsScheme by spec(ControlsScheme)
|
||||
@ -75,6 +76,7 @@ public class Canvas3DOptions : Scheme() {
|
||||
public companion object : SchemeSpec<Canvas3DOptions>(::Canvas3DOptions) {
|
||||
override val descriptor: MetaDescriptor by lazy {
|
||||
MetaDescriptor {
|
||||
@Suppress("DEPRECATION")
|
||||
scheme(Canvas3DOptions::axes, AxesScheme)
|
||||
|
||||
value(Canvas3DOptions::layers) {
|
||||
|
@ -0,0 +1,22 @@
|
||||
package space.kscience.visionforge.solid.three
|
||||
|
||||
import space.kscience.visionforge.onPropertyChange
|
||||
import space.kscience.visionforge.solid.AxesSolid
|
||||
import three.helpers.AxesHelper
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
public object ThreeAxesFactory : ThreeFactory<AxesSolid> {
|
||||
override val type: KClass<in AxesSolid> get() = AxesSolid::class
|
||||
|
||||
override suspend fun build(three: ThreePlugin, vision: AxesSolid, observe: Boolean): AxesHelper {
|
||||
val res = AxesHelper(vision.size.toInt())
|
||||
|
||||
if (observe) {
|
||||
vision.onPropertyChange(three.context) { propertyName ->
|
||||
res.updateProperty(vision, propertyName)
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
}
|
@ -57,16 +57,6 @@ public class ThreeCanvas(
|
||||
axesObject.name = AXES_NAME
|
||||
add(axesObject)
|
||||
}
|
||||
|
||||
// //Set up light
|
||||
// options.useProperty(Canvas3DOptions::light, this) { lightConfig ->
|
||||
// //remove old light if present
|
||||
// getObjectByName(LIGHT_NAME)?.let { remove(it) }
|
||||
// //add new light
|
||||
// val lightObject = buildLight(lightConfig)
|
||||
// lightObject.name = LIGHT_NAME
|
||||
// add(lightObject)
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@ -110,7 +100,7 @@ public class ThreeCanvas(
|
||||
}
|
||||
|
||||
/**
|
||||
* Force camera aspect ration and renderer size recalculation
|
||||
* Force camera aspect ratio and renderer size recalculation
|
||||
*/
|
||||
private fun updateSize() {
|
||||
val width = element.clientWidth
|
||||
@ -202,7 +192,7 @@ public class ThreeCanvas(
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve full name of the object relative to the global root
|
||||
* Resolve the full name of the object relative to the global root
|
||||
*/
|
||||
private fun Object3D.fullName(): Name {
|
||||
if (root == null) error("Can't resolve element name without the root")
|
||||
@ -213,7 +203,7 @@ public class ThreeCanvas(
|
||||
}
|
||||
}
|
||||
|
||||
//find first non-static parent in this object ancestry
|
||||
//find the first non-static parent in this object ancestry
|
||||
private tailrec fun Object3D.upTrace(): Object3D? = if (!name.startsWith("@")) this else parent?.upTrace()
|
||||
|
||||
private fun pick(): Object3D? {
|
||||
@ -267,6 +257,7 @@ public class ThreeCanvas(
|
||||
}
|
||||
three.context.launch {
|
||||
val object3D = three.buildObject3D(vision)
|
||||
|
||||
object3D.name = "@root"
|
||||
scene.add(object3D)
|
||||
root = object3D
|
||||
|
@ -37,7 +37,7 @@ public interface ThreeFactory<in T : Vision> {
|
||||
* Update position, rotation and visibility
|
||||
*/
|
||||
public fun Object3D.updatePosition(vision: Vision) {
|
||||
visible = vision.visible ?: true
|
||||
// visible = vision.visible ?: true
|
||||
if (vision is Solid) {
|
||||
position.set(vision.x, vision.y, vision.z)
|
||||
|
||||
|
@ -37,7 +37,8 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
|
||||
objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory
|
||||
objectFactories[AmbientLightSource::class] = ThreeAmbientLightFactory
|
||||
objectFactories[PointLightSource::class] = ThreePointLightFactory
|
||||
objectFactories[StlVision::class] = ThreeStlFactory
|
||||
objectFactories[StlSolid::class] = ThreeStlFactory
|
||||
objectFactories[AxesSolid::class] = ThreeAxesFactory
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
@ -7,11 +7,13 @@ import kotlin.reflect.KClass
|
||||
public object ThreeSmartLineFactory : ThreeFactory<PolyLine> {
|
||||
override val type: KClass<in PolyLine> get() = PolyLine::class
|
||||
|
||||
override suspend fun build(three: ThreePlugin, vision: PolyLine, observe: Boolean): Object3D {
|
||||
return if (vision.thickness == 1.0) {
|
||||
ThreeLineFactory.build(three, vision, observe)
|
||||
} else {
|
||||
ThreeMeshLineFactory.build(three, vision, observe)
|
||||
}
|
||||
override suspend fun build(
|
||||
three: ThreePlugin,
|
||||
vision: PolyLine,
|
||||
observe: Boolean,
|
||||
): Object3D = if (vision.thickness == 1.0) {
|
||||
ThreeLineFactory.build(three, vision, observe)
|
||||
} else {
|
||||
ThreeMeshLineFactory.build(three, vision, observe)
|
||||
}
|
||||
}
|
@ -2,9 +2,9 @@ package space.kscience.visionforge.solid.three
|
||||
|
||||
import org.khronos.webgl.ArrayBuffer
|
||||
import org.khronos.webgl.Int8Array
|
||||
import space.kscience.visionforge.solid.StlBinaryVision
|
||||
import space.kscience.visionforge.solid.StlUrlVision
|
||||
import space.kscience.visionforge.solid.StlVision
|
||||
import space.kscience.visionforge.solid.StlBinarySolid
|
||||
import space.kscience.visionforge.solid.StlSolid
|
||||
import space.kscience.visionforge.solid.StlUrlSolid
|
||||
import three.core.BufferGeometry
|
||||
import three.external.loaders.STLLoader
|
||||
import kotlin.coroutines.resume
|
||||
@ -13,15 +13,15 @@ import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
fun ArrayBuffer.toByteArray(): ByteArray = Int8Array(this).unsafeCast<ByteArray>()
|
||||
|
||||
public object ThreeStlFactory : ThreeMeshFactory<StlVision>(StlVision::class) {
|
||||
public object ThreeStlFactory : ThreeMeshFactory<StlSolid>(StlSolid::class) {
|
||||
|
||||
private val loader = STLLoader().apply {
|
||||
requestHeader = listOf("Access-Control-Allow-Origin: *")
|
||||
}
|
||||
|
||||
override suspend fun buildGeometry(obj: StlVision): BufferGeometry = when (obj) {
|
||||
is StlBinaryVision -> loader.parse(obj.data)
|
||||
is StlUrlVision -> suspendCoroutine { continuation ->
|
||||
override suspend fun buildGeometry(obj: StlSolid): BufferGeometry = when (obj) {
|
||||
is StlBinarySolid -> loader.parse(obj.data)
|
||||
is StlUrlSolid -> suspendCoroutine { continuation ->
|
||||
loader.load(
|
||||
url = obj.url,
|
||||
onLoad = {
|
||||
|
Loading…
Reference in New Issue
Block a user