package org.openrndr.extra.meshgenerators import org.openrndr.math.Matrix44 import org.openrndr.math.Vector2 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.Shape import org.openrndr.shape.Triangle /** * Writes two triangles to [writer] representing * the quad formed by four vertices. * * @param v00 vertex (0, 0) * @param v01 vertex (0, 1) * @param v10 vertex (1, 0) * @param v11 vertex (1, 1) * @param faceNormal the face normal * @param writer the vertex writer function */ fun quadToTris( v00: Vector3, v01: Vector3, v10: Vector3, v11: Vector3, faceNormal: Vector3, writer: VertexWriter ) { writeTri(v11, v01, v00, Vector2.ZERO, Vector2.ZERO, Vector2.ZERO, faceNormal, writer) writeTri(v00, v10, v11, Vector2.ZERO, Vector2.ZERO, Vector2.ZERO, faceNormal, writer) } /** * Writes a triangle to [writer]. * * @param v0 vertex 0 * @param v1 vertex 1 * @param v2 vertex 2 * @param tc0 texture coordinate 0 * @param tc1 texture coordinate 1 * @param tc2 texture coordinate 2 * @param faceNormal the face normal * @param writer the vertex writer function */ fun writeTri( v0: Vector3, v1: Vector3, v2: Vector3, tc0: Vector2, tc1: Vector2, tc2: Vector2, faceNormal: Vector3, writer: VertexWriter ) { writer(v0, faceNormal, tc0) writer(v1, faceNormal, tc1) writer(v2, faceNormal, tc2) } /** * Writes a list of triangles transformed by the [frame] * transformation matrix into [writer]. * * @param triangulation the list of triangles to write * @param frame a transformation matrix to apply to each triangle * @param flipNormals generates inside-out geometry if true * @param writer the vertex writer function */ fun triangulationWithFrame( triangulation: List, frame: Matrix44, flipNormals: Boolean = true, writer: VertexWriter ) { val normalFrame = normalMatrix(frame) val normalScale = if (!flipNormals) -1.0 else 1.0 val normal = ((normalFrame * Vector4(0.0, 0.0, normalScale, 0.0)).xyz) for (triangle in triangulation) { val t = if (!flipNormals) triangle else Triangle(triangle.x3, triangle.x2, triangle.x1) writer((frame * t.x1.xy01).xyz, normal, Vector2.ZERO) writer((frame * t.x2.xy01).xyz, normal, Vector2.ZERO) writer((frame * t.x3.xy01).xyz, normal, Vector2.ZERO) } } /** * Adds caps to an extruded shape * * @param linearShape the cross-section of the mesh * @param path the 3D path * @param startCap adds a start cap if set to true * @param endCap adds an end cap if set to true * @param frames a list of matrices holding the transformation matrices along * the path * @param writer the vertex writer function */ fun extrudeCaps( linearShape: Shape, path: Path3D, startCap: Boolean, endCap: Boolean, frames: List, writer: VertexWriter ) { if ((startCap || endCap) && !path.closed) { val capTriangles = linearShape.triangulation if (startCap) { triangulationWithFrame(capTriangles, frames.first(), false, writer) } if (endCap) { triangulationWithFrame(capTriangles, frames.last(), true, writer) } } }