rev |
line source |
nuclear@0
|
1 #include "meshgen.h"
|
nuclear@0
|
2 #include "mesh.h"
|
nuclear@0
|
3 #include "logger.h"
|
nuclear@0
|
4
|
nuclear@15
|
5 using namespace goatgfx;
|
nuclear@15
|
6
|
nuclear@0
|
7 // -------- sphere --------
|
nuclear@0
|
8
|
nuclear@0
|
9 #define SURAD(u) ((u) * 2.0 * M_PI)
|
nuclear@0
|
10 #define SVRAD(v) ((v) * M_PI)
|
nuclear@0
|
11
|
nuclear@0
|
12 static Vector3 sphvec(float theta, float phi)
|
nuclear@0
|
13 {
|
nuclear@0
|
14 return Vector3(sin(theta) * sin(phi),
|
nuclear@0
|
15 cos(phi),
|
nuclear@0
|
16 cos(theta) * sin(phi));
|
nuclear@0
|
17 }
|
nuclear@0
|
18
|
nuclear@17
|
19 void goatgfx::gen_sphere(Mesh *mesh, float rad, int usub, int vsub, float urange, float vrange)
|
nuclear@0
|
20 {
|
nuclear@0
|
21 if(usub < 4) usub = 4;
|
nuclear@0
|
22 if(vsub < 2) vsub = 2;
|
nuclear@0
|
23
|
nuclear@0
|
24 int uverts = usub + 1;
|
nuclear@0
|
25 int vverts = vsub + 1;
|
nuclear@0
|
26
|
nuclear@0
|
27 int num_verts = uverts * vverts;
|
nuclear@0
|
28 int num_quads = usub * vsub;
|
nuclear@0
|
29 int num_tri = num_quads * 2;
|
nuclear@0
|
30
|
nuclear@0
|
31 mesh->clear();
|
nuclear@0
|
32 Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0);
|
nuclear@0
|
33 Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0);
|
nuclear@0
|
34 Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0);
|
nuclear@0
|
35 Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0);
|
nuclear@0
|
36 unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0);
|
nuclear@0
|
37
|
nuclear@0
|
38 float du = urange / (float)(uverts - 1);
|
nuclear@0
|
39 float dv = vrange / (float)(vverts - 1);
|
nuclear@0
|
40
|
nuclear@0
|
41 float u = 0.0;
|
nuclear@0
|
42 for(int i=0; i<uverts; i++) {
|
nuclear@0
|
43 float theta = SURAD(u * urange);
|
nuclear@0
|
44
|
nuclear@0
|
45 float v = 0.0;
|
nuclear@0
|
46 for(int j=0; j<vverts; j++) {
|
nuclear@0
|
47 float phi = SVRAD(v * vrange);
|
nuclear@0
|
48
|
nuclear@0
|
49 Vector3 pos = sphvec(theta, phi);
|
nuclear@0
|
50
|
nuclear@0
|
51 *varr++ = pos * rad;
|
nuclear@0
|
52 *narr++ = pos;
|
nuclear@0
|
53 *tarr++ = (sphvec(theta + 0.1, M_PI / 2.0) - sphvec(theta - 0.1, M_PI / 2.0)).normalized();
|
nuclear@0
|
54 *uvarr++ = Vector2(u * urange, v * vrange);
|
nuclear@0
|
55
|
nuclear@0
|
56 if(i < usub && j < vsub) {
|
nuclear@0
|
57 int idx = i * vverts + j;
|
nuclear@0
|
58 *idxarr++ = idx;
|
nuclear@0
|
59 *idxarr++ = idx + 1;
|
nuclear@0
|
60 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
61
|
nuclear@0
|
62 *idxarr++ = idx;
|
nuclear@0
|
63 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
64 *idxarr++ = idx + vverts;
|
nuclear@0
|
65 }
|
nuclear@0
|
66
|
nuclear@0
|
67 v += dv;
|
nuclear@0
|
68 }
|
nuclear@0
|
69 u += du;
|
nuclear@0
|
70 }
|
nuclear@0
|
71 }
|
nuclear@0
|
72
|
nuclear@0
|
73
|
nuclear@0
|
74 // -------- cylinder --------
|
nuclear@0
|
75
|
nuclear@0
|
76 static Vector3 cylvec(float theta, float height)
|
nuclear@0
|
77 {
|
nuclear@0
|
78 return Vector3(sin(theta), height, cos(theta));
|
nuclear@0
|
79 }
|
nuclear@0
|
80
|
nuclear@17
|
81 void goatgfx::gen_cylinder(Mesh *mesh, float rad, float height, int usub, int vsub, int capsub, float urange, float vrange)
|
nuclear@0
|
82 {
|
nuclear@0
|
83 if(usub < 4) usub = 4;
|
nuclear@0
|
84 if(vsub < 1) vsub = 1;
|
nuclear@0
|
85
|
nuclear@0
|
86 int uverts = usub + 1;
|
nuclear@0
|
87 int vverts = vsub + 1;
|
nuclear@0
|
88
|
nuclear@0
|
89 int num_body_verts = uverts * vverts;
|
nuclear@0
|
90 int num_body_quads = usub * vsub;
|
nuclear@0
|
91 int num_body_tri = num_body_quads * 2;
|
nuclear@0
|
92
|
nuclear@0
|
93 int capvverts = capsub ? capsub + 1 : 0;
|
nuclear@0
|
94 int num_cap_verts = uverts * capvverts;
|
nuclear@0
|
95 int num_cap_quads = usub * capsub;
|
nuclear@0
|
96 int num_cap_tri = num_cap_quads * 2;
|
nuclear@0
|
97
|
nuclear@0
|
98 int num_verts = num_body_verts + num_cap_verts * 2;
|
nuclear@0
|
99 int num_tri = num_body_tri + num_cap_tri * 2;
|
nuclear@0
|
100
|
nuclear@0
|
101 mesh->clear();
|
nuclear@0
|
102 Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0);
|
nuclear@0
|
103 Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0);
|
nuclear@0
|
104 Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0);
|
nuclear@0
|
105 Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0);
|
nuclear@0
|
106 unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0);
|
nuclear@0
|
107
|
nuclear@0
|
108 float du = urange / (float)(uverts - 1);
|
nuclear@0
|
109 float dv = vrange / (float)(vverts - 1);
|
nuclear@0
|
110
|
nuclear@0
|
111 float u = 0.0;
|
nuclear@0
|
112 for(int i=0; i<uverts; i++) {
|
nuclear@0
|
113 float theta = SURAD(u);
|
nuclear@0
|
114
|
nuclear@0
|
115 float v = 0.0;
|
nuclear@0
|
116 for(int j=0; j<vverts; j++) {
|
nuclear@0
|
117 float y = (v - 0.5) * height;
|
nuclear@0
|
118 Vector3 pos = cylvec(theta, y);
|
nuclear@0
|
119
|
nuclear@0
|
120 *varr++ = Vector3(pos.x * rad, pos.y, pos.z * rad);
|
nuclear@0
|
121 *narr++ = Vector3(pos.x, 0.0, pos.z);
|
nuclear@0
|
122 *tarr++ = (cylvec(theta + 0.1, 0.0) - cylvec(theta - 0.1, 0.0)).normalized();
|
nuclear@0
|
123 *uvarr++ = Vector2(u * urange, v * vrange);
|
nuclear@0
|
124
|
nuclear@0
|
125 if(i < usub && j < vsub) {
|
nuclear@0
|
126 int idx = i * vverts + j;
|
nuclear@0
|
127
|
nuclear@0
|
128 *idxarr++ = idx;
|
nuclear@0
|
129 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
130 *idxarr++ = idx + 1;
|
nuclear@0
|
131
|
nuclear@0
|
132 *idxarr++ = idx;
|
nuclear@0
|
133 *idxarr++ = idx + vverts;
|
nuclear@0
|
134 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
135 }
|
nuclear@0
|
136
|
nuclear@0
|
137 v += dv;
|
nuclear@0
|
138 }
|
nuclear@0
|
139 u += du;
|
nuclear@0
|
140 }
|
nuclear@0
|
141
|
nuclear@0
|
142
|
nuclear@0
|
143 // now the cap!
|
nuclear@0
|
144 if(!capsub) {
|
nuclear@0
|
145 return;
|
nuclear@0
|
146 }
|
nuclear@0
|
147
|
nuclear@0
|
148 dv = 1.0 / (float)(capvverts - 1);
|
nuclear@0
|
149
|
nuclear@0
|
150 u = 0.0;
|
nuclear@0
|
151 for(int i=0; i<uverts; i++) {
|
nuclear@0
|
152 float theta = SURAD(u);
|
nuclear@0
|
153
|
nuclear@0
|
154 float v = 0.0;
|
nuclear@0
|
155 for(int j=0; j<capvverts; j++) {
|
nuclear@0
|
156 float r = v * rad;
|
nuclear@0
|
157
|
nuclear@0
|
158 Vector3 pos = cylvec(theta, height / 2.0) * r;
|
nuclear@0
|
159 pos.y = height / 2.0;
|
nuclear@0
|
160 Vector3 tang = (cylvec(theta + 0.1, 0.0) - cylvec(theta - 0.1, 0.0)).normalized();
|
nuclear@0
|
161
|
nuclear@0
|
162 *varr++ = pos;
|
nuclear@0
|
163 *narr++ = Vector3(0, 1, 0);
|
nuclear@0
|
164 *tarr++ = tang;
|
nuclear@0
|
165 *uvarr++ = Vector2(u * urange, v);
|
nuclear@0
|
166
|
nuclear@0
|
167 pos.y = -height / 2.0;
|
nuclear@0
|
168 *varr++ = pos;
|
nuclear@0
|
169 *narr++ = Vector3(0, -1, 0);
|
nuclear@0
|
170 *tarr++ = -tang;
|
nuclear@0
|
171 *uvarr++ = Vector2(u * urange, v);
|
nuclear@0
|
172
|
nuclear@0
|
173 if(i < usub && j < capsub) {
|
nuclear@0
|
174 unsigned int idx = num_body_verts + (i * capvverts + j) * 2;
|
nuclear@0
|
175
|
nuclear@0
|
176 unsigned int vidx[4] = {
|
nuclear@0
|
177 idx,
|
nuclear@0
|
178 idx + capvverts * 2,
|
nuclear@0
|
179 idx + (capvverts + 1) * 2,
|
nuclear@0
|
180 idx + 2
|
nuclear@0
|
181 };
|
nuclear@0
|
182
|
nuclear@0
|
183 *idxarr++ = vidx[0];
|
nuclear@0
|
184 *idxarr++ = vidx[2];
|
nuclear@0
|
185 *idxarr++ = vidx[1];
|
nuclear@0
|
186 *idxarr++ = vidx[0];
|
nuclear@0
|
187 *idxarr++ = vidx[3];
|
nuclear@0
|
188 *idxarr++ = vidx[2];
|
nuclear@0
|
189
|
nuclear@0
|
190 *idxarr++ = vidx[0] + 1;
|
nuclear@0
|
191 *idxarr++ = vidx[1] + 1;
|
nuclear@0
|
192 *idxarr++ = vidx[2] + 1;
|
nuclear@0
|
193 *idxarr++ = vidx[0] + 1;
|
nuclear@0
|
194 *idxarr++ = vidx[2] + 1;
|
nuclear@0
|
195 *idxarr++ = vidx[3] + 1;
|
nuclear@0
|
196 }
|
nuclear@0
|
197
|
nuclear@0
|
198 v += dv;
|
nuclear@0
|
199 }
|
nuclear@0
|
200 u += du;
|
nuclear@0
|
201 }
|
nuclear@0
|
202 }
|
nuclear@0
|
203
|
nuclear@0
|
204 // -------- cone --------
|
nuclear@0
|
205
|
nuclear@0
|
206 static Vector3 conevec(float theta, float y, float height)
|
nuclear@0
|
207 {
|
nuclear@0
|
208 float scale = 1.0 - y / height;
|
nuclear@0
|
209 return Vector3(sin(theta) * scale, y, cos(theta) * scale);
|
nuclear@0
|
210 }
|
nuclear@0
|
211
|
nuclear@17
|
212 void goatgfx::gen_cone(Mesh *mesh, float rad, float height, int usub, int vsub, int capsub, float urange, float vrange)
|
nuclear@0
|
213 {
|
nuclear@0
|
214 if(usub < 4) usub = 4;
|
nuclear@0
|
215 if(vsub < 1) vsub = 1;
|
nuclear@0
|
216
|
nuclear@0
|
217 int uverts = usub + 1;
|
nuclear@0
|
218 int vverts = vsub + 1;
|
nuclear@0
|
219
|
nuclear@0
|
220 int num_body_verts = uverts * vverts;
|
nuclear@0
|
221 int num_body_quads = usub * vsub;
|
nuclear@0
|
222 int num_body_tri = num_body_quads * 2;
|
nuclear@0
|
223
|
nuclear@0
|
224 int capvverts = capsub ? capsub + 1 : 0;
|
nuclear@0
|
225 int num_cap_verts = uverts * capvverts;
|
nuclear@0
|
226 int num_cap_quads = usub * capsub;
|
nuclear@0
|
227 int num_cap_tri = num_cap_quads * 2;
|
nuclear@0
|
228
|
nuclear@0
|
229 int num_verts = num_body_verts + num_cap_verts;
|
nuclear@0
|
230 int num_tri = num_body_tri + num_cap_tri;
|
nuclear@0
|
231
|
nuclear@0
|
232 mesh->clear();
|
nuclear@0
|
233 Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0);
|
nuclear@0
|
234 Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0);
|
nuclear@0
|
235 Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0);
|
nuclear@0
|
236 Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0);
|
nuclear@0
|
237 unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0);
|
nuclear@0
|
238
|
nuclear@0
|
239 float du = urange / (float)(uverts - 1);
|
nuclear@0
|
240 float dv = vrange / (float)(vverts - 1);
|
nuclear@0
|
241
|
nuclear@0
|
242 float u = 0.0;
|
nuclear@0
|
243 for(int i=0; i<uverts; i++) {
|
nuclear@0
|
244 float theta = SURAD(u);
|
nuclear@0
|
245
|
nuclear@0
|
246 float v = 0.0;
|
nuclear@0
|
247 for(int j=0; j<vverts; j++) {
|
nuclear@0
|
248 float y = v * height;
|
nuclear@0
|
249 Vector3 pos = conevec(theta, y, height);
|
nuclear@0
|
250
|
nuclear@0
|
251 Vector3 tang = (conevec(theta + 0.1, 0.0, height) - conevec(theta - 0.1, 0.0, height)).normalized();
|
nuclear@0
|
252 Vector3 bitang = (conevec(theta, y + 0.1, height) - pos).normalized();
|
nuclear@0
|
253
|
nuclear@0
|
254 *varr++ = Vector3(pos.x * rad, pos.y, pos.z * rad);
|
nuclear@0
|
255 *narr++ = cross_product(tang, bitang);
|
nuclear@0
|
256 *tarr++ = tang;
|
nuclear@0
|
257 *uvarr++ = Vector2(u * urange, v * vrange);
|
nuclear@0
|
258
|
nuclear@0
|
259 if(i < usub && j < vsub) {
|
nuclear@0
|
260 int idx = i * vverts + j;
|
nuclear@0
|
261
|
nuclear@0
|
262 *idxarr++ = idx;
|
nuclear@0
|
263 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
264 *idxarr++ = idx + 1;
|
nuclear@0
|
265
|
nuclear@0
|
266 *idxarr++ = idx;
|
nuclear@0
|
267 *idxarr++ = idx + vverts;
|
nuclear@0
|
268 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
269 }
|
nuclear@0
|
270
|
nuclear@0
|
271 v += dv;
|
nuclear@0
|
272 }
|
nuclear@0
|
273 u += du;
|
nuclear@0
|
274 }
|
nuclear@0
|
275
|
nuclear@0
|
276
|
nuclear@0
|
277 // now the bottom cap!
|
nuclear@0
|
278 if(!capsub) {
|
nuclear@0
|
279 return;
|
nuclear@0
|
280 }
|
nuclear@0
|
281
|
nuclear@0
|
282 dv = 1.0 / (float)(capvverts - 1);
|
nuclear@0
|
283
|
nuclear@0
|
284 u = 0.0;
|
nuclear@0
|
285 for(int i=0; i<uverts; i++) {
|
nuclear@0
|
286 float theta = SURAD(u);
|
nuclear@0
|
287
|
nuclear@0
|
288 float v = 0.0;
|
nuclear@0
|
289 for(int j=0; j<capvverts; j++) {
|
nuclear@0
|
290 float r = v * rad;
|
nuclear@0
|
291
|
nuclear@0
|
292 Vector3 pos = conevec(theta, 0.0, height) * r;
|
nuclear@0
|
293 Vector3 tang = (cylvec(theta + 0.1, 0.0) - cylvec(theta - 0.1, 0.0)).normalized();
|
nuclear@0
|
294
|
nuclear@0
|
295 *varr++ = pos;
|
nuclear@0
|
296 *narr++ = Vector3(0, -1, 0);
|
nuclear@0
|
297 *tarr++ = tang;
|
nuclear@0
|
298 *uvarr++ = Vector2(u * urange, v);
|
nuclear@0
|
299
|
nuclear@0
|
300 if(i < usub && j < capsub) {
|
nuclear@0
|
301 unsigned int idx = num_body_verts + i * capvverts + j;
|
nuclear@0
|
302
|
nuclear@0
|
303 unsigned int vidx[4] = {
|
nuclear@0
|
304 idx,
|
nuclear@0
|
305 idx + capvverts,
|
nuclear@0
|
306 idx + (capvverts + 1),
|
nuclear@0
|
307 idx + 1
|
nuclear@0
|
308 };
|
nuclear@0
|
309
|
nuclear@0
|
310 *idxarr++ = vidx[0];
|
nuclear@0
|
311 *idxarr++ = vidx[1];
|
nuclear@0
|
312 *idxarr++ = vidx[2];
|
nuclear@0
|
313 *idxarr++ = vidx[0];
|
nuclear@0
|
314 *idxarr++ = vidx[2];
|
nuclear@0
|
315 *idxarr++ = vidx[3];
|
nuclear@0
|
316 }
|
nuclear@0
|
317
|
nuclear@0
|
318 v += dv;
|
nuclear@0
|
319 }
|
nuclear@0
|
320 u += du;
|
nuclear@0
|
321 }
|
nuclear@0
|
322 }
|
nuclear@0
|
323
|
nuclear@0
|
324
|
nuclear@0
|
325 // -------- plane --------
|
nuclear@0
|
326
|
nuclear@17
|
327 void goatgfx::gen_plane(Mesh *mesh, float width, float height, int usub, int vsub)
|
nuclear@0
|
328 {
|
nuclear@0
|
329 if(usub < 1) usub = 1;
|
nuclear@0
|
330 if(vsub < 1) vsub = 1;
|
nuclear@0
|
331
|
nuclear@0
|
332 mesh->clear();
|
nuclear@0
|
333
|
nuclear@0
|
334 int uverts = usub + 1;
|
nuclear@0
|
335 int vverts = vsub + 1;
|
nuclear@0
|
336 int num_verts = uverts * vverts;
|
nuclear@0
|
337
|
nuclear@0
|
338 int num_quads = usub * vsub;
|
nuclear@0
|
339 int num_tri = num_quads * 2;
|
nuclear@0
|
340
|
nuclear@0
|
341 Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0);
|
nuclear@0
|
342 Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0);
|
nuclear@0
|
343 Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0);
|
nuclear@0
|
344 Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0);
|
nuclear@0
|
345 unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0);
|
nuclear@0
|
346
|
nuclear@0
|
347 float du = 1.0 / (float)usub;
|
nuclear@0
|
348 float dv = 1.0 / (float)vsub;
|
nuclear@0
|
349
|
nuclear@0
|
350 float u = 0.0;
|
nuclear@0
|
351 for(int i=0; i<uverts; i++) {
|
nuclear@0
|
352 float v = 0.0;
|
nuclear@0
|
353 for(int j=0; j<vverts; j++) {
|
nuclear@0
|
354 *varr++ = Vector3((u - 0.5) * width, (v - 0.5) * height, 0.0);
|
nuclear@0
|
355 *narr++ = Vector3(0, 0, 1);
|
nuclear@0
|
356 *tarr++ = Vector3(1, 0, 0);
|
nuclear@0
|
357 *uvarr++ = Vector2(u, v);
|
nuclear@0
|
358
|
nuclear@0
|
359 if(i < usub && j < vsub) {
|
nuclear@0
|
360 int idx = i * vverts + j;
|
nuclear@0
|
361
|
nuclear@0
|
362 *idxarr++ = idx;
|
nuclear@0
|
363 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
364 *idxarr++ = idx + 1;
|
nuclear@0
|
365
|
nuclear@0
|
366 *idxarr++ = idx;
|
nuclear@0
|
367 *idxarr++ = idx + vverts;
|
nuclear@0
|
368 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
369 }
|
nuclear@0
|
370
|
nuclear@0
|
371 v += dv;
|
nuclear@0
|
372 }
|
nuclear@0
|
373 u += du;
|
nuclear@0
|
374 }
|
nuclear@0
|
375 }
|