Demos: ensure 720px wide, reduce indentation

This commit is contained in:
Abe Pazos
2025-01-24 23:05:40 +01:00
parent ca8fbc1c0a
commit f84bf69713
31 changed files with 961 additions and 964 deletions

View File

@@ -11,34 +11,32 @@ import org.openrndr.shape.LineSegment
* cursor are highlighted with circles and lines connecting them to the cursor. * cursor are highlighted with circles and lines connecting them to the cursor.
* *
* Key features: * Key features:
* - Generates 1000 random 2D points within the canvas dimensions (1080x720). * - Generates 1000 random 2D points within the canvas.
* - Builds a KD-tree from the list of points for optimized spatial querying. * - Builds a KD-tree from the list of points for optimized spatial querying.
* - Visualizes the points and highlights the 7 nearest neighbors to the user's cursor position dynamically. * - Visualizes the points and highlights the 7 nearest neighbors to the user's cursor position dynamically.
* - Highlights include red-colored circles around the nearest points and red lines connecting them to the cursor. * - Highlights include red-colored circles around the nearest points and red lines connecting them to the cursor.
*/ */
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 1080 height = 720
height = 720 }
program {
val points = MutableList(1000) {
Vector2(Math.random() * width, Math.random() * height)
} }
val tree = points.kdTree()
program { extend {
val points = MutableList(1000) { drawer.circles(points, 5.0)
Vector2(Math.random() * width, Math.random() * height)
}
val tree = points.kdTree()
extend { val kNearest = tree.findKNearest(mouse.position, k = 7)
drawer.circles(points, 5.0) drawer.fill = ColorRGBa.RED
drawer.stroke = ColorRGBa.RED
val kNearest = tree.findKNearest(mouse.position, k = 7) drawer.strokeWeight = 2.0
drawer.fill = ColorRGBa.RED drawer.circles(kNearest, 7.0)
drawer.stroke = ColorRGBa.RED drawer.lineSegments(kNearest.map { LineSegment(mouse.position, it) })
drawer.strokeWeight = 2.0
drawer.circles(kNearest, 7.0)
drawer.lineSegments(kNearest.map { LineSegment(mouse.position, it) })
}
} }
} }
} }

View File

@@ -3,8 +3,8 @@ import org.openrndr.extra.kdtree.kdTree
import org.openrndr.math.Vector2 import org.openrndr.math.Vector2
/** /**
* Initializes an interactive graphical application that displays 1000 randomly distributed 2D points * Initializes an interactive graphical application that displays 1000 randomly distributed 2D points.
* on a canvas of dimensions 1280x720. The points are organized into a KD-tree for efficient spatial querying. * The points are organized into a KD-tree for efficient spatial querying.
* *
* Key functionality: * Key functionality:
* - Displays the points as small circles on the canvas. * - Displays the points as small circles on the canvas.
@@ -14,23 +14,21 @@ import org.openrndr.math.Vector2
* - KD-tree structure enables efficient nearest-neighbor searches. * - KD-tree structure enables efficient nearest-neighbor searches.
* - The nearest point to the cursor is determined and visually emphasized in real-time as the cursor moves. * - The nearest point to the cursor is determined and visually emphasized in real-time as the cursor moves.
*/ */
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 1280 height = 720
height = 720 }
program {
val points = MutableList(1000) {
Vector2(Math.random() * width, Math.random() * height)
} }
program { val tree = points.kdTree()
val points = MutableList(1000) { extend {
Vector2(Math.random() * width, Math.random() * height) drawer.circles(points, 5.0)
} val nearest = tree.findNearest(mouse.position)
val tree = points.kdTree() nearest?.let {
extend { drawer.circle(it.x, it.y, 20.0)
drawer.circles(points, 5.0)
val nearest = tree.findNearest(mouse.position)
nearest?.let {
drawer.circle(it.x, it.y, 20.0)
}
} }
} }
} }

View File

@@ -11,40 +11,37 @@ import org.openrndr.math.Vector2
* user's cursor position. * user's cursor position.
* *
* Key features: * Key features:
* - Generates and displays 1000 random 2D points within canvas dimensions of 1080x720. * - Generates and displays 1000 random 2D points within the canvas.
* - Builds a KD-tree structure for optimized querying of spatial data. * - Builds a KD-tree structure for optimized querying of spatial data.
* - Dynamically highlights points within a specified radius (50.0) from the cursor position. * - Dynamically highlights points within a specified radius (50.0) from the cursor position.
* - Visualizes the current query radius around the cursor as an outline circle. * - Visualizes the current query radius around the cursor as an outline circle.
* - Uses different fill and stroke styles to distinguish highlighted points and query visuals. * - Uses different fill and stroke styles to distinguish highlighted points and query visuals.
*/ */
fun main() { fun main() = application {
application { configure {
width = 720
height = 720
}
configure { program {
width = 1080 val points = MutableList(1000) {
height = 720 Vector2(Math.random() * width, Math.random() * height)
} }
val tree = points.kdTree()
val radius = 50.0
program { extend {
val points = MutableList(1000) { drawer.circles(points, 5.0)
Vector2(Math.random() * width, Math.random() * height)
}
val tree = points.kdTree()
val radius = 50.0
extend { val allInRange = tree.findAllInRadius(mouse.position, radius = radius)
drawer.circles(points, 5.0) drawer.fill = ColorRGBa.PINK
drawer.stroke = ColorRGBa.PINK
drawer.strokeWeight = 2.0
drawer.circles(allInRange, 7.0)
val allInRange = tree.findAllInRadius(mouse.position, radius = radius) drawer.fill = null
drawer.fill = ColorRGBa.PINK drawer.strokeWeight = 1.0
drawer.stroke = ColorRGBa.PINK drawer.circle(mouse.position, radius)
drawer.strokeWeight = 2.0
drawer.circles(allInRange, 7.0)
drawer.fill = null
drawer.strokeWeight = 1.0
drawer.circle(mouse.position, radius)
}
} }
} }
} }

View File

@@ -3,21 +3,19 @@ import org.openrndr.color.ColorRGBa
import org.openrndr.extra.marchingsquares.findContours import org.openrndr.extra.marchingsquares.findContours
import org.openrndr.math.Vector2 import org.openrndr.math.Vector2
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 720 height = 720
height = 720 }
} program {
program { extend {
extend { drawer.clear(ColorRGBa.BLACK)
drawer.clear(ColorRGBa.BLACK) drawer.stroke = ColorRGBa.PINK
drawer.stroke = ColorRGBa.PINK fun f(v: Vector2) = v.distanceTo(drawer.bounds.center) - 200.0
fun f(v: Vector2) = v.distanceTo(drawer.bounds.center) - 200.0 val contours = findContours(::f, drawer.bounds, 16.0)
val contours = findContours(::f, drawer.bounds, 16.0) drawer.fill = null
drawer.fill = null drawer.contours(contours)
drawer.contours(contours)
}
} }
} }
} }

View File

@@ -5,21 +5,19 @@ import org.openrndr.math.Vector2
import kotlin.math.PI import kotlin.math.PI
import kotlin.math.cos import kotlin.math.cos
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 720 height = 720
height = 720 }
} program {
program { extend {
extend { drawer.clear(ColorRGBa.BLACK)
drawer.clear(ColorRGBa.BLACK) drawer.stroke = ColorRGBa.PINK
drawer.stroke = ColorRGBa.PINK fun f(v: Vector2) = cos((v.distanceTo(drawer.bounds.center) / 100.0) * 2 * PI)
fun f(v: Vector2) = cos((v.distanceTo(drawer.bounds.center) / 100.0) * 2 * PI) val contours = findContours(::f, drawer.bounds.offsetEdges(-24.0), 16.0)
val contours = findContours(::f, drawer.bounds.offsetEdges(-24.0), 16.0) drawer.fill = null
drawer.fill = null drawer.contours(contours)
drawer.contours(contours)
}
} }
} }
} }

View File

@@ -6,24 +6,23 @@ import kotlin.math.PI
import kotlin.math.cos import kotlin.math.cos
import kotlin.math.sin import kotlin.math.sin
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 720 height = 720
height = 720 }
} program {
program { extend {
extend { drawer.clear(ColorRGBa.BLACK)
drawer.clear(ColorRGBa.BLACK) drawer.stroke = ColorRGBa.PINK
drawer.stroke = ColorRGBa.PINK drawer.fill = null
drawer.fill = null fun f(v: Vector2): Double {
fun f(v: Vector2): Double { val p = v + Vector2(cos(v.y * 0.1 + seconds) * 40.0, sin(v.x * 0.1 + seconds) * 40.0)
val p = v + Vector2(cos(v.y * 0.1 + seconds) * 40.0, sin(v.x * 0.1 + seconds) * 40.0) return cos((p.distanceTo(drawer.bounds.center) / 720.0) * 12 * PI)
return cos((p.distanceTo(drawer.bounds.center) / 720.0) * 12 * PI)
}
val contours = findContours(::f, drawer.bounds.offsetEdges(-2.0), 4.0)
drawer.contours(contours)
} }
val contours = findContours(::f, drawer.bounds.offsetEdges(-2.0), 4.0)
drawer.contours(contours)
} }
} }
} }

View File

@@ -7,30 +7,30 @@ import org.openrndr.math.Vector2
import kotlin.math.PI import kotlin.math.PI
import kotlin.math.cos import kotlin.math.cos
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 640 height = 540
height = 480 }
} program {
program { val image = loadImage("demo-data/images/image-001.png")
val image = loadImage("demo-data/images/image-001.png") image.shadow.download()
image.shadow.download() extend {
extend { drawer.clear(ColorRGBa.BLACK)
drawer.clear(ColorRGBa.BLACK) drawer.stroke = ColorRGBa.BLACK
drawer.stroke = ColorRGBa.BLACK drawer.fill = null
drawer.fill = null fun f(v: Vector2): Double {
fun f(v: Vector2): Double { val iv = v.toInt()
val iv = v.toInt() val d =
val d = if (iv.x >= 0 && iv.y >= 0 && iv.x < image.width && iv.y < image.height) image.shadow[iv.x, iv.y].luminance else 0.0 if (iv.x >= 0 && iv.y >= 0 && iv.x < image.width && iv.y < image.height) image.shadow[iv.x, iv.y].luminance else 0.0
return cos(d * PI * 8.0 + seconds) return cos(d * PI * 8.0 + seconds)
}
val contours = findContours(::f, drawer.bounds.offsetEdges(32.0), 4.0)
drawer.drawStyle.colorMatrix = grayscale()
drawer.image(image)
drawer.contours(contours)
} }
val contours = findContours(::f, drawer.bounds.offsetEdges(32.0), 4.0)
drawer.drawStyle.colorMatrix = grayscale()
drawer.scale(width.toDouble() / image.width, height.toDouble() / image.height)
drawer.image(image)
drawer.contours(contours)
} }
} }
} }

View File

@@ -8,60 +8,60 @@ import org.openrndr.math.Vector2
import org.openrndr.math.Vector3 import org.openrndr.math.Vector3
import org.openrndr.shape.Rectangle import org.openrndr.shape.Rectangle
fun main() { fun main() = application {
application { configure {
configure { width = 720
multisample = WindowMultisample.SampleCount(8) height = 720
} multisample = WindowMultisample.SampleCount(8)
program { }
val meshes = listOf( program {
boxMesh(1.0, 1.0, 1.0), val meshes = listOf(
sphereMesh(radius = 0.5), boxMesh(1.0, 1.0, 1.0),
dodecahedronMesh(0.5), sphereMesh(radius = 0.5),
cylinderMesh(radius = 0.5, length = 1.0, center = true), dodecahedronMesh(0.5),
planeMesh(Vector3.ZERO, Vector3.UNIT_X, Vector3.UNIT_Y), cylinderMesh(radius = 0.5, length = 1.0, center = true),
capMesh( planeMesh(Vector3.ZERO, Vector3.UNIT_X, Vector3.UNIT_Y),
15, 0.5, capMesh(
listOf(Vector2.ZERO, Vector2(0.5, 0.2), Vector2.UNIT_X) 15, 0.5,
), listOf(Vector2.ZERO, Vector2(0.5, 0.2), Vector2.UNIT_X)
revolveMesh(5, 0.5) ),
) revolveMesh(5, 0.5)
)
val texture = colorBuffer(256, 256) val texture = colorBuffer(256, 256)
val s = texture.shadow val s = texture.shadow
for (y in 0 until 256) { for (y in 0 until 256) {
for (x in 0 until 256) { for (x in 0 until 256) {
s[x, y] = ColorRGBa(x / 256.0, y / 256.0, 0.0, 1.0) s[x, y] = ColorRGBa(x / 256.0, y / 256.0, 0.0, 1.0)
}
} }
s.upload() }
s.upload()
val positions = Rectangle.fromCenter(Vector2.ZERO, width * 0.01, height * 0.01) val positions = Rectangle.fromCenter(Vector2.ZERO, width * 0.01, height * 0.01)
.grid(4, 2).flatten().map { .grid(4, 2).flatten().map {
it.center.vector3(z = -5.0) it.center.vector3(z = -5.0)
} }
extend { extend {
drawer.clear(ColorRGBa.PINK) drawer.clear(ColorRGBa.PINK)
drawer.perspective(60.0, width * 1.0 / height, 0.01, 1000.0) drawer.perspective(60.0, width * 1.0 / height, 0.01, 1000.0)
drawer.depthWrite = true drawer.depthWrite = true
drawer.depthTestPass = DepthTestPass.LESS_OR_EQUAL drawer.depthTestPass = DepthTestPass.LESS_OR_EQUAL
drawer.shadeStyle = shadeStyle { drawer.shadeStyle = shadeStyle {
fragmentTransform = """ fragmentTransform = """
float light = dot(v_worldNormal, p_light) * 0.5 + 0.5; float light = dot(v_worldNormal, p_light) * 0.5 + 0.5;
x_fill = texture(p_texture, va_texCoord0.xy); x_fill = texture(p_texture, va_texCoord0.xy);
x_fill.rgb *= light; x_fill.rgb *= light;
""".trimIndent() """.trimIndent()
parameter("texture", texture) parameter("texture", texture)
parameter("light", Vector3(1.0).normalized) parameter("light", Vector3(1.0).normalized)
} }
meshes.forEachIndexed { i, mesh -> meshes.forEachIndexed { i, mesh ->
drawer.isolated { drawer.isolated {
translate(positions[i]) translate(positions[i])
rotate(Vector3.UNIT_Y, seconds * 12) rotate(Vector3.UNIT_Y, seconds * 12)
rotate(Vector3.UNIT_X, seconds * 25) rotate(Vector3.UNIT_X, seconds * 25)
vertexBuffer(mesh, DrawPrimitive.TRIANGLES) vertexBuffer(mesh, DrawPrimitive.TRIANGLES)
}
} }
} }
} }

View File

@@ -9,37 +9,37 @@ import org.openrndr.extra.camera.Orbital
import org.openrndr.extra.meshgenerators.boxMesh import org.openrndr.extra.meshgenerators.boxMesh
import org.openrndr.math.Vector3 import org.openrndr.math.Vector3
fun main() { fun main() = application {
application { configure {
configure { width = 720
multisample = WindowMultisample.SampleCount(8) height = 720
multisample = WindowMultisample.SampleCount(8)
}
program {
val box = boxMesh(1.0, 1.0, 1.0)
val texture = colorBuffer(256, 256)
val s = texture.shadow
for (y in 0 until 256) {
for (x in 0 until 256) {
s[x, y] = ColorRGBa(x / 256.0, y / 256.0, 0.0, 1.0)
}
} }
program { s.upload()
val box = boxMesh(1.0, 1.0, 1.0)
val texture = colorBuffer(256, 256) extend(Orbital()) {
val s = texture.shadow eye = Vector3(1.0, 1.0, 1.0)
for (y in 0 until 256) { }
for (x in 0 until 256) { extend {
s[x, y] = ColorRGBa(x/256.0, y/256.0, 0.0, 1.0) drawer.clear(ColorRGBa.PINK)
} drawer.shadeStyle = shadeStyle {
} fragmentTransform = """
s.upload()
extend(Orbital()) {
eye = Vector3(1.0, 1.0, 1.0)
}
extend {
drawer.clear(ColorRGBa.PINK)
drawer.shadeStyle = shadeStyle {
fragmentTransform = """
x_fill = texture(p_texture, va_texCoord0.xy); x_fill = texture(p_texture, va_texCoord0.xy);
""".trimIndent() """.trimIndent()
parameter("texture", texture) parameter("texture", texture)
}
drawer.drawStyle.cullTestPass = CullTestPass.FRONT
drawer.vertexBuffer(box, DrawPrimitive.TRIANGLES)
} }
drawer.drawStyle.cullTestPass = CullTestPass.FRONT
drawer.vertexBuffer(box, DrawPrimitive.TRIANGLES)
} }
} }
} }

View File

@@ -9,38 +9,36 @@ import org.openrndr.extra.meshgenerators.buildTriangleMesh
import org.openrndr.extra.meshgenerators.sphere import org.openrndr.extra.meshgenerators.sphere
import org.openrndr.math.Vector3 import org.openrndr.math.Vector3
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 800 height = 720
height = 800 multisample = WindowMultisample.SampleCount(8)
multisample = WindowMultisample.SampleCount(8) }
program {
val m = buildTriangleMesh {
color = ColorRGBa.PINK
sphere(32, 32, 1.0)
color = ColorRGBa.WHITE
translate(0.0, -2.0, 0.0)
box(4.0, 4.0, 4.0)
} }
program {
val m = buildTriangleMesh {
color = ColorRGBa.PINK
sphere(32, 32, 1.0)
color = ColorRGBa.WHITE extend(Orbital()) {
translate(0.0, -2.0, 0.0) this.eye = Vector3(0.0, 3.0, 7.0)
box(4.0, 4.0, 4.0) this.lookAt = Vector3(0.0, 2.0, 0.0)
}
} extend {
drawer.shadeStyle = shadeStyle {
extend(Orbital()) { fragmentTransform = """
this.eye = Vector3(0.0, 3.0, 7.0)
this.lookAt = Vector3(0.0, 2.0, 0.0)
}
extend {
drawer.shadeStyle = shadeStyle {
fragmentTransform = """
x_fill = va_color; x_fill = va_color;
x_fill.rgb *= v_viewNormal.z; x_fill.rgb *= v_viewNormal.z;
""".trimIndent() """.trimIndent()
}
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
} }
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
} }
} }
} }

View File

@@ -8,60 +8,58 @@ import org.openrndr.extra.meshgenerators.cylinder
import org.openrndr.extra.meshgenerators.hemisphere import org.openrndr.extra.meshgenerators.hemisphere
import org.openrndr.math.Vector3 import org.openrndr.math.Vector3
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 800 height = 720
height = 800 multisample = WindowMultisample.SampleCount(8)
multisample = WindowMultisample.SampleCount(8) }
program {
extend(Orbital()) {
this.eye = Vector3(0.0, 10.0, 20.0)
this.lookAt = Vector3(0.0, 5.0, 0.0)
} }
program { val m = buildTriangleMesh {
extend(Orbital()) { isolated {
this.eye = Vector3(0.0, 10.0, 20.0) translate(0.0, 12.0, 0.0)
this.lookAt = Vector3(0.0, 5.0, 0.0) hemisphere(32, 16, 5.0)
} }
val m = buildTriangleMesh {
isolated {
translate(0.0, 12.0, 0.0)
hemisphere(32, 16, 5.0)
}
isolated { isolated {
translate(0.0, 9.0, 0.0) translate(0.0, 9.0, 0.0)
rotate(Vector3.UNIT_X, 90.0) rotate(Vector3.UNIT_X, 90.0)
cylinder(32, 1, 5.0, 6.0, center = true) cylinder(32, 1, 5.0, 6.0, center = true)
} }
isolated { isolated {
translate(0.0, 6.0, 0.0) translate(0.0, 6.0, 0.0)
rotate(Vector3.UNIT_X, 180.0) rotate(Vector3.UNIT_X, 180.0)
hemisphere(32, 16, 5.0) hemisphere(32, 16, 5.0)
} }
isolated { isolated {
val legCount = 12 val legCount = 12
val baseRadius = 3.0 val baseRadius = 3.0
val legRadius = 0.05 val legRadius = 0.05
val legLength = 4.0 val legLength = 4.0
for (i in 0 until legCount) { for (i in 0 until legCount) {
isolated { isolated {
val dphi = 360.0 / legCount val dphi = 360.0 / legCount
rotate(Vector3.UNIT_Y, dphi * i) rotate(Vector3.UNIT_Y, dphi * i)
translate(baseRadius, 0.0, 0.0) translate(baseRadius, 0.0, 0.0)
rotate(Vector3.UNIT_Z, -15.0) rotate(Vector3.UNIT_Z, -15.0)
translate(0.0, legLength / 2.0, 0.0) translate(0.0, legLength / 2.0, 0.0)
rotate(Vector3.UNIT_X, 90.0) rotate(Vector3.UNIT_X, 90.0)
cylinder(32, 1, legRadius, legLength, center = true) cylinder(32, 1, legRadius, legLength, center = true)
}
} }
} }
} }
extend { }
drawer.shadeStyle = shadeStyle { extend {
fragmentTransform = """ drawer.shadeStyle = shadeStyle {
fragmentTransform = """
x_fill.rgb *= v_viewNormal.z; x_fill.rgb *= v_viewNormal.z;
""".trimIndent() """.trimIndent()
}
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
} }
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
} }
} }
} }

View File

@@ -6,78 +6,80 @@ import org.openrndr.extra.camera.Orbital
import org.openrndr.extra.meshgenerators.* import org.openrndr.extra.meshgenerators.*
import org.openrndr.math.Vector3 import org.openrndr.math.Vector3
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 800 height = 720
height = 800 multisample = WindowMultisample.SampleCount(8)
multisample = WindowMultisample.SampleCount(8) }
program {
extend(Orbital()) {
this.eye = Vector3(0.0, 10.0, 20.0)
this.lookAt = Vector3(0.0, 5.0, 0.0)
} }
program { val m = buildTriangleMesh {
extend(Orbital()) { isolated {
this.eye = Vector3(0.0, 10.0, 20.0) translate(0.0, 12.0, 0.0)
this.lookAt = Vector3(0.0, 5.0, 0.0) hemisphere(32, 16, 5.0)
} }
val m = buildTriangleMesh {
val ridges = 5
val midLength = 6.0
val ridgeLength = midLength / ridges
val ridgeRadius = 5.5
for (r in 0 until ridges) {
isolated { isolated {
translate(0.0, 12.0, 0.0) translate(
hemisphere(32, 16, 5.0) 0.0,
ridgeLength / 4.0 + r * ridgeLength + 6.0,
0.0
)
rotate(Vector3.UNIT_X, 270.0)
taperedCylinder(32, 1, 5.0, ridgeRadius, ridgeLength / 2.0, center = true)
} }
val ridges = 5 isolated {
val midLength = 6.0 translate(
val ridgeLength = midLength / ridges 0.0,
val ridgeRadius = 5.5 ridgeLength / 4.0 + ridgeLength / 2.0 + r * ridgeLength + 6.0,
0.0
for (r in 0 until ridges) { )
rotate(Vector3.UNIT_X, 270.0)
taperedCylinder(32, 1, ridgeRadius, 5.0, ridgeLength / 2.0, center = true)
}
}
isolated {
translate(0.0, 6.0, 0.0)
rotate(Vector3.UNIT_X, 180.0)
hemisphere(32, 16, 5.0)
}
isolated {
val legCount = 12
val baseRadius = 3.0
val legRadius = 0.05
val legLength = 4.0
for (i in 0 until legCount) {
isolated { isolated {
translate(0.0, val dphi = 360.0 / legCount
ridgeLength/4.0 + r * ridgeLength + 6.0, rotate(Vector3.UNIT_Y, dphi * i)
0.0) translate(baseRadius, 0.0, 0.0)
rotate(Vector3.UNIT_X, 270.0) rotate(Vector3.UNIT_Z, -15.0)
taperedCylinder(32, 1, 5.0, ridgeRadius, ridgeLength/ 2.0, center = true) translate(0.0, legLength / 2.0, 0.0)
} rotate(Vector3.UNIT_X, 90.0)
cylinder(32, 1, legRadius, legLength, center = true)
isolated {
translate(0.0,
ridgeLength/4.0 + ridgeLength/2.0 + r * ridgeLength + 6.0,
0.0)
rotate(Vector3.UNIT_X, 270.0)
taperedCylinder(32, 1, ridgeRadius, 5.0, ridgeLength/2.0, center = true)
}
}
isolated {
translate(0.0, 6.0, 0.0)
rotate(Vector3.UNIT_X, 180.0)
hemisphere(32, 16, 5.0)
}
isolated {
val legCount = 12
val baseRadius = 3.0
val legRadius = 0.05
val legLength = 4.0
for (i in 0 until legCount) {
isolated {
val dphi = 360.0 / legCount
rotate(Vector3.UNIT_Y, dphi * i)
translate(baseRadius, 0.0, 0.0)
rotate(Vector3.UNIT_Z, -15.0)
translate(0.0, legLength/2.0, 0.0)
rotate(Vector3.UNIT_X, 90.0)
cylinder(32, 1, legRadius, legLength, center = true)
}
} }
} }
} }
}
extend { extend {
drawer.shadeStyle = shadeStyle { drawer.shadeStyle = shadeStyle {
fragmentTransform = """ fragmentTransform = """
x_fill.rgb *= v_viewNormal.z; x_fill.rgb *= v_viewNormal.z;
""".trimIndent() """.trimIndent()
}
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
} }
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
} }
} }
} }

View File

@@ -7,98 +7,98 @@ import org.openrndr.extra.meshgenerators.*
import org.openrndr.math.Vector2 import org.openrndr.math.Vector2
import org.openrndr.math.Vector3 import org.openrndr.math.Vector3
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 800 height = 720
height = 800 multisample = WindowMultisample.SampleCount(8)
multisample = WindowMultisample.SampleCount(8) }
program {
extend(Orbital()) {
this.eye = Vector3(0.0, 15.0, 15.0)
} }
program {
extend(Orbital()) {
this.eye = Vector3(0.0, 15.0, 15.0)
}
val m = buildTriangleMesh { val m = buildTriangleMesh {
val sides = 12 val sides = 12
isolated { isolated {
translate(0.0, 12.0, 0.0) translate(0.0, 12.0, 0.0)
cap(sides, 5.0, listOf( cap(
Vector2(0.0, 1.0), sides, 5.0, listOf(
Vector2(0.5, 1.0), Vector2(0.0, 1.0),
Vector2(0.5, 0.5), Vector2(0.5, 1.0),
Vector2(0.9, 0.5), Vector2(0.5, 0.5),
Vector2(1.0, 0.0)) Vector2(0.9, 0.5),
Vector2(1.0, 0.0)
) )
} )
}
val ridges = 5 val ridges = 5
val midLength = 6.0 val midLength = 6.0
val ridgeLength = midLength / ridges val ridgeLength = midLength / ridges
val ridgeRadius = 5.5 val ridgeRadius = 5.5
for (r in 0 until ridges) { for (r in 0 until ridges) {
isolated { isolated {
translate( translate(
0.0, 0.0,
ridgeLength / 6.0 + r * ridgeLength + 6.0, ridgeLength / 6.0 + r * ridgeLength + 6.0,
0.0 0.0
) )
rotate(Vector3.UNIT_X, 270.0) rotate(Vector3.UNIT_X, 270.0)
taperedCylinder(sides, 1, 5.0, ridgeRadius, ridgeLength / 3.0, center = true) taperedCylinder(sides, 1, 5.0, ridgeRadius, ridgeLength / 3.0, center = true)
}
isolated {
translate(
0.0,
ridgeLength / 6.0 + ridgeLength / 3.0 + r * ridgeLength + 6.0,
0.0
)
rotate(Vector3.UNIT_X, 270.0)
taperedCylinder(sides, 1, ridgeRadius, ridgeRadius, ridgeLength / 3.0, center = true)
}
isolated {
translate(
0.0,
ridgeLength / 6.0 + 2 * ridgeLength / 3.0 + r * ridgeLength + 6.0,
0.0
)
rotate(Vector3.UNIT_X, 270.0)
taperedCylinder(sides, 1, ridgeRadius, 5.0, ridgeLength / 3.0, center = true)
}
} }
isolated { isolated {
translate(0.0, 6.0, 0.0) translate(
rotate(Vector3.UNIT_X, 180.0) 0.0,
cap(sides, 5.0, listOf(Vector2(0.0, 0.0), Vector2(1.0, 0.0))) ridgeLength / 6.0 + ridgeLength / 3.0 + r * ridgeLength + 6.0,
0.0
)
rotate(Vector3.UNIT_X, 270.0)
taperedCylinder(sides, 1, ridgeRadius, ridgeRadius, ridgeLength / 3.0, center = true)
} }
isolated { isolated {
val legCount = 12 translate(
val baseRadius = 4.5 0.0,
val legRadius = 0.05 ridgeLength / 6.0 + 2 * ridgeLength / 3.0 + r * ridgeLength + 6.0,
val legLength = 7.0 0.0
for (i in 0 until legCount) { )
isolated { rotate(Vector3.UNIT_X, 270.0)
val dphi = 360.0 / legCount taperedCylinder(sides, 1, ridgeRadius, 5.0, ridgeLength / 3.0, center = true)
rotate(Vector3.UNIT_Y, dphi * i) }
translate(baseRadius, 0.0, 0.0) }
translate(0.0, legLength / 2.0, 0.0) isolated {
rotate(Vector3.UNIT_X, 90.0) translate(0.0, 6.0, 0.0)
cylinder(sides, 1, legRadius, legLength, center = true) rotate(Vector3.UNIT_X, 180.0)
} cap(sides, 5.0, listOf(Vector2(0.0, 0.0), Vector2(1.0, 0.0)))
}
isolated {
val legCount = 12
val baseRadius = 4.5
val legRadius = 0.05
val legLength = 7.0
for (i in 0 until legCount) {
isolated {
val dphi = 360.0 / legCount
rotate(Vector3.UNIT_Y, dphi * i)
translate(baseRadius, 0.0, 0.0)
translate(0.0, legLength / 2.0, 0.0)
rotate(Vector3.UNIT_X, 90.0)
cylinder(sides, 1, legRadius, legLength, center = true)
} }
} }
} }
}
extend { extend {
drawer.shadeStyle = shadeStyle { drawer.shadeStyle = shadeStyle {
fragmentTransform = """ fragmentTransform = """
x_fill.rgb *= v_viewNormal.z; x_fill.rgb *= v_viewNormal.z;
""".trimIndent() """.trimIndent()
}
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
} }
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
} }
} }
} }

View File

@@ -11,38 +11,36 @@ import org.openrndr.extra.meshgenerators.twist
import org.openrndr.math.Vector3 import org.openrndr.math.Vector3
import org.openrndr.shape.Circle import org.openrndr.shape.Circle
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 800 height = 720
height = 800 multisample = WindowMultisample.SampleCount(8)
multisample = WindowMultisample.SampleCount(8) }
program {
extend(Orbital()) {
this.eye = Vector3(0.0, 30.0, 50.0)
} }
program { val m = buildTriangleMesh {
extend(Orbital()) { grid(5, 5, 5) { u, v, w ->
this.eye = Vector3(0.0, 30.0, 50.0) isolated {
} translate(u * 20.0, v * 20.0, w * 20.0)
val m = buildTriangleMesh { extrudeShape(Circle(0.0, 0.0, 50.0).shape, 4.0, scale = 0.1)
grid(5, 5, 5) { u, v, w ->
isolated {
translate(u * 20.0, v * 20.0, w * 20.0)
extrudeShape(Circle(0.0, 0.0, 50.0).shape, 4.0, scale = 0.1)
}
} }
twist(360.0 / 200.0, 0.0)
twist(360.0 / 200.0, 0.0, Vector3.UNIT_X)
twist(360.0 / 200.0, 0.0, Vector3.UNIT_Z)
} }
twist(360.0 / 200.0, 0.0)
twist(360.0 / 200.0, 0.0, Vector3.UNIT_X)
twist(360.0 / 200.0, 0.0, Vector3.UNIT_Z)
}
extend { extend {
drawer.shadeStyle = shadeStyle { drawer.shadeStyle = shadeStyle {
fragmentTransform = """ fragmentTransform = """
x_fill.rgb *= v_viewNormal.z; x_fill.rgb *= v_viewNormal.z;
""".trimIndent() """.trimIndent()
}
drawer.drawStyle.cullTestPass = CullTestPass.FRONT
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
} }
drawer.drawStyle.cullTestPass = CullTestPass.FRONT
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
} }
} }
} }

View File

@@ -13,50 +13,48 @@ import org.openrndr.math.Vector3
* Interactive orbital camera. * Interactive orbital camera.
* *
*/ */
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 800 height = 720
height = 800 multisample = WindowMultisample.SampleCount(8)
multisample = WindowMultisample.SampleCount(8) }
program {
extend(Orbital()) {
this.eye = Vector3(3.0, 3.0, 10.0)
this.fov = 60.0
} }
program { val m = buildTriangleMesh {
extend(Orbital()) { grid(5, 5) { u, v ->
this.eye = Vector3(3.0, 3.0, 10.0) isolated {
this.fov = 60.0 grid(3, 3, 3, GridCoordinates.UNIPOLAR) { x, y, z ->
} val pos0 = Vector3(u, v, 0.0) * 10.0
val m = buildTriangleMesh { val pos1 = Vector3(x, y, z) * 2.0
grid(5, 5) { u, v -> val pos2 = pos0 + pos1 + Vector3(
isolated { y * 0.12 + z * 0.3,
grid(3, 3, 3, GridCoordinates.UNIPOLAR) { x, y, z -> x * 0.14 + z * 0.15,
val pos0 = Vector3(u, v, 0.0) * 10.0 x * 0.16 + y * 0.17
val pos1 = Vector3(x, y, z) * 2.0 )
val pos2 = pos0 + pos1 + Vector3( // Drop some boxes
y * 0.12 + z * 0.3, if (simplex(0, pos1 * 0.5 + pos0 * 0.05) > 0) {
x * 0.14 + z * 0.15, translate(pos2)
x * 0.16 + y * 0.17 color = rgb(x, y, z)
) box(1.2, 1.2, 1.2)
// Drop some boxes
if(simplex(0, pos1 * 0.5 + pos0 * 0.05) > 0) {
translate(pos2)
color = rgb(x, y, z)
box(1.2, 1.2, 1.2)
}
} }
} }
} }
} }
}
extend { extend {
drawer.shadeStyle = shadeStyle { drawer.shadeStyle = shadeStyle {
fragmentTransform = """ fragmentTransform = """
x_fill = va_color; x_fill = va_color;
vec3 s = sin(v_worldPosition.xyz * 2.5); vec3 s = sin(v_worldPosition.xyz * 2.5);
x_fill.rgb += s * 0.1 - 0.1; x_fill.rgb += s * 0.1 - 0.1;
""".trimIndent() """.trimIndent()
}
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
} }
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
} }
} }
} }

View File

@@ -11,57 +11,55 @@ import org.openrndr.extra.shapes.splines.toPath3D
import org.openrndr.math.Vector3 import org.openrndr.math.Vector3
import org.openrndr.shape.Circle import org.openrndr.shape.Circle
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 800 height = 720
height = 800 multisample = WindowMultisample.SampleCount(8)
multisample = WindowMultisample.SampleCount(8) }
program {
val m = buildTriangleMesh {
color = ColorRGBa.PINK
val path = listOf(
Vector3(0.0, 0.0, 0.0),
Vector3(-2.0, 2.0, 2.0),
Vector3(2.0, -4.0, 4.0),
Vector3(0.0, 0.0, 8.0)
).catmullRom(0.5, closed = false).toPath3D()
translate(-1.0, 0.0, 0.0)
for (i in 0 until 3) {
extrudeContourSteps(
Circle(0.0, 0.0, 0.5).contour,
path,
160,
Vector3.UNIT_Y,
contourDistanceTolerance = 0.02,
pathDistanceTolerance = 0.001
)
translate(1.0, 0.0, 0.0)
}
} }
program {
val m = buildTriangleMesh {
color = ColorRGBa.PINK
val path = listOf( extend(Orbital()) {
Vector3(0.0, 0.0, 0.0), this.eye = Vector3(0.0, 3.0, 7.0)
Vector3(-2.0, 2.0, 2.0), this.lookAt = Vector3(0.0, 2.0, 0.0)
Vector3(2.0, -4.0, 4.0), }
Vector3(0.0, 0.0, 8.0)
).catmullRom(0.5, closed = false).toPath3D()
extend {
translate(-1.0, 0.0, 0.0) drawer.shadeStyle = shadeStyle {
fragmentTransform = """
for (i in 0 until 3) {
extrudeContourSteps(
Circle(0.0, 0.0, 0.5).contour,
path,
160,
Vector3.UNIT_Y,
contourDistanceTolerance = 0.02,
pathDistanceTolerance = 0.001
)
translate(1.0, 0.0, 0.0)
}
}
extend(Orbital()) {
this.eye = Vector3(0.0, 3.0, 7.0)
this.lookAt = Vector3(0.0, 2.0, 0.0)
}
extend {
drawer.shadeStyle = shadeStyle {
fragmentTransform = """
x_fill = va_color; x_fill = va_color;
x_fill.rgb *= v_viewNormal.z; x_fill.rgb *= v_viewNormal.z;
""".trimIndent() """.trimIndent()
}
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
} }
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
} }
} }
} }

View File

@@ -12,60 +12,56 @@ import org.openrndr.math.Vector3
import org.openrndr.shape.Circle import org.openrndr.shape.Circle
import org.openrndr.shape.Shape import org.openrndr.shape.Shape
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 800 height = 720
height = 800 multisample = WindowMultisample.SampleCount(8)
multisample = WindowMultisample.SampleCount(8) }
program {
val m = buildTriangleMesh {
color = ColorRGBa.PINK
val path = listOf(
Vector3(0.0, 0.0, 0.0),
Vector3(-2.0, 2.0, 2.0),
Vector3(2.0, -4.0, 4.0),
Vector3(0.0, 0.0, 8.0)
).catmullRom(0.5, closed = false).toPath3D()
translate(-5.0, 0.0, 0.0)
val ring = Shape(listOf(Circle(0.0, 0.0, 0.5).contour, Circle(0.0, 0.0, 0.25).contour.reversed))
for (i in 0 until 5) {
extrudeShapeSteps(
ring,
path,
160,
Vector3.UNIT_Y,
contourDistanceTolerance = 0.02,
pathDistanceTolerance = 0.001
)
translate(2.0, 0.0, 0.0)
}
} }
program {
val m = buildTriangleMesh {
color = ColorRGBa.PINK
val path = listOf( extend(Orbital()) {
Vector3(0.0, 0.0, 0.0), this.eye = Vector3(0.0, 3.0, 7.0)
Vector3(-2.0, 2.0, 2.0), this.lookAt = Vector3(0.0, 2.0, 0.0)
Vector3(2.0, -4.0, 4.0), }
Vector3(0.0, 0.0, 8.0)
).catmullRom(0.5, closed = false).toPath3D()
extend {
translate(-5.0, 0.0, 0.0) drawer.shadeStyle = shadeStyle {
fragmentTransform = """
val ring = Shape(listOf(Circle(0.0, 0.0, 0.5).contour, Circle(0.0, 0.0, 0.25).contour.reversed))
for (i in 0 until 5) {
extrudeShapeSteps(
ring,
path,
160,
Vector3.UNIT_Y,
contourDistanceTolerance = 0.02,
pathDistanceTolerance = 0.001
)
translate(2.0, 0.0, 0.0)
}
}
extend(Orbital()) {
this.eye = Vector3(0.0, 3.0, 7.0)
this.lookAt = Vector3(0.0, 2.0, 0.0)
}
extend {
drawer.shadeStyle = shadeStyle {
fragmentTransform = """
x_fill = va_color; x_fill = va_color;
x_fill.rgb *= v_viewNormal.z; x_fill.rgb *= v_viewNormal.z;
""".trimIndent() """.trimIndent()
}
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
} }
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
} }
} }
} }

View File

@@ -15,82 +15,76 @@ import org.openrndr.shape.Path3D
import kotlin.math.PI import kotlin.math.PI
import kotlin.math.exp import kotlin.math.exp
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 800 height = 720
height = 800 multisample = WindowMultisample.SampleCount(8)
multisample = WindowMultisample.SampleCount(8) }
program {
fun spiralPath(a: Double, k: Double, cycles: Double, steps: Int, direction: Double = 1.0): Path3D {
val points = (0 until steps).map {
val theta = ((PI * 2.0 * cycles) / steps) * it
val radius = a * exp(k * theta)
val c = Polar(theta.asDegrees, radius).cartesian
c.xy0
}
return Path3D.fromPoints(points, false)
} }
program {
fun spiralPath(a: Double, k: Double, cycles: Double, steps: Int, direction:Double = 1.0): Path3D {
val points = (0 until steps).map {
val theta = ((PI * 2.0 * cycles) / steps) * it val spiral = buildTriangleMesh {
val radius = a * exp(k * theta) for (i in -1..1 step 2) {
val p = spiralPath(0.2 * i, 0.25, 4.0, 400)
val c = Polar(theta.asDegrees, radius).cartesian extrudeContourAdaptive(
c.xy0 Circle(0.0, 0.0, 0.1).contour,
} p,
return Path3D.fromPoints(points, false) Vector3.UNIT_Z,
contourDistanceTolerance = 0.02,
pathDistanceTolerance = 0.001
)
} }
val spiral = buildTriangleMesh { isolated {
for (i in -1..1 step 2) { color = ColorRGBa.YELLOW
val p = spiralPath(0.2 * i, 0.25, 4.0, 400) rotate(Vector3.UNIT_X, 90.0)
extrudeContourAdaptive( //rotate(Vector3.UNIT_Y, 45.0)
Circle(0.0, 0.0, 0.1).contour, for (j in 0 until 1) {
p, for (i in -1..1 step 2) {
Vector3.UNIT_Z,
contourDistanceTolerance = 0.02,
pathDistanceTolerance = 0.001
)
}
isolated { val rotationDegrees = j * 180.0 / 1.0
color = ColorRGBa.YELLOW val rotation = rotationDegrees.asRadians
rotate(Vector3.UNIT_X, 90.0) val scale = exp(rotation * 0.25)
//rotate(Vector3.UNIT_Y, 45.0) val p = spiralPath(0.2 * i * scale, 0.25, 4.0, 400)
for (j in 0 until 1) {
for (i in -1..1 step 2) {
val rotationDegrees = j * 180.0 / 1.0 extrudeContourAdaptive(
val rotation = rotationDegrees.asRadians Circle(0.0, 0.0, 0.1).contour,
val scale = exp(rotation * 0.25) p,
Vector3.UNIT_Z,
val p = spiralPath(0.2 * i * scale, 0.25, 4.0, 400) contourDistanceTolerance = 0.02,
pathDistanceTolerance = 0.001
extrudeContourAdaptive( )
Circle(0.0, 0.0, 0.1).contour,
p,
Vector3.UNIT_Z,
contourDistanceTolerance = 0.02,
pathDistanceTolerance = 0.001
)
}
rotate(Vector3.UNIT_Y, 180.0 / 1.0)
} }
rotate(Vector3.UNIT_Y, 180.0 / 1.0)
} }
} }
}
extend(Orbital()) extend(Orbital())
extend { extend {
drawer.shadeStyle = shadeStyle { drawer.shadeStyle = shadeStyle {
fragmentTransform = """ fragmentTransform = """
x_fill = va_color; x_fill = va_color;
x_fill.rgb *= v_viewNormal.z; x_fill.rgb *= v_viewNormal.z;
""".trimIndent() """.trimIndent()
}
drawer.rotate(Vector3.UNIT_X, seconds*20.0)
drawer.vertexBuffer(spiral, DrawPrimitive.TRIANGLES)
} }
drawer.rotate(Vector3.UNIT_X, seconds * 20.0)
drawer.vertexBuffer(spiral, DrawPrimitive.TRIANGLES)
} }
} }
} }

View File

@@ -16,71 +16,69 @@ import org.openrndr.shape.Segment3D
* Extruded Bézier tubes grown on a morphing Bézier surface. * Extruded Bézier tubes grown on a morphing Bézier surface.
* *
*/ */
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 800 height = 720
height = 800 multisample = WindowMultisample.SampleCount(8)
multisample = WindowMultisample.SampleCount(8) }
program {
val crossSection = Circle(0.0, 0.0, 0.2).contour
extend(Orbital()) {
this.eye = Vector3(0.0, 3.0, 7.0)
this.lookAt = Vector3(0.0, 0.0, 0.0)
} }
program {
val crossSection = Circle(0.0, 0.0, 0.2).contour
extend(Orbital()) { extend {
this.eye = Vector3(0.0, 3.0, 7.0) drawer.shadeStyle = shadeStyle {
this.lookAt = Vector3(0.0, 0.0, 0.0) fragmentTransform = """
}
extend {
drawer.shadeStyle = shadeStyle {
fragmentTransform = """
x_fill = va_color; x_fill = va_color;
x_fill.rgb *= v_viewNormal.z; x_fill.rgb *= v_viewNormal.z;
""".trimIndent() """.trimIndent()
}
val m = buildTriangleMesh {
val beziers = List(4) { curveId ->
val n = List(12) {
Random.simplex(it * 7.387, curveId * 5.531 + seconds * 0.05) * 10.0
}
Segment3D(
Vector3(n[0], n[1], n[2]),
Vector3(n[3], n[4], n[5]),
Vector3(n[6], n[7], n[8]),
Vector3(n[9], n[10], n[11])
)
}
for (i in 0 until 20) {
val t = i / (20.0 - 1.0)
val path = Path3D(
listOf(
Segment3D(
beziers[0].position(t),
beziers[1].position(t),
beziers[2].position(t),
beziers[3].position(t)
)
), false
)
color = if(i % 2 == 0) ColorRGBa.PINK else ColorRGBa.WHITE.shade(0.1)
extrudeContourSteps(
crossSection,
path,
120,
Vector3.UNIT_Y,
contourDistanceTolerance = 0.05,
pathDistanceTolerance = 0.05
)
}
}
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
// Remember to free the memory! Otherwise, the computer will quickly run out of RAM.
m.destroy()
} }
val m = buildTriangleMesh {
val beziers = List(4) { curveId ->
val n = List(12) {
Random.simplex(it * 7.387, curveId * 5.531 + seconds * 0.05) * 10.0
}
Segment3D(
Vector3(n[0], n[1], n[2]),
Vector3(n[3], n[4], n[5]),
Vector3(n[6], n[7], n[8]),
Vector3(n[9], n[10], n[11])
)
}
for (i in 0 until 20) {
val t = i / (20.0 - 1.0)
val path = Path3D(
listOf(
Segment3D(
beziers[0].position(t),
beziers[1].position(t),
beziers[2].position(t),
beziers[3].position(t)
)
), false
)
color = if (i % 2 == 0) ColorRGBa.PINK else ColorRGBa.WHITE.shade(0.1)
extrudeContourSteps(
crossSection,
path,
120,
Vector3.UNIT_Y,
contourDistanceTolerance = 0.05,
pathDistanceTolerance = 0.05
)
}
}
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
// Remember to free the memory! Otherwise, the computer will quickly run out of RAM.
m.destroy()
} }
} }
} }

View File

@@ -18,72 +18,70 @@ import kotlin.math.cos
* Extruded Bézier tubes grown on a morphing Bézier surface. * Extruded Bézier tubes grown on a morphing Bézier surface.
* *
*/ */
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 800 height = 720
height = 800 multisample = WindowMultisample.SampleCount(8)
multisample = WindowMultisample.SampleCount(8) }
program {
val crossSection = Circle(0.0, 0.0, 0.2).contour
extend(Orbital()) {
this.eye = Vector3(0.0, 3.0, 7.0)
this.lookAt = Vector3(0.0, 0.0, 0.0)
} }
program {
val crossSection = Circle(0.0, 0.0, 0.2).contour
extend(Orbital()) { extend {
this.eye = Vector3(0.0, 3.0, 7.0) drawer.shadeStyle = shadeStyle {
this.lookAt = Vector3(0.0, 0.0, 0.0) fragmentTransform = """
}
extend {
drawer.shadeStyle = shadeStyle {
fragmentTransform = """
x_fill = va_color; x_fill = va_color;
x_fill.rgb *= v_viewNormal.z; x_fill.rgb *= v_viewNormal.z;
""".trimIndent() """.trimIndent()
}
val m = buildTriangleMesh {
val beziers = List(4) { curveId ->
val n = List(12) {
Random.simplex(it * 7.387, curveId * 5.531 + seconds * 0.05) * 10.0
}
Segment3D(
Vector3(n[0], n[1], n[2]),
Vector3(n[3], n[4], n[5]),
Vector3(n[6], n[7], n[8]),
Vector3(n[9], n[10], n[11])
)
}
for (i in 0 until 20) {
val t = i / (20.0 - 1.0)
val path = Path3D(
listOf(
Segment3D(
beziers[0].position(t),
beziers[1].position(t),
beziers[2].position(t),
beziers[3].position(t)
)
), false
)
color = if(i % 2 == 0) ColorRGBa.PINK else ColorRGBa.WHITE.shade(0.1)
extrudeContourStepsScaled(
crossSection,
path,
120,
Vector3.UNIT_Y,
contourDistanceTolerance = 0.05,
pathDistanceTolerance = 0.05,
scale = { tt: Double -> 0.5 - 0.5 * cos(tt * 2 * PI) }
)
}
}
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
// Remember to free the memory! Otherwise, the computer will quickly run out of RAM.
m.destroy()
} }
val m = buildTriangleMesh {
val beziers = List(4) { curveId ->
val n = List(12) {
Random.simplex(it * 7.387, curveId * 5.531 + seconds * 0.05) * 10.0
}
Segment3D(
Vector3(n[0], n[1], n[2]),
Vector3(n[3], n[4], n[5]),
Vector3(n[6], n[7], n[8]),
Vector3(n[9], n[10], n[11])
)
}
for (i in 0 until 20) {
val t = i / (20.0 - 1.0)
val path = Path3D(
listOf(
Segment3D(
beziers[0].position(t),
beziers[1].position(t),
beziers[2].position(t),
beziers[3].position(t)
)
), false
)
color = if (i % 2 == 0) ColorRGBa.PINK else ColorRGBa.WHITE.shade(0.1)
extrudeContourStepsScaled(
crossSection,
path,
120,
Vector3.UNIT_Y,
contourDistanceTolerance = 0.05,
pathDistanceTolerance = 0.05,
scale = { tt: Double -> 0.5 - 0.5 * cos(tt * 2 * PI) }
)
}
}
drawer.vertexBuffer(m, DrawPrimitive.TRIANGLES)
// Remember to free the memory! Otherwise, the computer will quickly run out of RAM.
m.destroy()
} }
} }
} }

View File

@@ -22,25 +22,24 @@ import kotlin.math.cos
* based on the t value along a Path3D. In other words, a tube in which the cross-section does not need * based on the t value along a Path3D. In other words, a tube in which the cross-section does not need
* to be constant, but can be scaled, rotated and displaced along its curvy axis. * to be constant, but can be scaled, rotated and displaced along its curvy axis.
*/ */
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 800 height = 720
height = 800 multisample = WindowMultisample.SampleCount(8)
multisample = WindowMultisample.SampleCount(8) }
program {
Random.seed = System.currentTimeMillis().toString()
val texture = loadImage("demo-data/images/peopleCity01.jpg").also {
it.wrapU = WrapMode.REPEAT
it.wrapV = WrapMode.REPEAT
it.filterMag = MagnifyingFilter.LINEAR
it.filterMin = MinifyingFilter.LINEAR
} }
program {
Random.seed = System.currentTimeMillis().toString()
val texture = loadImage("demo-data/images/peopleCity01.jpg").also { val shader = shadeStyle {
it.wrapU = WrapMode.REPEAT fragmentTransform = """
it.wrapV = WrapMode.REPEAT
it.filterMag = MagnifyingFilter.LINEAR
it.filterMin = MinifyingFilter.LINEAR
}
val shader = shadeStyle {
fragmentTransform = """
// A. Passed color // A. Passed color
x_fill = va_color; x_fill = va_color;
@@ -56,38 +55,37 @@ fun main() {
// Black fog (darken far away shapes) // Black fog (darken far away shapes)
x_fill.rgb += v_viewPosition.z * 0.05; x_fill.rgb += v_viewPosition.z * 0.05;
""".trimIndent() """.trimIndent()
parameter("img", texture) parameter("img", texture)
} }
extend(Orbital()) { extend(Orbital()) {
eye = Vector3(0.0, 3.0, 7.0) eye = Vector3(0.0, 3.0, 7.0)
lookAt = Vector3(0.0, 0.0, 0.0) lookAt = Vector3(0.0, 0.0, 0.0)
} }
extend { extend {
drawer.stroke = null drawer.stroke = null
val path = get3DPath(10.0, seconds * 0.05, 400) val path = get3DPath(10.0, seconds * 0.05, 400)
val tubes = makeTubes(path, seconds * 0.2) val tubes = makeTubes(path, seconds * 0.2)
shader.parameter("seconds", seconds * 0.1) shader.parameter("seconds", seconds * 0.1)
drawer.fill = ColorRGBa.WHITE drawer.fill = ColorRGBa.WHITE
drawer.shadeStyle = shader drawer.shadeStyle = shader
tubes.forEachIndexed { i, vb -> tubes.forEachIndexed { i, vb ->
shader.parameter("offset", i * 0.3 + 0.2) shader.parameter("offset", i * 0.3 + 0.2)
// Mirror the mesh 5 times // Mirror the mesh 5 times
repeat(5) { repeat(5) {
drawer.isolated { drawer.isolated {
rotate(Vector3.UNIT_Z, it * 72.0) rotate(Vector3.UNIT_Z, it * 72.0)
vertexBuffer(vb, DrawPrimitive.TRIANGLES) vertexBuffer(vb, DrawPrimitive.TRIANGLES)
}
} }
// Remember to free the memory! Otherwise, the computer will quickly run out of RAM.
vb.destroy()
} }
// Remember to free the memory! Otherwise, the computer will quickly run out of RAM.
vb.destroy()
} }
} }
} }
} }

View File

@@ -15,41 +15,39 @@ import java.io.File
* Demonstrate decal generator as an object slicer * Demonstrate decal generator as an object slicer
* @see <img src="https://raw.githubusercontent.com/openrndr/orx/media/orx-mesh-generators/images/decal-DemoDecal01Kt.png"> * @see <img src="https://raw.githubusercontent.com/openrndr/orx/media/orx-mesh-generators/images/decal-DemoDecal01Kt.png">
*/ */
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 720 height = 720
height = 720 }
program {
val obj = loadOBJMeshData(File("demo-data/obj-models/suzanne/Suzanne.obj")).toMeshData().triangulate()
val slices = 25
val sliceStep = 0.1
val sliceWidth = 0.14
val sliceVBs = (0 until slices).map {
val projector = buildTransform {
translate(0.0, 0.0, -1.0 + it * sliceStep)
}
val decal = obj.decal(projector, Vector3(4.0, 4.0, sliceWidth))
val vb = decal.toVertexBuffer()
vb
} }
program {
val obj = loadOBJMeshData(File("demo-data/obj-models/suzanne/Suzanne.obj")).toMeshData().triangulate()
val slices = 25 extend(Orbital()) {
val sliceStep = 0.1 eye = Vector3(0.0, 0.0, 2.0)
val sliceWidth = 0.14 }
extend {
val sliceVBs = (0 until slices).map { drawer.shadeStyle = shadeStyle {
val projector = buildTransform { fragmentTransform = """x_fill.rgb = v_viewNormal.rgb * 0.5 + 0.5; """
translate(0.0, 0.0, -1.0 + it * sliceStep)
}
val decal = obj.decal(projector, Vector3(4.0, 4.0, sliceWidth))
val vb = decal.toVertexBuffer()
vb
} }
extend(Orbital()) { drawer.translate(0.0, 0.0, slices * 0.5 * 0.5)
eye = Vector3(0.0, 0.0, 2.0) for (i in 0 until sliceVBs.size) {
} drawer.vertexBuffer(sliceVBs[i], DrawPrimitive.TRIANGLES)
extend { drawer.translate(0.0, 0.0, -0.5)
drawer.shadeStyle = shadeStyle {
fragmentTransform = """x_fill.rgb = v_viewNormal.rgb * 0.5 + 0.5; """
}
drawer.translate(0.0, 0.0, slices * 0.5 * 0.5)
for (i in 0 until sliceVBs.size) {
drawer.vertexBuffer(sliceVBs[i], DrawPrimitive.TRIANGLES)
drawer.translate(0.0, 0.0, -0.5)
}
} }
} }
} }

View File

@@ -17,69 +17,67 @@ import kotlin.math.PI
* Demonstrate decal generation and rendering * Demonstrate decal generation and rendering
* @see <img src="https://raw.githubusercontent.com/openrndr/orx/media/orx-mesh-generators/images/decal-DemoDecal02Kt.png"> * @see <img src="https://raw.githubusercontent.com/openrndr/orx/media/orx-mesh-generators/images/decal-DemoDecal02Kt.png">
*/ */
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 720 height = 720
height = 720 }
program {
/** base object */
val obj = loadOBJMeshData(File("demo-data/obj-models/suzanne/Suzanne.obj"))
.toMeshData() // convert from CompoundMeshData to MeshData
.triangulate() // convert to triangles, we need this for the decal generation steps
/** object [VertexBuffer] */
val objVB = obj.toVertexBuffer()
/** positions for the decal projectors */
val decalPositions = listOf(
Vector3(0.35, 0.245, 0.8),
Vector3(-0.35, 0.245, 0.8)
)
/** decal vertex buffers */
val decalVBs = decalPositions.map {
val projector = buildTransform {
translate(it)
}
val decal = obj.decal(projector, Vector3(2.0, 2.0, 0.5))
val vb = decal.toVertexBuffer()
vb
} }
program {
/** base object */
val obj = loadOBJMeshData(File("demo-data/obj-models/suzanne/Suzanne.obj"))
.toMeshData() // convert from CompoundMeshData to MeshData
.triangulate() // convert to triangles, we need this for the decal generation steps
/** object [VertexBuffer] */ extend(Orbital()) {
val objVB = obj.toVertexBuffer() eye = Vector3(0.0, 0.0, 2.0)
}
extend {
/** positions for the decal projectors */ /* draw the base mesh */
val decalPositions = listOf( drawer.isolated {
Vector3(0.35, 0.245, 0.8), drawer.shadeStyle = shadeStyle {
Vector3(-0.35, 0.245, 0.8) fragmentTransform = """x_fill.rgb = vec3(v_viewNormal * 0.5 + 0.5); """
)
/** decal vertex buffers */
val decalVBs = decalPositions.map {
val projector = buildTransform {
translate(it)
} }
val decal = obj.decal(projector, Vector3(2.0, 2.0, 0.5)) drawer.vertexBuffer(objVB, DrawPrimitive.TRIANGLES)
val vb = decal.toVertexBuffer()
vb
} }
extend(Orbital()) { /* draw the decals */
eye = Vector3(0.0, 0.0, 2.0) drawer.isolated {
} for ((index, decal) in decalVBs.withIndex()) {
extend { /* offset the projection transform to avoid z-fighting */
/* draw the base mesh */ drawer.projection = buildTransform {
drawer.isolated { translate(0.0, 0.0, -1e-4)
} * drawer.projection
/* draw effects on the decal geometry */
drawer.shadeStyle = shadeStyle { drawer.shadeStyle = shadeStyle {
fragmentTransform = """x_fill.rgb = vec3(v_viewNormal * 0.5 + 0.5); """ fragmentTransform = """
}
drawer.vertexBuffer(objVB, DrawPrimitive.TRIANGLES)
}
/* draw the decals */
drawer.isolated {
for ((index, decal) in decalVBs.withIndex()) {
/* offset the projection transform to avoid z-fighting */
drawer.projection = buildTransform {
translate(0.0, 0.0, -1e-4)
} * drawer.projection
/* draw effects on the decal geometry */
drawer.shadeStyle = shadeStyle {
fragmentTransform = """
float d = length(va_texCoord0.xy - vec2(0.5)); float d = length(va_texCoord0.xy - vec2(0.5));
float sd = smoothstep(-0.01, 0.01, cos(p_time + d * 3.1415 * 2.0 * 10.0)); float sd = smoothstep(-0.01, 0.01, cos(p_time + d * 3.1415 * 2.0 * 10.0));
float l = max(0.0, va_normal.z); float l = max(0.0, va_normal.z);
x_fill = vec4(0.0, 0.0, 0.0, l * sd * 0.5); """ x_fill = vec4(0.0, 0.0, 0.0, l * sd * 0.5); """
parameter("time", seconds * PI * 2 + index * PI) parameter("time", seconds * PI * 2 + index * PI)
}
drawer.vertexBuffer(decal, DrawPrimitive.TRIANGLES)
} }
drawer.vertexBuffer(decal, DrawPrimitive.TRIANGLES)
} }
} }
} }

View File

@@ -11,6 +11,10 @@ import org.openrndr.math.Vector3
import java.io.File import java.io.File
fun main() = application { fun main() = application {
configure {
width = 720
height = 720
}
program { program {
val obj = loadOBJMeshData(File("demo-data/obj-models/suzanne/Suzanne.obj")).toMeshData().triangulate() val obj = loadOBJMeshData(File("demo-data/obj-models/suzanne/Suzanne.obj")).toMeshData().triangulate()
val tangentObj = obj.estimateTangents() val tangentObj = obj.estimateTangents()

View File

@@ -25,7 +25,7 @@ Optionally, a static `backdrop` may be setup by providing custom code.
- Example 1. Customising the backdrop with an image - Example 1. Customising the backdrop with an image
```kotlin ```kotlin
extend(NoClear()) { extend(NoClear()) {
val img = loadImage("data\\backdrop.png") val img = loadImage("data/backdrop.png")
backdrop = { backdrop = {
drawer.image(img, 0.0, 0.0, width * 1.0, height * 1.0) drawer.image(img, 0.0, 0.0, width * 1.0, height * 1.0)
} }

View File

@@ -2,60 +2,72 @@ import org.openrndr.application
import org.openrndr.color.ColorHSLa import org.openrndr.color.ColorHSLa
import org.openrndr.color.rgb import org.openrndr.color.rgb
import org.openrndr.draw.isolated import org.openrndr.draw.isolated
import org.openrndr.extensions.SingleScreenshot
import org.openrndr.extra.noclear.NoClear import org.openrndr.extra.noclear.NoClear
import org.openrndr.math.Polar import org.openrndr.math.Polar
import org.openrndr.shape.contour import org.openrndr.shape.contour
import kotlin.math.sin import kotlin.math.sin
fun main() { fun main() = application {
application { configure {
program { width = 720
var time = 0.0 height = 540
}
program {
var time = 0.0
// ------------------------------------------------------------ // ------------------------------------------------------------
// By default OPENRNDR clears the canvas on each animation // By default OPENRNDR clears the canvas on each animation
// frame. NoClear disables that behavior, letting you // frame. NoClear disables that behavior, letting you
// draw on top of what you drew previously. // draw on top of what you drew previously.
// That's the default in some other frameworks. // That's the default in some other frameworks.
// ------------------------------------------------------------ // ------------------------------------------------------------
extend(NoClear()) { extend(NoClear()) {
// backdrop is optional and it sets the initial state // backdrop is optional, and it sets the initial state
// of the canvas. It can be a generative pattern, an image // of the canvas. It can be code generated or an image
// loaded from disk... In this case we start with dark gray. // loaded from disk. In this case we start with dark gray.
backdrop = { drawer.clear(rgb(0.15)) } backdrop = { drawer.clear(rgb(0.15)) }
}
if (System.getProperty("takeScreenshot") == "true") {
extensions.filterIsInstance<SingleScreenshot>().forEach {
it.delayFrames = 60
} }
}
extend {
// Draw something. For this demo *what* you draw is not so
// important, only the fact that it stays on the canvas
// until you draw something else on top of it.
extend { drawer.isolated {
// Draw something. For this demo *what* you draw is not so // center the origin
// important, only the fact that it stays on the canvas translate(bounds.center)
// until you draw something else on top of it.
drawer.isolated { for (i in 0..5) {
// center the origin time += 0.01
translate(bounds.center)
for(i in 0..5) { // Make a list of 4 points rotating around the center at
time += 0.01 // different speeds
val points = List(4) {
// Make a list of 4 points rotating around the center at Polar(
// different speeds time * (15.0 + it * 5),
val points = List(4) { 250.0 * sin(time + it * 65)
Polar(time * (15.0 + it * 5), ).cartesian
250.0 * sin(time + it * 65)).cartesian
}
// Use those 4 points to create a bezier curve
val c = contour {
moveTo(points.first())
curveTo(points[1], points[2], points.last())
}
// Draw the curve with increasing hue and lightness modulation
fill = null
stroke = ColorHSLa(time * 10.0, 0.8,
0.5 + 0.2 * sin(time * 3), 0.5).toRGBa()
contour(c)
} }
// Use those 4 points to create a Bézier curve
val c = contour {
moveTo(points.first())
curveTo(points[1], points[2], points.last())
}
// Draw the curve with increasing hue and lightness modulation
fill = null
stroke = ColorHSLa(
time * 10.0, 0.8,
0.5 + 0.2 * sin(time * 3), 0.5
).toRGBa()
contour(c)
} }
} }
} }

View File

@@ -1,15 +1,32 @@
import org.openrndr.application import org.openrndr.application
import org.openrndr.draw.loadFont
import org.openrndr.extra.objloader.loadOBJMeshData import org.openrndr.extra.objloader.loadOBJMeshData
import org.openrndr.extra.objloader.toObj import org.openrndr.extra.objloader.toObj
import org.openrndr.math.Vector2
import java.io.File import java.io.File
fun main() { fun main() = application {
application { configure {
program { width = 720
val path = "demo-data/obj-models" height = 720
val cm = loadOBJMeshData(File("$path/suzanne/Suzanne.obj")) }
program {
val path = "demo-data/obj-models"
val cm = loadOBJMeshData(File("$path/suzanne/Suzanne.obj"))
println(cm.toObj()) // Convert mesh data to Wavefront OBJ String representation
val obj = cm.toObj()
println(obj)
val font = loadFont("demo-data/fonts/IBMPlexMono-Regular.ttf", 24.0)
extend {
// Draw part of the OBJ data as text
drawer.fontMap = font
drawer.texts(obj.split("\n").take(50), List(50) {
Vector2(10.0, 20.0 + it * 20.0)
})
} }
} }
} }

View File

@@ -7,6 +7,10 @@ import org.openrndr.extra.objloader.loadOBJasVertexBuffer
import org.openrndr.math.Vector3 import org.openrndr.math.Vector3
fun main() = application { fun main() = application {
configure {
width = 720
height = 540
}
program { program {
val mesh = loadOBJasVertexBuffer("demo-data/obj-models/suzanne/Suzanne.obj") val mesh = loadOBJasVertexBuffer("demo-data/obj-models/suzanne/Suzanne.obj")

View File

@@ -5,6 +5,7 @@ import org.openrndr.extra.objloader.saveOBJ
fun main() = application { fun main() = application {
configure { configure {
width = 720
height = 100 height = 100
} }
program { program {

View File

@@ -6,6 +6,7 @@ import org.openrndr.extra.objloader.saveOBJ
fun main() = application { fun main() = application {
configure { configure {
width = 720
height = 100 height = 100
} }
program { program {

View File

@@ -16,48 +16,46 @@ import org.openrndr.shape.Path3D
import java.io.File import java.io.File
import kotlin.math.cos import kotlin.math.cos
fun main() { fun main() = application {
application { configure {
configure { width = 720
width = 720 height = 720
height = 720 multisample = WindowMultisample.SampleCount(4)
multisample = WindowMultisample.SampleCount(4) }
program {
val vb = loadOBJasVertexBuffer("orx-obj-loader/test-data/non-planar.obj")
val md = readObjMeshData(File("orx-obj-loader/test-data/non-planar.obj").readLines())
val paths = md.wireframe().map {
Path3D.fromPoints(it, true)
} }
program {
val vb = loadOBJasVertexBuffer("orx-obj-loader/test-data/non-planar.obj")
val md = readObjMeshData(File("orx-obj-loader/test-data/non-planar.obj").readLines())
val paths = md.wireframe().map { extend(Orbital())
Path3D.fromPoints(it, true) extend {
} drawer.rotate(Vector3.Companion.UNIT_Y, seconds * 45.0 + 45.0, TransformTarget.MODEL)
drawer.translate(0.0, 0.0, 9.0, TransformTarget.VIEW)
extend(Orbital()) drawer.shadeStyle = shadeStyle {
extend { fragmentTransform = """
drawer.rotate(Vector3.Companion.UNIT_Y, seconds * 45.0 + 45.0, TransformTarget.MODEL)
drawer.translate(0.0, 0.0, 9.0, TransformTarget.VIEW)
drawer.shadeStyle = shadeStyle {
fragmentTransform = """
x_fill.rgb = normalize(v_viewNormal) * 0.5 + vec3(0.5); x_fill.rgb = normalize(v_viewNormal) * 0.5 + vec3(0.5);
""".trimIndent() """.trimIndent()
} }
drawer.vertexBuffer(vb, DrawPrimitive.TRIANGLES) drawer.vertexBuffer(vb, DrawPrimitive.TRIANGLES)
drawer.stroke = ColorRGBa.WHITE drawer.stroke = ColorRGBa.WHITE
drawer.strokeWeight = 1.0 drawer.strokeWeight = 1.0
drawer.shadeStyle = shadeStyle { drawer.shadeStyle = shadeStyle {
vertexTransform = """ vertexTransform = """
x_projectionMatrix[3][2] -= 0.001; x_projectionMatrix[3][2] -= 0.001;
""".trimIndent() """.trimIndent()
}
drawer.strokeWeight = 1.0
drawer.paths(paths.mapIndexed { index, it ->
it.sub(
0.0, cos(seconds * 0.5 + index * 0.5) * 0.5 + 0.5
)
})
} }
drawer.strokeWeight = 1.0
drawer.paths(paths.mapIndexed { index, it ->
it.sub(
0.0, cos(seconds * 0.5 + index * 0.5) * 0.5 + 0.5
)
})
} }
} }
} }