Add shape extrusion mesh generator for precalced tessellation

This commit is contained in:
Edwin Jakobs
2020-01-14 00:17:40 +01:00
parent 4d60875989
commit aefdcb85d5
2 changed files with 35 additions and 12 deletions

View File

@@ -127,6 +127,10 @@ fun GeneratorBuffer.revolve(sides:Int, length:Double, enveloppe: List<Vector2>)
generateRevolve(sides, length, enveloppe, this::write) generateRevolve(sides, length, enveloppe, this::write)
} }
fun GeneratorBuffer.extrudeShape( baseTriangles:List<Vector2>, contours:List<List<Vector2>>, length: Double, scale: Double = 1.0, distanceTolerance: Double = 0.5) {
extrudeShape(baseTriangles, contours, -length / 2.0, length / 2.0, scale, scale, true, true, distanceTolerance, false, this::write)
}
fun GeneratorBuffer.extrudeShape(shape: Shape, length: Double, scale: Double = 1.0, distanceTolerance: Double = 0.5) { fun GeneratorBuffer.extrudeShape(shape: Shape, length: Double, scale: Double = 1.0, distanceTolerance: Double = 0.5) {
extrudeShape(shape, -length / 2.0, length / 2.0, scale, scale, true, true, distanceTolerance, false, this::write) extrudeShape(shape, -length / 2.0, length / 2.0, scale, scale, true, true, distanceTolerance, false, this::write)
} }

View File

@@ -43,12 +43,11 @@ fun extrudeShape(shape: Shape, front: Double, back: Double, distanceTolerance: D
extrudeShape(shape, front, back, distanceTolerance = distanceTolerance, flipNormals = false, writer = writer) extrudeShape(shape, front, back, distanceTolerance = distanceTolerance, flipNormals = false, writer = writer)
} }
/** /**
* extrudes a [shape] by triangulating it and creating side- and cap geometry * extrudes a [shape] from its triangulations
* @sample sample
*/ */
fun extrudeShape(shape: Shape, fun extrudeShape(baseTriangles: List<Vector2>, contours: List<List<Vector2>>, front: Double,
front: Double,
back: Double, back: Double,
frontScale: Double = 1.0, frontScale: Double = 1.0,
backScale: Double = 1.0, backScale: Double = 1.0,
@@ -56,7 +55,7 @@ fun extrudeShape(shape: Shape,
backCap: Boolean = true, backCap: Boolean = true,
distanceTolerance: Double = 0.5, distanceTolerance: Double = 0.5,
flipNormals: Boolean = false, writer: VertexWriter) { flipNormals: Boolean = false, writer: VertexWriter) {
val baseTriangles = triangulate(shape, distanceTolerance)
val depth = back - front val depth = back - front
val flip = if (flipNormals) 1.0 else -1.0 val flip = if (flipNormals) 1.0 else -1.0
@@ -66,18 +65,18 @@ fun extrudeShape(shape: Shape,
if (frontCap) { if (frontCap) {
baseTriangles.reversed().forEach { baseTriangles.reversed().forEach {
writer((it*frontScale).vector3(z = front), normal, Vector2.ZERO) writer((it * frontScale).vector3(z = front), normal, Vector2.ZERO)
} }
} }
if (backCap) { if (backCap) {
baseTriangles.forEach { baseTriangles.forEach {
writer((it*backScale).vector3(z = back), negativeNormal, Vector2.ZERO) writer((it * backScale).vector3(z = back), negativeNormal, Vector2.ZERO)
} }
} }
} }
shape.contours.forEach { contours.forEach {
val points = it.adaptivePositions(distanceTolerance) val points = it
val normals = (0 until points.size).map { val normals = (0 until points.size).map {
(points[mod(it + 1, points.size)] - points[mod(it - 1, points.size)]).safeNormalized * -flip (points[mod(it + 1, points.size)] - points[mod(it - 1, points.size)]).safeNormalized * -flip
@@ -89,7 +88,7 @@ fun extrudeShape(shape: Shape,
val frontRight = (right.first * frontScale).xy0 + base val frontRight = (right.first * frontScale).xy0 + base
val frontLeft = (left.first * frontScale).xy0 + base val frontLeft = (left.first * frontScale).xy0 + base
val backRight =(right.first * backScale).xy0 + base + forward val backRight = (right.first * backScale).xy0 + base + forward
val backLeft = (left.first * backScale).xy0 + base + forward val backLeft = (left.first * backScale).xy0 + base + forward
val lnormal = (frontLeft - backLeft).normalized.cross(left.second.xy0) val lnormal = (frontLeft - backLeft).normalized.cross(left.second.xy0)
@@ -106,6 +105,26 @@ fun extrudeShape(shape: Shape,
} }
} }
/**
* extrudes a [shape] by triangulating it and creating side- and cap geometry
*/
fun extrudeShape(shape: Shape,
front: Double,
back: Double,
frontScale: Double = 1.0,
backScale: Double = 1.0,
frontCap: Boolean = true,
backCap: Boolean = true,
distanceTolerance: Double = 0.5,
flipNormals: Boolean = false, writer: VertexWriter) {
val baseTriangles = triangulate(shape, distanceTolerance)
val points = shape.contours.map { it.adaptivePositions(distanceTolerance) }
extrudeShape(baseTriangles, points, front, back, frontScale, backScale, frontCap, backCap, distanceTolerance,
flipNormals, writer)
}
fun extrudeShapes(shapes: List<Shape>, fun extrudeShapes(shapes: List<Shape>,
front: Double, front: Double,
back: Double, back: Double,
@@ -114,9 +133,9 @@ fun extrudeShapes(shapes: List<Shape>,
frontCap: Boolean = true, frontCap: Boolean = true,
backCap: Boolean = true, backCap: Boolean = true,
distanceTolerance: Double = 0.5, distanceTolerance: Double = 0.5,
flipNormals: Boolean = false, writer: VertexWriter ) { flipNormals: Boolean = false, writer: VertexWriter) {
shapes.forEach { shapes.forEach {
extrudeShape(it, front, back, frontScale, backScale, frontCap , backCap , distanceTolerance, flipNormals, writer) extrudeShape(it, front, back, frontScale, backScale, frontCap, backCap, distanceTolerance, flipNormals, writer)
} }
} }