[orx-shapes, orx-mesh-generator] Move frames code from orx-mesh-generator to orx-shapes
This commit is contained in:
@@ -9,6 +9,7 @@ kotlin {
|
|||||||
dependencies {
|
dependencies {
|
||||||
api(libs.openrndr.application)
|
api(libs.openrndr.application)
|
||||||
api(libs.openrndr.math)
|
api(libs.openrndr.math)
|
||||||
|
implementation(project(":orx-shapes"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
package org.openrndr.extra.meshgenerators
|
package org.openrndr.extra.meshgenerators
|
||||||
|
|
||||||
|
import org.openrndr.extra.shapes.frames.frames
|
||||||
import org.openrndr.math.Matrix44
|
import org.openrndr.math.Matrix44
|
||||||
import org.openrndr.math.Vector2
|
import org.openrndr.math.Vector2
|
||||||
import org.openrndr.math.Vector3
|
import org.openrndr.math.Vector3
|
||||||
import org.openrndr.math.Vector4
|
|
||||||
import org.openrndr.math.transforms.normalMatrix
|
|
||||||
import org.openrndr.shape.Path3D
|
import org.openrndr.shape.Path3D
|
||||||
import org.openrndr.shape.Shape
|
import org.openrndr.shape.Shape
|
||||||
import org.openrndr.shape.ShapeContour
|
import org.openrndr.shape.ShapeContour
|
||||||
import org.openrndr.shape.Triangle
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes quads to [writer] creating a surface that connects two
|
* Writes quads to [writer] creating a surface that connects two
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.openrndr.extra.meshgenerators
|
package org.openrndr.extra.meshgenerators
|
||||||
|
|
||||||
|
import org.openrndr.extra.shapes.frames.frames
|
||||||
import org.openrndr.math.Matrix44
|
import org.openrndr.math.Matrix44
|
||||||
import org.openrndr.math.Vector3
|
import org.openrndr.math.Vector3
|
||||||
import org.openrndr.shape.Path3D
|
import org.openrndr.shape.Path3D
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.openrndr.extra.meshgenerators
|
package org.openrndr.extra.meshgenerators
|
||||||
|
|
||||||
|
import org.openrndr.extra.shapes.frames.frames
|
||||||
import org.openrndr.math.Matrix44
|
import org.openrndr.math.Matrix44
|
||||||
import org.openrndr.math.Vector3
|
import org.openrndr.math.Vector3
|
||||||
import org.openrndr.shape.Path3D
|
import org.openrndr.shape.Path3D
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.openrndr.extra.meshgenerators
|
package org.openrndr.extra.shapes.frames
|
||||||
|
|
||||||
import org.openrndr.math.Matrix44
|
import org.openrndr.math.Matrix44
|
||||||
import org.openrndr.math.Vector3
|
import org.openrndr.math.Vector3
|
||||||
@@ -9,45 +9,51 @@ import org.openrndr.math.transforms.buildTransform
|
|||||||
* Calculate frames (pose matrices) using parallel transport
|
* Calculate frames (pose matrices) using parallel transport
|
||||||
* @param up0 initial up vector, should not be collinear with `this[1] - this[0]`
|
* @param up0 initial up vector, should not be collinear with `this[1] - this[0]`
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fun List<Vector3>.frames(up0: Vector3): List<Matrix44> {
|
fun List<Vector3>.frames(up0: Vector3): List<Matrix44> {
|
||||||
|
return frames(this, up0 = up0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun frames(positions: List<Vector3>, directions: List<Vector3> = emptyList(), up0: Vector3): List<Matrix44> {
|
||||||
|
|
||||||
|
require(up0.squaredLength > 0.0) {
|
||||||
|
"up0 ($up0) has 0 or NaN length"
|
||||||
|
}
|
||||||
|
|
||||||
val result = mutableListOf<Matrix44>()
|
val result = mutableListOf<Matrix44>()
|
||||||
|
|
||||||
if (this.isEmpty()) {
|
if (positions.isEmpty()) {
|
||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.size == 1) {
|
if (positions.size == 1) {
|
||||||
return listOf(Matrix44.IDENTITY)
|
return listOf(Matrix44.IDENTITY)
|
||||||
}
|
}
|
||||||
|
|
||||||
var up = up0.normalized
|
var up = up0.normalized
|
||||||
run {
|
run {
|
||||||
val current = this[0]
|
val current = positions[0]
|
||||||
val next = this[1]
|
val next = positions[1]
|
||||||
val forward = (next - current).normalized
|
val forward = (directions.getOrNull(0) ?: (next - current)).normalized
|
||||||
val right = (forward cross up).normalized
|
val right = (forward cross up).normalized
|
||||||
up = ((right cross forward)).normalized
|
up = ((right cross forward)).normalized
|
||||||
result.add(Matrix44.fromColumnVectors(right.xyz0, up.xyz0, forward.xyz0, current.xyz1))
|
result.add(Matrix44.fromColumnVectors(right.xyz0, up.xyz0, forward.xyz0, current.xyz1))
|
||||||
}
|
}
|
||||||
|
|
||||||
require(up.length > 0.0) { "initial `up.length` is zero in .frames()" }
|
for (i in 1 until positions.size - 1) {
|
||||||
|
val prev = positions[i - 1]
|
||||||
for (i in 1 until size - 1) {
|
val current = positions[i]
|
||||||
val prev = this[i - 1]
|
val next = positions[i + 1]
|
||||||
val current = this[i]
|
|
||||||
val next = this[i + 1]
|
|
||||||
val f1 = (next - current).normalized
|
val f1 = (next - current).normalized
|
||||||
val f0 = (current - prev).normalized
|
val f0 = (current - prev).normalized
|
||||||
|
|
||||||
val forward = (f0 + f1).normalized
|
val forward = (directions.getOrNull(i) ?: (f0 + f1)).normalized
|
||||||
require(forward.length > 0.0) { "`forward.length` is zero in .frames()" }
|
require(forward.length > 0.0) { "`forward.length` is zero or NaN in .frames()" }
|
||||||
val right = (forward cross up).normalized
|
val right = (forward cross up).normalized
|
||||||
up = ((right cross forward)).normalized
|
up = ((right cross forward)).normalized
|
||||||
|
|
||||||
require(up.length > 0.0) { "`up.length` is zero in .frames()" }
|
require(up.length > 0.0) { "`up.length` is zero or NaN in .frames()" }
|
||||||
require(right.length > 0.0) { "`right.length` is zero in .frames()" }
|
require(right.length > 0.0) { "`right.length` is zero or NaN in .frames()" }
|
||||||
|
|
||||||
//val m = Matrix44.fromColumnVectors(right.xyz0, up.xyz0, forward.xyz0, current.xyz1)
|
|
||||||
|
|
||||||
val m = buildTransform {
|
val m = buildTransform {
|
||||||
translate(current)
|
translate(current)
|
||||||
20
orx-shapes/src/commonMain/kotlin/frames/Path3DExtensions.kt
Normal file
20
orx-shapes/src/commonMain/kotlin/frames/Path3DExtensions.kt
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package org.openrndr.extra.shapes.frames
|
||||||
|
|
||||||
|
import org.openrndr.extra.shapes.rectify.RectifiedPath3D
|
||||||
|
import org.openrndr.math.Matrix44
|
||||||
|
import org.openrndr.math.Vector3
|
||||||
|
import org.openrndr.shape.Path3D
|
||||||
|
|
||||||
|
fun Path3D.frames(ascendingTs: List<Double>, up0: Vector3, analyticalDirections: Boolean) : List<Matrix44> {
|
||||||
|
val positions = ascendingTs.map { this.position(it) }
|
||||||
|
val directions = if (analyticalDirections) ascendingTs.map { this.direction(it) } else emptyList()
|
||||||
|
|
||||||
|
return frames(positions, directions, up0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun RectifiedPath3D.frames(ascendingTs: List<Double>, up0: Vector3, analyticalDirections: Boolean = true) : List<Matrix44> {
|
||||||
|
val positions = ascendingTs.map { this.position(it) }
|
||||||
|
val directions = if (analyticalDirections) ascendingTs.map { this.direction(it) } else emptyList()
|
||||||
|
|
||||||
|
return frames(positions, directions, up0)
|
||||||
|
}
|
||||||
@@ -92,6 +92,14 @@ abstract class RectifiedPath<T : EuclideanVector<T>>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun direction(t: Double): T {
|
||||||
|
return if (path.empty) {
|
||||||
|
path.infinity
|
||||||
|
} else {
|
||||||
|
path.direction(rectify(safe(t)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
abstract fun sub(t0: Double, t1: Double): Path<T>
|
abstract fun sub(t0: Double, t1: Double): Path<T>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import org.openrndr.extra.shapes.tunni.tunniPoint
|
|||||||
import org.openrndr.extra.shapes.tunni.withTunniLine
|
import org.openrndr.extra.shapes.tunni.withTunniLine
|
||||||
import org.openrndr.launch
|
import org.openrndr.launch
|
||||||
import org.openrndr.math.Vector2
|
import org.openrndr.math.Vector2
|
||||||
import org.openrndr.shape.Segment
|
import org.openrndr.shape.Segment2D
|
||||||
import kotlin.math.cos
|
import kotlin.math.cos
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
@@ -21,7 +21,7 @@ fun main() {
|
|||||||
program {
|
program {
|
||||||
|
|
||||||
var res = drawer.bounds.offsetEdges(-200.0).contour
|
var res = drawer.bounds.offsetEdges(-200.0).contour
|
||||||
var selectedSegments = emptyList<Segment>()
|
var selectedSegments = emptyList<Segment2D>()
|
||||||
var selectedPoints = emptyList<Vector2>()
|
var selectedPoints = emptyList<Vector2>()
|
||||||
|
|
||||||
val contourSeq = adjustContourSequence(res) {
|
val contourSeq = adjustContourSequence(res) {
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package arrangement
|
||||||
|
|
||||||
|
import org.openrndr.application
|
||||||
|
import org.openrndr.color.ColorRGBa
|
||||||
|
import org.openrndr.color.rgb
|
||||||
|
import org.openrndr.extra.color.spaces.OKHSV
|
||||||
|
import org.openrndr.extra.color.tools.saturate
|
||||||
|
import org.openrndr.extra.noise.uniform
|
||||||
|
import org.openrndr.extra.shapes.arrangement.Arrangement
|
||||||
|
import org.openrndr.math.Vector2
|
||||||
|
import org.openrndr.shape.Circle
|
||||||
|
import kotlin.math.sqrt
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
application {
|
||||||
|
program {
|
||||||
|
val circles = listOf(
|
||||||
|
Circle(drawer.bounds.center -Vector2(50.0, 0.0), 50.0),
|
||||||
|
Circle(drawer.bounds.center + Vector2(50.0, 0.0), 50.0),
|
||||||
|
Circle(drawer.bounds.center + Vector2(0.0, 50.0), 50.0),
|
||||||
|
Circle(drawer.bounds.center - Vector2(0.0, 50.0), 50.0),
|
||||||
|
Circle(drawer.bounds.center -Vector2(50.0, 0.0), sqrt(50.0*50.0+50.0*50.0)-49.9),
|
||||||
|
Circle(drawer.bounds.center +Vector2(50.0, 0.0), sqrt(50.0*50.0+50.0*50.0)-49.9),
|
||||||
|
Circle(drawer.bounds.center -Vector2(0.0, 50.0), sqrt(50.0*50.0+50.0*50.0)-49.9),
|
||||||
|
Circle(drawer.bounds.center +Vector2(0.0, 50.0), sqrt(50.0*50.0+50.0*50.0)-49.9),
|
||||||
|
).shuffled()
|
||||||
|
|
||||||
|
val arr = Arrangement(circles)
|
||||||
|
|
||||||
|
extend {
|
||||||
|
val r = Random(100)
|
||||||
|
drawer.stroke = ColorRGBa.WHITE
|
||||||
|
for (f in arr.boundedFaces) {
|
||||||
|
drawer.fill =
|
||||||
|
|
||||||
|
rgb(Double.uniform(0.0, 1.0, r), Double.uniform(0.0, 1.0, r), Double.uniform(0.0, 1.0, r)).saturate<OKHSV>(0.25)
|
||||||
|
drawer.contour(f.contour)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
65
orx-shapes/src/jvmDemo/kotlin/frames/DemoFrames01.kt
Normal file
65
orx-shapes/src/jvmDemo/kotlin/frames/DemoFrames01.kt
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
package frames
|
||||||
|
|
||||||
|
import org.openrndr.application
|
||||||
|
import org.openrndr.color.ColorRGBa
|
||||||
|
import org.openrndr.draw.DrawPrimitive
|
||||||
|
import org.openrndr.draw.isolated
|
||||||
|
import org.openrndr.draw.shadeStyle
|
||||||
|
import org.openrndr.extra.camera.Orbital
|
||||||
|
import org.openrndr.extra.meshgenerators.cylinderMesh
|
||||||
|
import org.openrndr.extra.noise.uniformRing
|
||||||
|
import org.openrndr.extra.shapes.frames.frames
|
||||||
|
import org.openrndr.extra.shapes.rectify.rectified
|
||||||
|
import org.openrndr.math.Vector3
|
||||||
|
import org.openrndr.shape.path3D
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
application {
|
||||||
|
configure {
|
||||||
|
width = 720
|
||||||
|
height = 720
|
||||||
|
}
|
||||||
|
program {
|
||||||
|
val random = Random(0)
|
||||||
|
val cylinder = cylinderMesh(radius = 0.5, length = 0.1)
|
||||||
|
val p = path3D {
|
||||||
|
moveTo(0.0, 0.0, 0.0)
|
||||||
|
curveTo(
|
||||||
|
Vector3.uniformRing(0.1, 1.0, random = random)*10.0,
|
||||||
|
Vector3.uniformRing(0.1, 1.0, random = random)*10.0,
|
||||||
|
Vector3.uniformRing(0.1, 1.0, random = random)*10.0
|
||||||
|
)
|
||||||
|
for (i in 0 until 10) {
|
||||||
|
continueTo(
|
||||||
|
Vector3.uniformRing(0.1, 1.0, random = random)*10.0,
|
||||||
|
Vector3.uniformRing(0.1, 1.0, random = random)*10.0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val pr = p.rectified(0.01, 100.0)
|
||||||
|
|
||||||
|
|
||||||
|
val frames = pr.frames((0 until 100).map { it / 100.0}, Vector3.UNIT_Y)
|
||||||
|
extend(Orbital())
|
||||||
|
extend {
|
||||||
|
drawer.shadeStyle = shadeStyle {
|
||||||
|
fragmentTransform = """
|
||||||
|
x_fill.rgb = vec3(abs(v_viewNormal.z)*0.9+ 0.1);
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
|
||||||
|
drawer.stroke = ColorRGBa.PINK
|
||||||
|
drawer.path(p)
|
||||||
|
|
||||||
|
for (frame in frames) {
|
||||||
|
drawer.isolated {
|
||||||
|
drawer.model = frame
|
||||||
|
drawer.vertexBuffer(cylinder, DrawPrimitive.TRIANGLES)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user