1 module gfx.genmesh.poly; 2 3 import std.typecons : Flag, Yes, No; 4 5 6 struct GenVertex(Flag!"normals" normals) { 7 float[3] p; 8 static if (normals == Yes.normals) { 9 float[3] n; 10 } 11 } 12 13 14 /// a generic face type 15 struct GenFace(size_t N, VT) { 16 enum size_t length = N; 17 VT[N] vertices; 18 19 VT opIndex(size_t n) const { 20 assert(n < length); 21 return vertices[n]; 22 } 23 } 24 25 /// a triangular face type, with a vertex type parameter 26 /// T can be an index or actual vertex 27 alias Triangle(VT) = GenFace!(3, VT); 28 29 auto triangle(VT)(in VT v1, in VT v2, in VT v3) { 30 return Triangle!VT([v1, v2, v3]); 31 } 32 33 /// a quad face type, with a vertex type parameter 34 /// T can be an index or actual vertex 35 alias Quad(VT) = GenFace!(4, VT); 36 37 auto quad(VT)(in VT v1, in VT v2, in VT v3, in VT v4) { 38 return Quad!VT([v1, v2, v3, v4]); 39 } 40 41 42 /// a runtime flexible face 43 struct FlexFace(VT) { 44 private Quad!VT q; 45 VT[] vertices; 46 47 this(in VT v1, in VT v2, in VT v3) { 48 q = quad(v1, v2, v3, VT.init); 49 vertices = q.vertices[0 .. 3]; 50 } 51 52 this(in VT v1, in VT v2, in VT v3, in VT v4) { 53 q = quad(v1, v2, v3, v4); 54 vertices = q.vertices[0 .. 4]; 55 } 56 57 @property size_t length() const { 58 return vertices.length; 59 } 60 61 VT opIndex(size_t n) const { 62 return vertices[n]; 63 } 64 } 65 66 auto flexFace(Args...)(Args args) if (Args.length == 3 || Args.length == 4) { 67 return FlexFace!(Args[0]) (args); 68 } 69 70 71 enum isFlexFace(FT) = FaceTplt!FT.isFlexFace; 72 enum isGenFace(FT) = FaceTplt!FT.isGenFace; 73 enum isFace(FT) = isFlexFace!FT || isGenFace!FT; 74 75 template VertexType(FT) if (isFace!FT) { 76 alias VertexType = FaceTplt!FT.VertexType; 77 } 78 template faceDim(FT) if (isGenFace!FT) { 79 enum faceDim = FaceTplt!FT.faceDim; 80 } 81 82 83 private template FaceTplt(FT) { 84 static if (is(FT == FlexFace!VT, VT)) { 85 enum isFlexFace = true; 86 alias VertexType = VT; 87 } 88 else { 89 enum isFlexFace = false; 90 } 91 92 static if (is(FT == GenFace!(N, VT), size_t N, VT)) { 93 enum isGenFace = true; 94 enum faceDim = N; 95 alias VertexType = VT; 96 } 97 else { 98 enum isGenFace = false; 99 } 100 } 101