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