source: trunk/orbital/mesh.h @ 1245

Last change on this file since 1245 was 1245, checked in by sam, 8 years ago

orbital: start implementing the mesh builder features found in the original.

  • Property svn:keywords set to Id
File size: 8.3 KB
Line 
1//
2// Orbital
3//
4// Copyright: (c) 2012 Various People
5//
6
7#if !defined __MESH_H__
8#define __MESH_H__
9
10class Mesh
11{
12public:
13    Mesh()
14      : m_color(0), m_color2(0),
15        m_vert_cursor(0), m_quadidx_cursor(0), m_triidx_cursor(0)
16    {}
17
18    void Flush()
19    {
20        m_vert_cursor = m_vert.Count();
21        m_quadidx_cursor = m_quadidx.Count();
22        m_triidx_cursor = m_triidx.Count();
23    }
24
25    void SetCurColor(vec4 const &color) { m_color = color; }
26    void SetCurColor2(vec4 const &color) { m_color2 = color; }
27
28    void AppendQuadVert(vec3 const &coord)
29    {
30        m_vert.Append(coord, vec3(0.0f, 1.0f, 0.0f), m_color);
31    }
32
33    void AppendDuplicateQuadVert(int i)
34    {
35        m_vert.Append(m_vert[i].m1, vec3(0.0f, 1.0f, 0.0f), m_vert[i].m3);
36    }
37
38    void AppendQuad(int i1, int i2, int i3, int i4, int base)
39    {
40        m_quadidx += base + i1;
41        m_quadidx += base + i2;
42        m_quadidx += base + i3;
43        m_quadidx += base + i4;
44    }
45
46    void AppendQuadDuplicateVerts(int i1, int i2, int i3, int i4, int base)
47    {
48        m_quadidx += m_vert.Count(); AppendDuplicateQuadVert(base + i1);
49        m_quadidx += m_vert.Count(); AppendDuplicateQuadVert(base + i2);
50        m_quadidx += m_vert.Count(); AppendDuplicateQuadVert(base + i3);
51        m_quadidx += m_vert.Count(); AppendDuplicateQuadVert(base + i4);
52    }
53
54    void AppendTriangle(int i1, int i2, int i3, int base)
55    {
56        m_quadidx += base + i1;
57        m_quadidx += base + i2;
58        m_quadidx += base + i3;
59    }
60
61    void AppendTriangleDuplicateVerts(int i1, int i2, int i3, int base)
62    {
63        m_quadidx += m_vert.Count(); AppendDuplicateQuadVert(base + i1);
64        m_quadidx += m_vert.Count(); AppendDuplicateQuadVert(base + i2);
65        m_quadidx += m_vert.Count(); AppendDuplicateQuadVert(base + i3);
66    }
67
68    void ComputeQuadNormals(int start, int vcount)
69    {
70        for (int i = 0; i < vcount; i += 4)
71        {
72            vec3 v0 = m_vert[m_quadidx[start + i + 2]].m1
73                    - m_vert[m_quadidx[start + i + 0]].m1;
74            vec3 v1 = m_vert[m_quadidx[start + i + 1]].m1
75                    - m_vert[m_quadidx[start + i + 0]].m1;
76            vec3 n = normalize(cross(v1, v0));
77
78            for (int j = 0; j < 4; j++)
79                m_vert[m_quadidx[start + i + j]].m2 = n;
80        }
81    }
82
83    void ComputeTriNormals(int start, int vcount)
84    {
85        for (int i = 0; i < vcount; i += 3)
86        {
87            vec3 v0 = m_vert[m_quadidx[start + i + 2]].m1
88                    - m_vert[m_quadidx[start + i + 0]].m1;
89            vec3 v1 = m_vert[m_quadidx[start + i + 1]].m1
90                    - m_vert[m_quadidx[start + i + 0]].m1;
91            vec3 n = normalize(cross(v1, v0));
92
93            for (int j = 0; j < 3; j++)
94                m_vert[m_quadidx[start + i + j]].m2 = n;
95        }
96    }
97
98    void SetVertColor(vec4 const &color)
99    {
100        for (int i = m_vert_cursor; i < m_vert.Count(); i++)
101            m_vert[i].m3 = color;
102    }
103
104    void SetCurVertNormal(vec3 const &normal)
105    {
106        m_vert[m_vert.Count() - 1].m2 = normal;
107    }
108
109    void SetCurVertColor(vec4 const &color)
110    {
111        m_vert[m_vert.Count() - 1].m3 = color;
112    }
113
114    void Translate(vec3 const &v)
115    {
116        for (int i = m_vert_cursor; i < m_vert.Count(); i++)
117            m_vert[i].m1 += v;
118    }
119
120    void RotateZ(float t)
121    {
122        /* FIXME: use mat3 instead of mat4 when it's working */
123        mat4 m = mat4::rotate(t, 0, 0, 1);
124        for (int i = m_vert_cursor; i < m_vert.Count(); i++)
125            m_vert[i].m1 = (m * vec4(m_vert[i].m1, 1.0)).xyz;
126    }
127
128    void RotateY(float t)
129    {
130        mat4 m = mat4::rotate(t, 0, 1, 0);
131        for (int i = m_vert_cursor; i < m_vert.Count(); i++)
132            m_vert[i].m1 = (m * vec4(m_vert[i].m1, 1.0)).xyz;
133    }
134
135    void RotateX(float t)
136    {
137        mat4 m = mat4::rotate(t, 1, 0, 0);
138        for (int i = m_vert_cursor; i < m_vert.Count(); i++)
139            m_vert[i].m1 = (m * vec4(m_vert[i].m1, 1.0)).xyz;
140    }
141
142    void TaperX(float y, float z, float xoff)
143    {
144        for (int i = m_vert_cursor; i < m_vert.Count(); i++)
145        {
146            m_vert[i].m1.y *= 1.0f + (y * m_vert[i].m1.x + xoff);
147            m_vert[i].m1.z *= 1.0f + (z * m_vert[i].m1.x + xoff);
148        }
149    }
150
151    void TaperY(float x, float z, float yoff)
152    {
153        for (int i = m_vert_cursor; i < m_vert.Count(); i++)
154        {
155            m_vert[i].m1.x *= 1.0f + (x * m_vert[i].m1.y + yoff);
156            m_vert[i].m1.z *= 1.0f + (z * m_vert[i].m1.y + yoff);
157        }
158    }
159
160    void TaperZ(float x, float y, float zoff)
161    {
162        for (int i = m_vert_cursor; i < m_vert.Count(); i++)
163        {
164            m_vert[i].m1.x *= 1.0f + (x * m_vert[i].m1.z + zoff);
165            m_vert[i].m1.y *= 1.0f + (y * m_vert[i].m1.z + zoff);
166        }
167    }
168
169    void Scale(vec3 const &s)
170    {
171        for (int i = m_vert_cursor; i < m_vert.Count(); i++)
172        {
173            m_vert[i].m1 *= s;
174            m_vert[i].m2 *= s;
175        }
176
177        // BH : TODO : not sure about this one
178        // Sam: not too sure either!
179        if (s.x * s.y * s.z < 0)
180        {
181            for (int i = m_quadidx_cursor; i < m_quadidx.Count(); i += 2)
182            {
183                uint16_t tmp = m_quadidx[i + 0];
184                m_quadidx[i + 0] = m_quadidx[i + 1];
185                m_quadidx[i + 1] = tmp;
186            }
187
188            for (int i = m_triidx_cursor; i < m_triidx.Count(); i += 3)
189            {
190                uint16_t tmp = m_triidx[i + 0];
191                m_triidx[i + 0] = m_triidx[i + 1];
192                m_triidx[i + 1] = tmp;
193            }
194        }
195    }
196
197    void MirrorX() { Duplicate(); Scale(vec3(-1, 1, 1)); }
198    void MirrorY() { Duplicate(); Scale(vec3(1, -1, 1)); }
199    void MirrorZ() { Duplicate(); Scale(vec3(1, 1, -1)); }
200
201    void Duplicate()
202    {
203        int vlen = m_vert.Count() - m_vert_cursor;
204        int qlen = m_quadidx.Count() - m_quadidx_cursor;
205        int tlen = m_triidx.Count() - m_triidx_cursor;
206
207        for (int i = 0; i < vlen; i++)
208            m_vert += m_vert[m_vert_cursor++];
209
210        for (int i = 0; i < qlen; i++)
211            m_quadidx += m_quadidx[m_quadidx_cursor++] + vlen;
212
213        for (int i = 0; i < tlen; i++)
214            m_triidx += m_triidx[m_triidx_cursor++] + vlen;
215    }
216
217    void AppendCylinder() {} /* TODO */
218
219    void AppendBox(vec3 const &size)
220    {
221        AppendBox(size, 0.0f);
222    }
223
224    void AppendBox(vec3 const &size, float chamf)
225    {
226        int ibase = m_quadidx.Count();
227        int vbase = m_vert.Count();
228
229        vec3 d = size * 0.5f;
230
231        AppendQuadVert(vec3(-d.x, -d.y, -d.z - chamf));
232        AppendQuadVert(vec3(-d.x, +d.y, -d.z - chamf));
233        AppendQuadVert(vec3(+d.x, +d.y, -d.z - chamf));
234        AppendQuadVert(vec3(+d.x, -d.y, -d.z - chamf));
235
236        AppendQuadVert(vec3(-d.x - chamf, -d.y, +d.z));
237        AppendQuadVert(vec3(-d.x - chamf, +d.y, +d.z));
238        AppendQuadVert(vec3(-d.x - chamf, +d.y, -d.z));
239        AppendQuadVert(vec3(-d.x - chamf, -d.y, -d.z));
240
241        AppendQuadVert(vec3(+d.x, -d.y, +d.z + chamf));
242        AppendQuadVert(vec3(+d.x, +d.y, +d.z + chamf));
243        AppendQuadVert(vec3(-d.x, +d.y, +d.z + chamf));
244        AppendQuadVert(vec3(-d.x, -d.y, +d.z + chamf));
245
246        AppendQuadVert(vec3(+d.x + chamf, -d.y, -d.z));
247        AppendQuadVert(vec3(+d.x + chamf, +d.y, -d.z));
248        AppendQuadVert(vec3(+d.x + chamf, +d.y, +d.z));
249        AppendQuadVert(vec3(+d.x + chamf, -d.y, +d.z));
250
251        AppendQuadVert(vec3(-d.x, -d.y - chamf, +d.z));
252        AppendQuadVert(vec3(-d.x, -d.y - chamf, -d.z));
253        AppendQuadVert(vec3(+d.x, -d.y - chamf, -d.z));
254        AppendQuadVert(vec3(+d.x, -d.y - chamf, +d.z));
255
256        AppendQuadVert(vec3(-d.x, +d.y + chamf, -d.z));
257        AppendQuadVert(vec3(-d.x, +d.y + chamf, +d.z));
258        AppendQuadVert(vec3(+d.x, +d.y + chamf, +d.z));
259        AppendQuadVert(vec3(+d.x, +d.y + chamf, -d.z));
260
261        AppendQuad(0, 1, 2, 3, vbase);
262        AppendQuad(4, 5, 6, 7, vbase);
263        AppendQuad(8, 9, 10, 11, vbase);
264        AppendQuad(12, 13, 14, 15, vbase);
265        AppendQuad(16, 17, 18, 19, vbase);
266        AppendQuad(20, 21, 22, 23, vbase);
267
268        ComputeQuadNormals(ibase, m_quadidx.Count() - ibase);
269    }
270
271private:
272    vec4 m_color, m_color2;
273    Array<uint16_t> m_triidx, m_quadidx;
274    Array<vec3, vec3, vec4> m_vert;
275    int m_vert_cursor, m_quadidx_cursor, m_triidx_cursor;
276};
277
278#endif /* __MESH_H__ */
279
Note: See TracBrowser for help on using the repository browser.