Added box, plane and sphere mesh generators
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
.idea/
|
||||
.gradle/
|
||||
out/
|
||||
target/
|
||||
|
||||
61
orx-mesh-generators/src/main/kotlin/Box.kt
Normal file
61
orx-mesh-generators/src/main/kotlin/Box.kt
Normal file
@@ -0,0 +1,61 @@
|
||||
package org.openrndr.extras.meshgenerators
|
||||
|
||||
import org.openrndr.draw.VertexBuffer
|
||||
import org.openrndr.math.Vector3
|
||||
|
||||
fun boxMesh(width: Double = 1.0, height: Double = 1.0, depth: Double,
|
||||
widthSegments: Int = 1, heightSegments: Int = 1, depthSegments: Int = 1,
|
||||
invert: Boolean = false): VertexBuffer {
|
||||
val vb = meshVertexBuffer(widthSegments * heightSegments * 6 * 2 +
|
||||
widthSegments * depthSegments * 6 * 2 +
|
||||
heightSegments * depthSegments * 6 * 2)
|
||||
vb.put {
|
||||
generateBox(width, height, depth,
|
||||
widthSegments, heightSegments, depthSegments,
|
||||
invert, bufferWriter(this))
|
||||
}
|
||||
return vb
|
||||
}
|
||||
|
||||
fun generateBox(width: Double = 1.0, height: Double = 1.0, depth: Double = 1.0,
|
||||
widthSegments: Int = 1, heightSegments: Int = 1, depthSegments: Int = 1,
|
||||
invert: Boolean = false,
|
||||
writer: VertexWriter) {
|
||||
|
||||
val sign = if (invert) -1.0 else 1.0
|
||||
// +x -- ZY
|
||||
generatePlane(Vector3(width / 2.0 * sign, 0.0, 0.0),
|
||||
Vector3.UNIT_Z, Vector3.UNIT_Y, Vector3.UNIT_X,
|
||||
depth, height,
|
||||
depthSegments, heightSegments, writer)
|
||||
|
||||
// -x -- ZY
|
||||
generatePlane(Vector3(-width / 2.0 * sign, 0.0, 0.0),
|
||||
Vector3.UNIT_Z, Vector3.UNIT_Y, -Vector3.UNIT_X,
|
||||
depth, height,
|
||||
depthSegments, heightSegments, writer)
|
||||
|
||||
// +y -- XZ
|
||||
generatePlane(Vector3(0.0, height / 2.0 * sign, 0.0),
|
||||
Vector3.UNIT_X, Vector3.UNIT_Z, Vector3.UNIT_Y,
|
||||
width, depth,
|
||||
widthSegments, depthSegments, writer)
|
||||
|
||||
// -y -- XZ
|
||||
generatePlane(Vector3(0.0, -height / 2.0 * sign, 0.0),
|
||||
Vector3.UNIT_X, Vector3.UNIT_Z, -Vector3.UNIT_Y,
|
||||
width, depth,
|
||||
widthSegments, depthSegments, writer)
|
||||
|
||||
// +z -- XY
|
||||
generatePlane(Vector3(0.0, 0.0, depth / 2.0 * sign),
|
||||
Vector3.UNIT_X, Vector3.UNIT_Y, Vector3.UNIT_Z,
|
||||
width, height,
|
||||
widthSegments, heightSegments, writer)
|
||||
|
||||
// -z -- XY
|
||||
generatePlane(Vector3(0.0, 0.0, -depth / 2.0 * sign),
|
||||
Vector3.UNIT_X, Vector3.UNIT_Y, -Vector3.UNIT_Z,
|
||||
width, height,
|
||||
widthSegments, heightSegments, writer)
|
||||
}
|
||||
72
orx-mesh-generators/src/main/kotlin/Plane.kt
Normal file
72
orx-mesh-generators/src/main/kotlin/Plane.kt
Normal file
@@ -0,0 +1,72 @@
|
||||
package org.openrndr.extras.meshgenerators
|
||||
|
||||
import org.openrndr.draw.VertexBuffer
|
||||
import org.openrndr.math.Vector2
|
||||
import org.openrndr.math.Vector3
|
||||
|
||||
fun planeMesh(center: Vector3,
|
||||
right: Vector3,
|
||||
forward: Vector3,
|
||||
up: Vector3 = forward.cross(right).normalized,
|
||||
width: Double = 1.0, height: Double = 1.0,
|
||||
widthSegments: Int = 1, heightSegments: Int = 2): VertexBuffer {
|
||||
|
||||
val vertexCount = (widthSegments * heightSegments) * 6
|
||||
val vb = meshVertexBuffer(vertexCount)
|
||||
vb.put {
|
||||
generatePlane(center, forward, right, up,
|
||||
width, height, widthSegments, heightSegments, bufferWriter(this))
|
||||
}
|
||||
return vb
|
||||
}
|
||||
|
||||
/**
|
||||
* generates a finite plane with its center at (0,0,0) and spanning the xz-plane
|
||||
*/
|
||||
fun groundPlaneMesh(width: Double = 1.0,
|
||||
height: Double = 1.0,
|
||||
widthSegments: Int = 1,
|
||||
heightSegments: Int): VertexBuffer {
|
||||
return planeMesh(Vector3.ZERO, Vector3.UNIT_X, Vector3.UNIT_Z, Vector3.UNIT_Y,
|
||||
width, height, widthSegments, heightSegments)
|
||||
}
|
||||
|
||||
fun generatePlane(center: Vector3,
|
||||
right: Vector3,
|
||||
forward: Vector3,
|
||||
up: Vector3 = forward.cross(right).normalized,
|
||||
|
||||
width: Double = 1.0, height: Double = 1.0,
|
||||
widthSegments: Int = 1, heightSegments: Int = 2,
|
||||
writer: VertexWriter) {
|
||||
|
||||
val forwardStep = forward.normalized * (height / heightSegments)
|
||||
val rightStep = right.normalized * (width / widthSegments)
|
||||
|
||||
val corner = center - forward.normalized * (height*0.5) - right.normalized * (width * 0.5)
|
||||
|
||||
val step = Vector2(1.0 / width, 1.0 / height)
|
||||
|
||||
for (v in 0 until heightSegments) {
|
||||
for (u in 0 until widthSegments) {
|
||||
|
||||
val uv00 = Vector2(u + 0.0, v + 0.0) * step
|
||||
val uv01 = Vector2(u + 0.0, v + 0.1) * step
|
||||
val uv10 = Vector2(u + 1.0, v + 0.0) * step
|
||||
val uv11 = Vector2(u + 1.0, v + 0.1) * step
|
||||
|
||||
val c00 = corner + forwardStep * v.toDouble() + rightStep * u.toDouble()
|
||||
val c01 = corner + forwardStep * (v + 1).toDouble() + rightStep * u.toDouble()
|
||||
val c10 = corner + forwardStep * v.toDouble() + rightStep * (u + 1).toDouble()
|
||||
val c11 = corner + forwardStep * (v + 1).toDouble() + rightStep * (u + 1).toDouble()
|
||||
|
||||
writer(c00, up, uv00)
|
||||
writer(c10, up, uv10)
|
||||
writer(c11, up, uv11)
|
||||
|
||||
writer(c11, up, uv11)
|
||||
writer(c01, up, uv01)
|
||||
writer(c00, up, uv00)
|
||||
}
|
||||
}
|
||||
}
|
||||
50
orx-mesh-generators/src/main/kotlin/Sphere.kt
Normal file
50
orx-mesh-generators/src/main/kotlin/Sphere.kt
Normal file
@@ -0,0 +1,50 @@
|
||||
package org.openrndr.extras.meshgenerators
|
||||
|
||||
import org.openrndr.draw.VertexBuffer
|
||||
import org.openrndr.math.Spherical
|
||||
import org.openrndr.math.Vector2
|
||||
|
||||
fun sphereMesh(sides:Int, segments:Int, radius: Double): VertexBuffer {
|
||||
val vertexCount = 2 * sides * 3 + Math.max(0, (segments-2)) * sides * 6
|
||||
val vb = meshVertexBuffer(vertexCount)
|
||||
vb.put {
|
||||
generateSphere(sides, segments, radius, bufferWriter(this))
|
||||
}
|
||||
return vb
|
||||
}
|
||||
|
||||
fun generateSphere(sides: Int, segments: Int, radius: Double = 1.0, writer: VertexWriter) {
|
||||
for (t in 0 until segments) {
|
||||
for (s in 0 until sides) {
|
||||
val st00 = Spherical(radius, s*Math.PI*2.0/sides, t*Math.PI/segments)
|
||||
val st01 = Spherical(radius, s*Math.PI*2.0/sides, (t+1)*Math.PI/segments)
|
||||
val st10 = Spherical(radius, (s+1)*Math.PI*2.0/sides, t*Math.PI/segments)
|
||||
val st11 = Spherical(radius, (s+1)*Math.PI*2.0/sides, (t+1)*Math.PI/segments)
|
||||
|
||||
val thetaMax = Math.PI
|
||||
val phiMax = Math.PI*2.0
|
||||
|
||||
when (t) {
|
||||
0 -> {
|
||||
writer(st00.cartesian, st00.cartesian.normalized, Vector2(st00.phi/phiMax, st00.theta/thetaMax))
|
||||
writer(st01.cartesian, st01.cartesian.normalized, Vector2(st01.phi/phiMax, st01.theta/thetaMax))
|
||||
writer(st11.cartesian, st11.cartesian.normalized, Vector2(st11.phi/phiMax, st11.theta/thetaMax))
|
||||
}
|
||||
segments-1 -> {
|
||||
writer(st00.cartesian, st00.cartesian.normalized, Vector2(st00.phi/phiMax, st00.theta/thetaMax))
|
||||
writer(st10.cartesian, st10.cartesian.normalized, Vector2(st10.phi/phiMax, st10.theta/thetaMax))
|
||||
writer(st11.cartesian, st11.cartesian.normalized, Vector2(st11.phi/phiMax, st11.theta/thetaMax))
|
||||
}
|
||||
else -> {
|
||||
writer(st00.cartesian, st00.cartesian.normalized, Vector2(st00.phi/phiMax, st00.theta/thetaMax))
|
||||
writer(st10.cartesian, st10.cartesian.normalized, Vector2(st10.phi/phiMax, st10.theta/thetaMax))
|
||||
writer(st11.cartesian, st11.cartesian.normalized, Vector2(st11.phi/phiMax, st11.theta/thetaMax))
|
||||
|
||||
writer(st11.cartesian, st11.cartesian.normalized, Vector2(st11.phi/phiMax, st11.theta/thetaMax))
|
||||
writer(st01.cartesian, st01.cartesian.normalized, Vector2(st01.phi/phiMax, st01.theta/thetaMax))
|
||||
writer(st00.cartesian, st00.cartesian.normalized, Vector2(st00.phi/phiMax, st00.theta/thetaMax))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user