diff --git a/orx-kinect-common/src/main/kotlin/Kinect.kt b/orx-kinect-common/src/main/kotlin/Kinect.kt index 736686fe..ff634dd6 100644 --- a/orx-kinect-common/src/main/kotlin/Kinect.kt +++ b/orx-kinect-common/src/main/kotlin/Kinect.kt @@ -17,9 +17,10 @@ interface Kinects { /** * Starts kinect device of a given number. * - * @param num the kinect device index. - * @throws KinectException if device of such a number does not exist, - * better to count them first. + * @param num the kinect device index (starts with 0). If no value specified, + * it will default to 0. + * @throws KinectException if device of such a number does not exist + * (better to count them first), or it was already started. * @see countDevices */ fun startDevice(num: Int = 0): KinectDevice @@ -34,15 +35,17 @@ interface Kinects { /** * Represents specific device. * - * @param data needed to make low level kinect support calls. + * @param CTX type of data needed to make low level kinect support calls (e.g. freenect contexts). */ interface KinectDevice : Extension { + val depthCamera: KinectDepthCamera /** * Executes low level Kinect commands in the kinect thread in the context of this device. */ fun execute(commands: (CTX) -> T): T + } interface KinectCamera { @@ -51,6 +54,19 @@ interface KinectCamera { val height: Int var mirror: Boolean val currentFrame: ColorBuffer + /** + * Returns the latest frame, but only once. Useful for the scenarios + * where each new frame triggers extra computation. Therefore the same + * expensive operation might happen only once, especially when the refresh + * rate of the target screen is higher than kinect's 30 fps. + *

+ * Example usage: + *

+     * kinect.depthCamera.getLatestFrame()?.let { frame ->
+     *     grayscaleFilter.apply(frame, grayscaleBuffer)
+     * }
+     * 
+ */ fun getLatestFrame(): ColorBuffer? } diff --git a/orx-kinect-common/src/main/kotlin/KinectImpl.kt b/orx-kinect-common/src/main/kotlin/org/openrndr/extra/kinect/impl/KinectImpl.kt similarity index 82% rename from orx-kinect-common/src/main/kotlin/KinectImpl.kt rename to orx-kinect-common/src/main/kotlin/org/openrndr/extra/kinect/impl/KinectImpl.kt index 85d3e12e..c7a0dab8 100644 --- a/orx-kinect-common/src/main/kotlin/KinectImpl.kt +++ b/orx-kinect-common/src/main/kotlin/org/openrndr/extra/kinect/impl/KinectImpl.kt @@ -1,7 +1,10 @@ -package org.openrndr.extra.kinect +package org.openrndr.extra.kinect.impl import org.openrndr.Program import org.openrndr.draw.* +import org.openrndr.extra.kinect.KinectDepthCamera +import org.openrndr.extra.kinect.KinectDevice +import org.openrndr.extra.kinect.Kinects import org.openrndr.math.Vector2 import org.openrndr.resourceUrl import java.nio.ByteBuffer @@ -9,8 +12,11 @@ import java.util.concurrent.atomic.AtomicReference import java.util.function.Supplier import kotlin.concurrent.thread +class DefaultKinects( + private val program: Program, + private val manager: KinectsManager +) : Kinects { -class DefaultKinects(private val manager: KinectsManager) : Kinects { init { manager.initialize() // as we don't have explicit shutdown mechanism in OPENRNDR @@ -31,10 +37,12 @@ class DefaultKinects(private val manager: KinectsManager) : Kinects { - return manager.startDevice(num) + val device = manager.startDevice(num) + program.extend(device) + return device } - override fun execute(commands: (CTX) -> Any): Any { + override fun execute(commands: (CTX) -> T): T { return manager.execute(commands) } @@ -44,7 +52,7 @@ interface KinectsManager { fun initialize() fun countDevices(): Int fun startDevice(num: Int): KinectDevice - fun execute(commands: (CTX) -> Any): Any + fun execute(commands: (CTX) -> T): T fun shutdown() } @@ -53,7 +61,7 @@ interface KinectFeatureEnabler { } interface KinectCommandsExecutor { - fun execute(commands: (CTX) -> Any): Any + fun execute(commands: (CTX) -> T): T } class DefaultKinectDevice( @@ -64,7 +72,8 @@ class DefaultKinectDevice( override fun beforeDraw(drawer: Drawer, program: Program) { depthCamera.update() } - override fun execute(commands: (CTX) -> Any): Any { + + override fun execute(commands: (CTX) -> T): T { return commandsExecutor.execute(commands) } } @@ -128,7 +137,10 @@ class DefaultKinectDepthCamera( } private class KinectRawDataToDepthMapper : - Filter(filterShaderFromUrl(resourceUrl("kinect-raw-to-depth.frag", Kinects::class.java))) { + Filter(filterShaderFromUrl( + resourceUrl("kinect-raw-to-depth.frag", + DefaultKinects::class.java)) + ) { var depthScale: Double by parameters var mirror: Boolean by parameters var resolution: Vector2 by parameters diff --git a/orx-kinect-common/src/main/resources/org/openrndr/extra/kinect/kinect-raw-to-depth.frag b/orx-kinect-common/src/main/resources/org/openrndr/extra/kinect/impl/kinect-raw-to-depth.frag similarity index 100% rename from orx-kinect-common/src/main/resources/org/openrndr/extra/kinect/kinect-raw-to-depth.frag rename to orx-kinect-common/src/main/resources/org/openrndr/extra/kinect/impl/kinect-raw-to-depth.frag