Add orx-view-box, adjust for api changes in OPENRNDR

This commit is contained in:
Edwin Jakobs
2022-11-30 11:32:12 +01:00
parent 711222db33
commit 4c22687763
16 changed files with 349 additions and 33 deletions

View File

@@ -4,6 +4,7 @@ import org.openrndr.Extension
import org.openrndr.MouseEvents
import org.openrndr.Program
import org.openrndr.draw.Drawer
import org.openrndr.draw.RenderTarget
import org.openrndr.math.Matrix44
import org.openrndr.math.transforms.buildTransform
@@ -36,6 +37,14 @@ class Camera2D : Extension {
}
override fun beforeDraw(drawer: Drawer, program: Program) {
drawer.pushTransforms()
drawer.ortho(RenderTarget.active)
drawer.view = view
}
}
override fun afterDraw(drawer: Drawer, program: Program) {
drawer.popTransforms()
}
}

View File

@@ -168,6 +168,9 @@ class OrbitalCamera(eye: Vector3 = Vector3.ZERO, lookAt: Vector3 = Vector3.UNIT_
override var enabled: Boolean = true
override fun beforeDraw(drawer: Drawer, program: Program) {
drawer.pushTransforms()
if (lastSeconds == -1.0) lastSeconds = program.seconds
val delta = program.seconds - lastSeconds
@@ -178,8 +181,7 @@ class OrbitalCamera(eye: Vector3 = Vector3.ZERO, lookAt: Vector3 = Vector3.UNIT_
}
override fun afterDraw(drawer: Drawer, program: Program) {
drawer.view = Matrix44.IDENTITY
drawer.ortho()
drawer.popTransforms()
}
}
@@ -206,7 +208,6 @@ fun OrbitalCamera.isolated(drawer: Drawer, function: Drawer.() -> Unit) {
* if you don't need to revert back to the orthographic projection.
*/
fun OrbitalCamera.applyTo(drawer: Drawer) {
if (projectionType == ProjectionType.PERSPECTIVE) {
drawer.perspective(fov, drawer.width.toDouble() / drawer.height, near, far)
} else {

View File

@@ -57,14 +57,14 @@ class OrbitalControls(
// half of the fov is center to top of screen
val targetDistance = offset.length * tan(fov.asRadians / 2)
val panX = (2 * delta.x * targetDistance / program.window.size.x)
val panY = (2 * delta.y * targetDistance / program.window.size.y)
val panX = (2 * delta.x * targetDistance / program.width)
val panY = (2 * delta.y * targetDistance / program.height)
orbitalCamera.pan(panX, -panY, 0.0)
} else {
val rotX = 360.0 * delta.x / program.window.size.x
val rotY = 360.0 * delta.y / program.window.size.y
val rotX = 360.0 * delta.x / program.width
val rotY = 360.0 * delta.y / program.height
orbitalCamera.rotate(rotX, rotY)
}
}

View File

@@ -138,16 +138,3 @@ private val watchThread by lazy {
}
}
}
fun main() {
val a = watchFile(Program(), File("README.md")) {
it.readText()
}
a.stop()
a.triggerChange()
while (true) {
println(a())
Thread.sleep(2000)
}
}

View File

@@ -77,7 +77,6 @@ class Olive<P : Program>(val resources: Resources? = null, private var scriptMod
val originalExtensions = program.extensions.map { it }
val trackedListeners = listOf<Event<*>>(program.mouse.buttonDown,
program.mouse.buttonUp,
program.mouse.clicked,
program.mouse.dragged,
program.mouse.moved,
program.mouse.scrolled,

View File

@@ -2,13 +2,14 @@ package org.openrndr.extra.olive
import org.openrndr.ApplicationBuilder
import org.openrndr.Program
import org.openrndr.ProgramImplementation
import java.io.File
import java.nio.file.Files
import java.nio.file.Paths
import kotlin.reflect.KProperty
import kotlin.streams.toList
open class OliveProgram(private val sourceLocation: String, private val scriptHost: OliveScriptHost, resources: Resources?) : Program() {
open class OliveProgram(private val sourceLocation: String, private val scriptHost: OliveScriptHost, resources: Resources?) : ProgramImplementation() {
val olive = extend(Olive<OliveProgram>(scriptMode = ScriptMode.OLIVE_PROGRAM, resources = resources)) {
script = sourceLocation
scriptHost = this@OliveProgram.scriptHost

View File

@@ -73,7 +73,7 @@ class ControlManager : Extension {
var body: Element? = null
val layouter = Layouter()
val fontManager = FontManager()
lateinit var window: Program.Window
lateinit var window: Window
private val renderTargetCache = HashMap<Element, RenderTarget>()
lateinit var program: Program
@@ -524,7 +524,7 @@ class ControlManager : Extension {
}
profile("draw image") {
drawer.ortho()
drawer.ortho(RenderTarget.active)
drawer.view = Matrix44.IDENTITY
drawer.defaults()
program.drawer.image(renderTarget.colorBuffer(0), 0.0, 0.0)

View File

@@ -6,4 +6,6 @@ dependencies {
implementation(libs.openrndr.application)
implementation(libs.openrndr.math)
demoImplementation(project(":orx-shapes"))
demoImplementation(project(":orx-mesh-generators"))
demoImplementation(project(":orx-camera"))
}

View File

@@ -3,9 +3,7 @@ package org.openrndr.extra.palette
import mu.KotlinLogging
import com.google.gson.GsonBuilder
import com.google.gson.JsonParseException
import org.openrndr.Extension
import org.openrndr.Keyboard
import org.openrndr.Program
import org.openrndr.*
import org.openrndr.extra.noise.Random
import org.openrndr.color.ColorRGBa
import org.openrndr.color.ColorRGBa.Companion.BLACK
@@ -14,7 +12,6 @@ import org.openrndr.color.ColorRGBa.Companion.PINK
import org.openrndr.color.ColorRGBa.Companion.RED
import org.openrndr.color.ColorRGBa.Companion.YELLOW
import org.openrndr.color.ColorRGBa.Companion.fromHex
import org.openrndr.resourceUrl
import java.io.File
import java.net.URL
import kotlin.math.max
@@ -232,7 +229,7 @@ class PaletteStudio(
palettes.clear()
}
private fun registerKeybindings(keyboard: Keyboard) {
private fun registerKeybindings(keyboard: KeyEvents) {
keyboard.keyDown.listen {
if (!it.propagationCancelled) {
if (it.name == "$randomPaletteKey") {

View File

@@ -28,7 +28,8 @@ class LFO(wave: LFOWave = LFOWave.Saw) : TimeTools {
private var time = 0.0
override fun tick(seconds: Double, deltaTime: Double, frameCount: Int) {
time += deltaTime
//time += deltaTime
time = seconds
}
fun sample(frequency: Double = 1.0, phase: Double = 0.0): Double {

View File

@@ -18,6 +18,6 @@ class TimeOperators : Extension {
}
override fun beforeDraw(drawer: Drawer, program: Program) {
operators.forEach { it.tick(program.seconds, program.deltaTime, program.frameCount) }
operators.forEach { it.tick(program.seconds, 0.0, 0) }
}
}

4
orx-view-box/README.md Normal file
View File

@@ -0,0 +1,4 @@
# orx-view-box
Tools to provide view box support

View File

@@ -0,0 +1,43 @@
import ScreenshotsHelper.collectScreenshots
plugins {
org.openrndr.extra.convention.`kotlin-multiplatform`
}
kotlin {
jvm {
@Suppress("UNUSED_VARIABLE")
val demo by compilations.getting {
// TODO: Move demos to /jvmDemo
defaultSourceSet {
kotlin.srcDir("src/demo/kotlin")
}
collectScreenshots { }
}
testRuns["test"].executionTask {
useJUnitPlatform {
includeEngines("spek2")
}
}
}
sourceSets {
@Suppress("UNUSED_VARIABLE")
val commonMain by getting {
dependencies {
implementation(libs.openrndr.application)
implementation(libs.openrndr.draw)
}
}
@Suppress("UNUSED_VARIABLE")
val jvmDemo by getting {
dependencies {
implementation(project(":orx-camera"))
implementation(project(":orx-fx"))
implementation(project(":orx-mesh-generators"))
implementation(project(":orx-view-box"))
}
}
}
}

View File

@@ -0,0 +1,213 @@
package org.openrndr.extra.viewbox
import org.openrndr.*
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.*
import org.openrndr.events.Event
import org.openrndr.math.Vector2
import org.openrndr.shape.Rectangle
import kotlin.math.ceil
class ViewBox(override val program: Program, var clientArea: Rectangle) : Program by program {
override var width: Int
get() {
return renderTarget?.width ?: clientArea.width.toInt()
}
set(value) {}
override var height: Int
get() = renderTarget?.height ?: clientArea.height.toInt()
set(value) {}
private var renderTarget: RenderTarget? = null
private var resolved: ColorBuffer? = null
override val extensions: MutableList<Extension> = mutableListOf<Extension>()
override val mouse: MouseEvents = object :MouseEvents{
override val buttonDown = Event<MouseEvent>()
override val buttonUp = Event<MouseEvent>()
override val dragged = Event<MouseEvent>()
override val entered = Event<MouseEvent>()
override val exited = Event<MouseEvent>()
override val moved = Event<MouseEvent>()
override val position: Vector2
get() = TODO("Not yet implemented")
override val pressedButtons: MutableSet<MouseButton>
get() = TODO("Not yet implemented")
override val scrolled = Event<MouseEvent>()
}
override val keyboard: KeyEvents = object: KeyEvents {
override val character: Event<CharacterEvent> = Event<CharacterEvent>()
override val keyDown: Event<KeyEvent> = Event<KeyEvent>()
override val keyRepeat: Event<KeyEvent> = Event<KeyEvent>()
override val keyUp: Event<KeyEvent> = Event<KeyEvent>()
}
override val pointers: Pointers by lazy { program.pointers }
var hasInputFocus = false
init {
program.mouse.moved.listen {
if (it.position in clientArea && !it.propagationCancelled) {
hasInputFocus = true
mouse.moved.trigger(it.copy(position = it.position - clientArea.corner))
it.cancelPropagation()
} else if (it.position !in clientArea) {
hasInputFocus = false
}
}
program.mouse.buttonUp.listen {
if (it.position in clientArea && !it.propagationCancelled) {
mouse.buttonUp.trigger(it.copy(position = it.position - clientArea.corner))
it.cancelPropagation()
}
}
program.mouse.dragged.listen {
if (it.position in clientArea && !it.propagationCancelled) {
mouse.dragged.trigger(it.copy(position = it.position - clientArea.corner))
it.cancelPropagation()
}
}
program.mouse.buttonDown.listen {
if (it.position in clientArea && !it.propagationCancelled) {
mouse.buttonDown.trigger(it.copy(position = it.position - clientArea.corner))
it.cancelPropagation()
}
}
program.mouse.scrolled.listen {
if (it.position in clientArea && !it.propagationCancelled) {
mouse.scrolled.trigger(it.copy(position = it.position - clientArea.corner))
it.cancelPropagation()
}
}
program.keyboard.keyDown.listen {
if (hasInputFocus && !it.propagationCancelled) {
keyboard.keyDown.trigger(it)
it.cancelPropagation()
}
}
program.keyboard.keyUp.listen {
if (hasInputFocus && !it.propagationCancelled) {
keyboard.keyUp.trigger(it)
it.cancelPropagation()
}
}
program.keyboard.keyRepeat.listen {
if (hasInputFocus && !it.propagationCancelled) {
keyboard.keyRepeat.trigger(it)
it.cancelPropagation()
}
}
program.keyboard.character.listen {
if (hasInputFocus && !it.propagationCancelled) {
keyboard.character.trigger(it)
it.cancelPropagation()
}
}
}
override fun <T : Extension> extend(extension: T): T {
extensions.add(extension)
extension.setup(this)
return extension
}
override fun <T : Extension> extend(extension: T, configure: T.() -> Unit): T {
extensions.add(extension)
extension.configure()
extension.setup(this)
return extension
}
override fun extend(stage: ExtensionStage, userDraw: Program.() -> Unit) {
val functionExtension = when (stage) {
ExtensionStage.SETUP ->
object : Extension {
override var enabled: Boolean = true
override fun setup(program: Program) {
program.userDraw()
}
}
ExtensionStage.BEFORE_DRAW ->
object : Extension {
override var enabled: Boolean = true
override fun beforeDraw(drawer: Drawer, program: Program) {
program.userDraw()
}
}
ExtensionStage.AFTER_DRAW ->
object : Extension {
override var enabled: Boolean = true
override fun afterDraw(drawer: Drawer, program: Program) {
program.userDraw()
}
}
}
extensions.add(functionExtension)
}
override fun draw() {
val widthCeil = ceil(clientArea.width).toInt()
val heightCeil = ceil(clientArea.height).toInt()
val lrt = renderTarget
if (lrt != null) {
if (lrt.width != widthCeil || lrt.height != heightCeil) {
lrt.colorBuffer(0).destroy()
lrt.depthBuffer?.destroy()
lrt.detachColorAttachments()
lrt.detachDepthBuffer()
lrt.destroy()
renderTarget = null
resolved?.destroy()
resolved = null
}
}
if (renderTarget == null) {
val art = RenderTarget.active
renderTarget = renderTarget(widthCeil, heightCeil, art.contentScale, art.multisample) {
colorBuffer()
depthBuffer()
}
if (art.multisample != BufferMultisample.Disabled) {
resolved = colorBuffer(widthCeil, heightCeil, art.contentScale, multisample = art.multisample)
}
}
program.drawer.isolatedWithTarget(renderTarget!!) {
drawer.clear(ColorRGBa.BLACK)
drawer.defaults()
drawer.ortho(renderTarget!!)
for (extension in extensions) {
extension.beforeDraw(program.drawer, this@ViewBox)
}
for (extension in extensions.reversed()) {
extension.afterDraw(program.drawer, this@ViewBox)
}
program.drawer.defaults()
}
program.drawer.isolated {
program.drawer.image(renderTarget!!.colorBuffer(0), clientArea.corner)
}
}
}
fun Program.viewBox(area: Rectangle, f: ViewBox.() -> Unit): ViewBox {
val viewBox = ViewBox(this, area)
viewBox.f()
return viewBox
}

View File

@@ -0,0 +1,58 @@
import org.openrndr.application
import org.openrndr.draw.DrawPrimitive
import org.openrndr.extensions.Screenshots
import org.openrndr.extra.camera.Camera2D
import org.openrndr.extra.camera.Orbital
import org.openrndr.extra.fx.Post
import org.openrndr.extra.fx.blur.ApproximateGaussianBlur
import org.openrndr.extra.meshgenerators.boxMesh
import org.openrndr.extra.viewbox.viewBox
import org.openrndr.shape.Rectangle
fun main() {
application {
configure {
width = 800
height = 800
}
program {
val vbx = viewBox(Rectangle(0.0, 0.0, 200.0, 800.0)) {
extend(Screenshots())
extend(Camera2D())
extend {
drawer.rectangle(20.0, 20.0, 100.0, 100.0)
}
}
val vbx2 = viewBox(Rectangle(200.0, 0.0, 200.0, 800.0)) {
extend(Post()) {
val blur = ApproximateGaussianBlur()
blur.sigma = 10.0
blur.window = 25
post { i, o ->
blur.apply(i, o)
}
}
extend(Camera2D())
extend {
drawer.rectangle(20.0, 20.0, 100.0, 100.0)
}
}
val vbx3d = viewBox(Rectangle(400.0, 0.0, 400.0, 800.0)) {
extend(Orbital())
val cube = boxMesh()
extend {
drawer.vertexBuffer(cube, DrawPrimitive.TRIANGLES)
}
}
extend {
vbx.draw()
vbx2.draw()
vbx3d.draw()
}
}
}
}

View File

@@ -82,6 +82,7 @@ include(
"orx-jvm:orx-kinect-v1-demo",
"orx-jvm:orx-video-profiles",
"orx-depth-camera",
"orx-jvm:orx-depth-camera-calibrator"
"orx-jvm:orx-depth-camera-calibrator",
"orx-view-box"
)
)