Skip to content

Commit

Permalink
[orx-noise] Add hash functions
Browse files Browse the repository at this point in the history
  • Loading branch information
edwinRNDR committed Oct 20, 2024
1 parent 6e1e161 commit fba1e5b
Show file tree
Hide file tree
Showing 23 changed files with 473 additions and 63 deletions.
17 changes: 11 additions & 6 deletions orx-composition/src/commonMain/kotlin/Composition.kt
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,16 @@ class ShapeNode(var shape: Shape) : CompositionNode() {
}
}


/**
* apply transforms of all ancestor nodes and return a new detached shape node with identity transform and transformed Shape
* @param composition use viewport transform
*/
fun flatten(): ShapeNode {
return ShapeNode(shape.transform(transform(this))).also {
fun flatten(composition: Composition? = null): ShapeNode {

val viewport = composition?.calculateViewportTransform() ?: Matrix44.IDENTITY

return ShapeNode(shape.transform(viewport * transform(this))).also {
it.id = id
it.parent = parent
it.style = effectiveStyle
Expand Down Expand Up @@ -293,10 +298,10 @@ data class CompositionDimensions(val x: Length, val y: Length, val width: Length
// but otherwise equality checks will never succeed
override fun equals(other: Any?): Boolean {
return other is CompositionDimensions
&& x.value == other.x.value
&& y.value == other.y.value
&& width.value == other.width.value
&& height.value == other.height.value
&& x.value == other.x.value
&& y.value == other.y.value
&& width.value == other.width.value
&& height.value == other.height.value
}

override fun hashCode(): Int {
Expand Down
6 changes: 3 additions & 3 deletions orx-envelopes/src/jvmDemo/kotlin/DemoADSRTracker02.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import org.openrndr.application
import org.openrndr.draw.loadFont
import org.openrndr.extra.envelopes.ADSRTracker
import org.openrndr.extra.noise.uniform
import org.openrndr.extra.noise.shapes.uniform
import org.openrndr.shape.Rectangle

fun main() {
Expand All @@ -15,13 +15,13 @@ fun main() {

keyboard.keyDown.listen {
if (it.name == "t") {
val center = drawer.bounds.uniform(distanceToEdge = 30.0)
val center = drawer.bounds.offsetEdges(-30.0).uniform()
tracker.triggerOn(0) { time, value, position ->
drawer.circle(center, value * 100.0)
}
}
if (it.name == "r") {
val center = drawer.bounds.uniform(distanceToEdge = 30.0)
val center = drawer.bounds.offsetEdges(-30.0).uniform()
tracker.triggerOn(1) { time, value, position ->
val r = Rectangle.fromCenter(center, width = value * 100.0, height = value * 100.0)
drawer.rectangle(r)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package typed

import org.openrndr.extra.expressions.typed.compileFunction1OrNull
import org.openrndr.extra.noise.uniform
import org.openrndr.extra.noise.shapes.uniform
import org.openrndr.math.Vector2
import kotlin.test.Test
import kotlin.test.assertEquals
Expand Down
2 changes: 1 addition & 1 deletion orx-hash-grid/src/jvmDemo/kotlin/DemoFilter01.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import org.openrndr.application
import org.openrndr.extra.hashgrid.filter
import org.openrndr.extra.noise.uniform
import org.openrndr.extra.noise.shapes.uniform
import kotlin.random.Random

fun main() {
Expand Down
2 changes: 1 addition & 1 deletion orx-hash-grid/src/jvmDemo/kotlin/DemoHashGrid01.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.extra.hashgrid.HashGrid
import org.openrndr.extra.noise.uniform
import org.openrndr.extra.noise.shapes.uniform
import kotlin.random.Random

fun main() {
Expand Down
72 changes: 72 additions & 0 deletions orx-mesh-generators/src/commonMain/kotlin/mesh/Box.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package org.openrndr.extra.mesh.generators

import org.openrndr.extra.mesh.*
import org.openrndr.math.Vector2
import org.openrndr.math.Vector3

class MeshBuilder {
val vertexData = MutableVertexData()
val polygons = mutableListOf<IndexedPolygon>()
val mesh = MutableMeshData(vertexData, polygons)
}

fun box(): MeshData {

val positions = listOf(
Vector3(-0.5, -0.5, -0.5),
Vector3(0.5, -0.5, -0.5),
Vector3(-0.5, 0.5, -0.5),
Vector3(0.5, 0.5, -0.5),

Vector3(-0.5, -0.5, 0.5),
Vector3(0.5, -0.5, 0.5),
Vector3(-0.5, 0.5, 0.5),
Vector3(0.5, 0.5, 0.5),
)

val textureCoords = listOf(
Vector2(0.0, 0.0),
Vector2(1.0, 0.0),
Vector2(0.0, 1.0),
Vector2(1.0, 1.0),
)

val normals = listOf(
Vector3(-1.0, 0.0, 0.0),
Vector3(1.0, 0.0, 0.0),
Vector3(0.0, -1.0, 0.0),
Vector3(0.0, 1.0, 0.0),
Vector3(0.0, 0.0, -1.0),
Vector3(0.0, 0.0, 1.0)
)

val polygons = listOf(
// -x
IndexedPolygon(
positions = listOf(0, 2, 4, 6),
textureCoords = listOf(0, 1, 3, 2),
colors = emptyList(),
normals = listOf(0, 0, 0, 0),
tangents = listOf(5, 5, 5, 5),
bitangents = listOf(3, 3, 3, 3)
),
// +x
IndexedPolygon(
positions = listOf(1, 3, 5, 7),
textureCoords = listOf(0, 1, 3, 2),
colors = emptyList(),
normals = listOf(1, 1, 1, 1),
tangents = listOf(4, 4, 4, 4),
bitangents = listOf(3, 3, 3, 3)
)
)
return MeshData(
VertexData(
positions = positions,
textureCoords = textureCoords,
normals = normals,
tangents = normals,
bitangents = normals
), polygons
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import java.io.File

/**
* Demonstrate decal generator as an object slicer
* @see <img src="https://raw.githubusercontent.com/openrndr/orx/media/orx-mesh-generators/images/decal-DemoDecal01Kt.png">
*/
fun main() {
application {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import kotlin.math.PI

/**
* Demonstrate decal generation and rendering
* @see <img src="https://raw.githubusercontent.com/openrndr/orx/media/orx-mesh-generators/images/decal-DemoDecal02Kt.png">
*/
fun main() {
application {
Expand Down
39 changes: 39 additions & 0 deletions orx-mesh-generators/src/jvmDemo/kotlin/tangents/DemoTangents01.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package tangents

import org.openrndr.application
import org.openrndr.draw.DrawPrimitive
import org.openrndr.draw.shadeStyle
import org.openrndr.extra.camera.Orbital
import org.openrndr.extra.mesh.toVertexBuffer
import org.openrndr.extra.meshgenerators.tangents.estimateTangents
import org.openrndr.extra.objloader.loadOBJMeshData
import org.openrndr.math.Vector3
import java.io.File

fun main() = application {
program {
val obj = loadOBJMeshData(File("demo-data/obj-models/suzanne/Suzanne.obj")).toMeshData().triangulate()
val tangentObj = obj.estimateTangents()

val objVB = tangentObj.toVertexBuffer()

extend(Orbital()) {
eye = Vector3(0.0, 0.0, 2.0)
}
extend {
drawer.shadeStyle = shadeStyle {
fragmentTransform = """
vec3 viewTangent = (u_viewNormalMatrix * u_modelNormalMatrix * vec4(va_tangent, 0.0)).xyz;
vec3 viewBitangent = (u_viewNormalMatrix * u_modelNormalMatrix * vec4(va_bitangent, 0.0)).xyz;
float c = cos(100.0*dot(v_worldPosition, va_normal)) * 0.5 + 0.5;
//x_fill.rgb = normalize(viewTangent)*0.5+0.5;
x_fill.rgb = vec3(c);
""".trimIndent()

}

drawer.vertexBuffer(objVB, DrawPrimitive.TRIANGLES)
}
}
}
1 change: 1 addition & 0 deletions orx-mesh-noise/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ kotlin {
api(libs.openrndr.math)
api(libs.openrndr.shape)
api(project(":orx-mesh"))
implementation(project(":orx-noise"))
}
}

Expand Down
56 changes: 56 additions & 0 deletions orx-mesh-noise/src/commonMain/kotlin/MeshNoise.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package org.openrndr.extra.mesh.noise
import org.openrndr.extra.mesh.IIndexedPolygon
import org.openrndr.extra.mesh.IMeshData
import org.openrndr.extra.mesh.IVertexData
import org.openrndr.extra.noise.fhash1D
import org.openrndr.extra.noise.uhash11
import org.openrndr.extra.noise.uhash1D
import org.openrndr.math.Vector3
import kotlin.math.sqrt
import kotlin.random.Random
Expand All @@ -20,6 +23,23 @@ fun uniformBarycentric(random: Random = Random.Default): Vector3 {
return Vector3(b0, b1, 1.0 - b0 - b1)
}

/**
* Generate a uniformly distributed barycentric coordinate
* @param random a random number generator
*/
fun hashBarycentric(seed: Int, x: Int): Vector3 {
val u = fhash1D(seed, x)
val v = fhash1D(seed, u.toRawBits().toInt() - x)



val su0 = sqrt(u)
val b0 = 1.0 - su0
val b1 = v * su0
return Vector3(b0, b1, 1.0 - b0 - b1)
}


/**
* Generate a uniformly distributed point that lies inside this [IIndexedPolygon]
* @param vertexData vertex data used to resolve positions
Expand All @@ -33,6 +53,19 @@ fun IIndexedPolygon.uniform(vertexData: IVertexData, random: Random = Random.Def
return x[0] * b.x + x[1] * b.y + x[2] * b.z
}

/**
* Generate a uniformly distributed point that lies inside this [IIndexedPolygon]
* @param vertexData vertex data used to resolve positions
* @param random a random number generator
*/
fun IIndexedPolygon.hash(vertexData: IVertexData, seed:Int, x: Int): Vector3 {
require(positions.size == 3) { "polygon must be a triangle"}

val s = vertexData.positions.slice(positions)
val b = hashBarycentric(seed, x)
return s[0] * b.x + s[1] * b.y + s[2] * b.z
}

internal fun IIndexedPolygon.area(vertexData: IVertexData): Double {
require(positions.size == 3) { "polygon must be a triangle"}
val x = vertexData.positions.slice(positions)
Expand Down Expand Up @@ -62,4 +95,27 @@ fun IMeshData.uniform(count: Int, random: Random = Random.Default): List<Vector3
}
}
return result
}

/**
* Generate points on the surface described by the mesh data
*/
fun IMeshData.hash(count: Int, seed:Int, x: Int): List<Vector3> {
val triangulated = triangulate()
val result = mutableListOf<Vector3>()
val totalArea = triangulated.polygons.sumOf { it.area(vertexData) }
val randoms = (0 until count).map {
Pair(x + it, fhash1D(seed, x + it) * totalArea)
}.sortedBy { it.second }

var idx = 0
var sum = 0.0
for (t in triangulated.polygons) {
sum += t.area(vertexData)
while (idx <= randoms.lastIndex && sum > randoms[idx].second) {
result.add(t.hash(vertexData, seed xor 0x7f7f7f, randoms[idx].first))
idx++
}
}
return result
}
48 changes: 48 additions & 0 deletions orx-mesh-noise/src/jvmDemo/kotlin/DemoMeshNoise02.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import org.openrndr.application
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.mesh.noise.hash
import org.openrndr.extra.objloader.loadOBJMeshData
import org.openrndr.extra.mesh.noise.uniform
import org.openrndr.extra.meshgenerators.sphereMesh
import org.openrndr.math.Vector3
import java.io.File
import kotlin.math.cos
import kotlin.random.Random

/**
* Demonstrate uniform point on mesh generation using hash functions
*/
fun main() {
application {
configure {
width = 720
height = 720
}
program {
val mesh = loadOBJMeshData(File("demo-data/obj-models/suzanne/Suzanne.obj")).toMeshData()

val sphere = sphereMesh(radius = 0.01)
extend(Orbital()) {
eye = Vector3(0.0, 0.0, 2.0)
}
extend {

val points = mesh.hash((1000 + (cos(seconds)*0.5+0.5)*9000).toInt(), 808, (seconds*10000).toInt())


drawer.shadeStyle = shadeStyle {
fragmentTransform = "x_fill = vec4(v_viewNormal*0.5+0.5, 1.0);"
}
for (point in points) {
drawer.isolated {
drawer.translate(point)
drawer.vertexBuffer(sphere, DrawPrimitive.TRIANGLES)
}
}
}
}
}
}
Loading

0 comments on commit fba1e5b

Please sign in to comment.