commonMain.Segment.kt Maven / Gradle / Ivy
The newest version!
package org.openrndr.extra.meshgenerators
import org.openrndr.math.Matrix44
import org.openrndr.math.Vector2
import org.openrndr.math.Vector3
/**
* Writes quads to [writer] creating a surface that connects
* [linearContour0] with [linearContour1].
* The positions and orientations of the two contours
* are defined by the [frame0] and [frame1] matrices.
*
* @param linearContour0 the first cross-section
* @param linearContour1 the second cross-section
* @param frame0 a transformation matrix with the pose of [linearContour0]
* @param frame1 a transformation matrix with the pose of [linearContour1]
* @param writer the vertex writer function
*/
fun contourSegment(
linearContour0: List,
linearContour1: List,
frame0: Matrix44,
frame1: Matrix44,
writer: VertexWriter
) {
for (i in linearContour0.indices) {
val v0a = linearContour0[i]
val v1a = linearContour0[(i + 1).mod(linearContour0.size)]
val v0b = linearContour1[i]
val v1b = linearContour1[(i + 1).mod(linearContour1.size)]
val v00a = (frame0 * v0a.xy01).xyz
val v01a = (frame0 * v1a.xy01).xyz
val v10b = (frame1 * v0b.xy01).xyz
val v11b = (frame1 * v1b.xy01).xyz
val faceNormal = ((v10b - v00a).normalized cross (v01a - v00a).normalized).normalized
quadToTris(v00a, v01a, v10b, v11b, faceNormal, writer)
}
}
/**
* Contour segment
*
* @param linearContour0
* @param linearContour1
* @param frame0
* @param frame1
* @param v0
* @param v1
* @param writer
*/
fun contourSegment(
linearContour0: List,
linearContour1: List,
frame0: Matrix44,
frame1: Matrix44,
v0: Double,
v1: Double,
writer: VertexWriter
) {
var i0 = 0
var i1 = 0
do {
val flipNormal = false
val vCurr0 = (frame0 * linearContour0[i0 % linearContour0.size].xy01).xyz
val vCurr1 = (frame1 * linearContour1[i1 % linearContour1.size].xy01).xyz
val vNext0 = (frame0 * linearContour0[(i0 + 1) % linearContour0.size].xy01).xyz
val vNext1 = (frame1 * linearContour1[(i1 + 1) % linearContour1.size].xy01).xyz
val tCurr0 = i0.toDouble() / linearContour0.size
val tCurr1 = i1.toDouble() / linearContour1.size
val tNext0 = (i0 + 1.0) / linearContour0.size
val tNext1 = (i1 + 1.0) / linearContour1.size
val uvCurr0 = Vector2(tCurr0, v0)
val uvCurr1 = Vector2(tCurr1, v1)
val vNext: Vector3
val uvNext: Vector2
if (tNext0 < tNext1 || (tNext0 == tNext1 && tCurr0 < tCurr1)) {
++i0
vNext = vNext0
uvNext = Vector2(i0.toDouble() / linearContour0.size, v0)
} else {
++i1
vNext = vNext1
uvNext = Vector2(i1.toDouble() / linearContour1.size, v1)
}
val faceNormal = if (flipNormal)
(vNext - vCurr1).cross(vCurr0 - vCurr1)
else
(vNext - vCurr0).cross(vCurr1 - vCurr0)
writeTri(
vCurr0, vNext, vCurr1,
uvCurr0, uvNext, uvCurr1,
faceNormal.normalized,
writer
)
} while (i0 < linearContour0.size || i1 < linearContour1.size)
}