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