rev |
line source |
nuclear@0
|
1 #include <stdio.h>
|
nuclear@0
|
2 #include "meshgen.h"
|
nuclear@0
|
3 #include "mesh.h"
|
nuclear@0
|
4
|
nuclear@0
|
5 // -------- sphere --------
|
nuclear@0
|
6
|
nuclear@0
|
7 #define SURAD(u) ((u) * 2.0 * M_PI)
|
nuclear@0
|
8 #define SVRAD(v) ((v) * M_PI)
|
nuclear@0
|
9
|
nuclear@0
|
10 static Vector3 sphvec(float theta, float phi)
|
nuclear@0
|
11 {
|
nuclear@0
|
12 return Vector3(sin(theta) * sin(phi),
|
nuclear@0
|
13 cos(phi),
|
nuclear@0
|
14 cos(theta) * sin(phi));
|
nuclear@0
|
15 }
|
nuclear@0
|
16
|
nuclear@0
|
17 void gen_sphere(Mesh *mesh, float rad, int usub, int vsub, float urange, float vrange)
|
nuclear@0
|
18 {
|
nuclear@0
|
19 if(usub < 4) usub = 4;
|
nuclear@0
|
20 if(vsub < 2) vsub = 2;
|
nuclear@0
|
21
|
nuclear@0
|
22 int uverts = usub + 1;
|
nuclear@0
|
23 int vverts = vsub + 1;
|
nuclear@0
|
24
|
nuclear@0
|
25 int num_verts = uverts * vverts;
|
nuclear@0
|
26 int num_quads = usub * vsub;
|
nuclear@0
|
27 int num_tri = num_quads * 2;
|
nuclear@0
|
28
|
nuclear@0
|
29 mesh->clear();
|
nuclear@0
|
30 Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0);
|
nuclear@0
|
31 Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0);
|
nuclear@0
|
32 Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0);
|
nuclear@0
|
33 Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0);
|
nuclear@0
|
34 unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0);
|
nuclear@0
|
35
|
nuclear@0
|
36 float du = urange / (float)(uverts - 1);
|
nuclear@0
|
37 float dv = vrange / (float)(vverts - 1);
|
nuclear@0
|
38
|
nuclear@0
|
39 float u = 0.0;
|
nuclear@0
|
40 for(int i=0; i<uverts; i++) {
|
nuclear@0
|
41 float theta = u * 2.0 * M_PI;
|
nuclear@0
|
42
|
nuclear@0
|
43 float v = 0.0;
|
nuclear@0
|
44 for(int j=0; j<vverts; j++) {
|
nuclear@0
|
45 float phi = v * M_PI;
|
nuclear@0
|
46
|
nuclear@0
|
47 Vector3 pos = sphvec(theta, phi);
|
nuclear@0
|
48
|
nuclear@0
|
49 *varr++ = pos * rad;
|
nuclear@0
|
50 *narr++ = pos;
|
nuclear@0
|
51 *tarr++ = (sphvec(theta + 0.1f, (float)M_PI / 2.0f) - sphvec(theta - 0.1f, (float)M_PI / 2.0f)).normalized();
|
nuclear@0
|
52 *uvarr++ = Vector2(u * urange, v * vrange);
|
nuclear@0
|
53
|
nuclear@0
|
54 if(i < usub && j < vsub) {
|
nuclear@0
|
55 int idx = i * vverts + j;
|
nuclear@0
|
56 *idxarr++ = idx;
|
nuclear@0
|
57 *idxarr++ = idx + 1;
|
nuclear@0
|
58 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
59
|
nuclear@0
|
60 *idxarr++ = idx;
|
nuclear@0
|
61 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
62 *idxarr++ = idx + vverts;
|
nuclear@0
|
63 }
|
nuclear@0
|
64
|
nuclear@0
|
65 v += dv;
|
nuclear@0
|
66 }
|
nuclear@0
|
67 u += du;
|
nuclear@0
|
68 }
|
nuclear@0
|
69 }
|
nuclear@0
|
70
|
nuclear@0
|
71 // -------- torus -----------
|
nuclear@0
|
72 static Vector3 torusvec(float theta, float phi, float mr, float rr)
|
nuclear@0
|
73 {
|
nuclear@0
|
74 theta = -theta;
|
nuclear@0
|
75
|
nuclear@0
|
76 float rx = -cos(phi) * rr + mr;
|
nuclear@0
|
77 float ry = sin(phi) * rr;
|
nuclear@0
|
78 float rz = 0.0;
|
nuclear@0
|
79
|
nuclear@0
|
80 float x = rx * sin(theta) + rz * cos(theta);
|
nuclear@0
|
81 float y = ry;
|
nuclear@0
|
82 float z = -rx * cos(theta) + rz * sin(theta);
|
nuclear@0
|
83
|
nuclear@0
|
84 return Vector3(x, y, z);
|
nuclear@0
|
85 }
|
nuclear@0
|
86
|
nuclear@0
|
87 void gen_torus(Mesh *mesh, float mainrad, float ringrad, int usub, int vsub, float urange, float vrange)
|
nuclear@0
|
88 {
|
nuclear@0
|
89 if(usub < 4) usub = 4;
|
nuclear@0
|
90 if(vsub < 2) vsub = 2;
|
nuclear@0
|
91
|
nuclear@0
|
92 int uverts = usub + 1;
|
nuclear@0
|
93 int vverts = vsub + 1;
|
nuclear@0
|
94
|
nuclear@0
|
95 int num_verts = uverts * vverts;
|
nuclear@0
|
96 int num_quads = usub * vsub;
|
nuclear@0
|
97 int num_tri = num_quads * 2;
|
nuclear@0
|
98
|
nuclear@0
|
99 mesh->clear();
|
nuclear@0
|
100 Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0);
|
nuclear@0
|
101 Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0);
|
nuclear@0
|
102 Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0);
|
nuclear@0
|
103 Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0);
|
nuclear@0
|
104 unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0);
|
nuclear@0
|
105
|
nuclear@0
|
106 float du = urange / (float)(uverts - 1);
|
nuclear@0
|
107 float dv = vrange / (float)(vverts - 1);
|
nuclear@0
|
108
|
nuclear@0
|
109 float u = 0.0;
|
nuclear@0
|
110 for(int i=0; i<uverts; i++) {
|
nuclear@0
|
111 float theta = u * 2.0 * M_PI;
|
nuclear@0
|
112
|
nuclear@0
|
113 float v = 0.0;
|
nuclear@0
|
114 for(int j=0; j<vverts; j++) {
|
nuclear@0
|
115 float phi = v * 2.0 * M_PI;
|
nuclear@0
|
116
|
nuclear@0
|
117 Vector3 pos = torusvec(theta, phi, mainrad, ringrad);
|
nuclear@0
|
118 Vector3 cent = torusvec(theta, phi, mainrad, 0.0);
|
nuclear@0
|
119
|
nuclear@0
|
120 *varr++ = pos;
|
nuclear@0
|
121 *narr++ = (pos - cent) / ringrad;
|
nuclear@0
|
122
|
nuclear@0
|
123 Vector3 pprev = torusvec(theta - 0.1f, phi, mainrad, ringrad);
|
nuclear@0
|
124 Vector3 pnext = torusvec(theta + 0.1f, phi, mainrad, ringrad);
|
nuclear@0
|
125
|
nuclear@0
|
126 *tarr++ = (pnext - pprev).normalized();
|
nuclear@0
|
127 *uvarr++ = Vector2(u * urange, v * vrange);
|
nuclear@0
|
128
|
nuclear@0
|
129 if(i < usub && j < vsub) {
|
nuclear@0
|
130 int idx = i * vverts + j;
|
nuclear@0
|
131 *idxarr++ = idx;
|
nuclear@0
|
132 *idxarr++ = idx + 1;
|
nuclear@0
|
133 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
134
|
nuclear@0
|
135 *idxarr++ = idx;
|
nuclear@0
|
136 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
137 *idxarr++ = idx + vverts;
|
nuclear@0
|
138 }
|
nuclear@0
|
139
|
nuclear@0
|
140 v += dv;
|
nuclear@0
|
141 }
|
nuclear@0
|
142 u += du;
|
nuclear@0
|
143 }
|
nuclear@0
|
144 }
|
nuclear@0
|
145
|
nuclear@0
|
146
|
nuclear@0
|
147 // -------- cylinder --------
|
nuclear@0
|
148
|
nuclear@0
|
149 static Vector3 cylvec(float theta, float height)
|
nuclear@0
|
150 {
|
nuclear@0
|
151 return Vector3(sin(theta), height, cos(theta));
|
nuclear@0
|
152 }
|
nuclear@0
|
153
|
nuclear@0
|
154 void gen_cylinder(Mesh *mesh, float rad, float height, int usub, int vsub, int capsub, float urange, float vrange)
|
nuclear@0
|
155 {
|
nuclear@0
|
156 if(usub < 4) usub = 4;
|
nuclear@0
|
157 if(vsub < 1) vsub = 1;
|
nuclear@0
|
158
|
nuclear@0
|
159 int uverts = usub + 1;
|
nuclear@0
|
160 int vverts = vsub + 1;
|
nuclear@0
|
161
|
nuclear@0
|
162 int num_body_verts = uverts * vverts;
|
nuclear@0
|
163 int num_body_quads = usub * vsub;
|
nuclear@0
|
164 int num_body_tri = num_body_quads * 2;
|
nuclear@0
|
165
|
nuclear@0
|
166 int capvverts = capsub ? capsub + 1 : 0;
|
nuclear@0
|
167 int num_cap_verts = uverts * capvverts;
|
nuclear@0
|
168 int num_cap_quads = usub * capsub;
|
nuclear@0
|
169 int num_cap_tri = num_cap_quads * 2;
|
nuclear@0
|
170
|
nuclear@0
|
171 int num_verts = num_body_verts + num_cap_verts * 2;
|
nuclear@0
|
172 int num_tri = num_body_tri + num_cap_tri * 2;
|
nuclear@0
|
173
|
nuclear@0
|
174 mesh->clear();
|
nuclear@0
|
175 Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0);
|
nuclear@0
|
176 Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0);
|
nuclear@0
|
177 Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0);
|
nuclear@0
|
178 Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0);
|
nuclear@0
|
179 unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0);
|
nuclear@0
|
180
|
nuclear@0
|
181 float du = urange / (float)(uverts - 1);
|
nuclear@0
|
182 float dv = vrange / (float)(vverts - 1);
|
nuclear@0
|
183
|
nuclear@0
|
184 float u = 0.0;
|
nuclear@0
|
185 for(int i=0; i<uverts; i++) {
|
nuclear@0
|
186 float theta = SURAD(u);
|
nuclear@0
|
187
|
nuclear@0
|
188 float v = 0.0;
|
nuclear@0
|
189 for(int j=0; j<vverts; j++) {
|
nuclear@0
|
190 float y = (v - 0.5) * height;
|
nuclear@0
|
191 Vector3 pos = cylvec(theta, y);
|
nuclear@0
|
192
|
nuclear@0
|
193 *varr++ = Vector3(pos.x * rad, pos.y, pos.z * rad);
|
nuclear@0
|
194 *narr++ = Vector3(pos.x, 0.0, pos.z);
|
nuclear@0
|
195 *tarr++ = (cylvec(theta + 0.1, 0.0) - cylvec(theta - 0.1, 0.0)).normalized();
|
nuclear@0
|
196 *uvarr++ = Vector2(u * urange, v * vrange);
|
nuclear@0
|
197
|
nuclear@0
|
198 if(i < usub && j < vsub) {
|
nuclear@0
|
199 int idx = i * vverts + j;
|
nuclear@0
|
200
|
nuclear@0
|
201 *idxarr++ = idx;
|
nuclear@0
|
202 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
203 *idxarr++ = idx + 1;
|
nuclear@0
|
204
|
nuclear@0
|
205 *idxarr++ = idx;
|
nuclear@0
|
206 *idxarr++ = idx + vverts;
|
nuclear@0
|
207 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
208 }
|
nuclear@0
|
209
|
nuclear@0
|
210 v += dv;
|
nuclear@0
|
211 }
|
nuclear@0
|
212 u += du;
|
nuclear@0
|
213 }
|
nuclear@0
|
214
|
nuclear@0
|
215
|
nuclear@0
|
216 // now the cap!
|
nuclear@0
|
217 if(!capsub) {
|
nuclear@0
|
218 return;
|
nuclear@0
|
219 }
|
nuclear@0
|
220
|
nuclear@0
|
221 dv = 1.0 / (float)(capvverts - 1);
|
nuclear@0
|
222
|
nuclear@0
|
223 u = 0.0;
|
nuclear@0
|
224 for(int i=0; i<uverts; i++) {
|
nuclear@0
|
225 float theta = SURAD(u);
|
nuclear@0
|
226
|
nuclear@0
|
227 float v = 0.0;
|
nuclear@0
|
228 for(int j=0; j<capvverts; j++) {
|
nuclear@0
|
229 float r = v * rad;
|
nuclear@0
|
230
|
nuclear@0
|
231 Vector3 pos = cylvec(theta, height / 2.0) * r;
|
nuclear@0
|
232 pos.y = height / 2.0;
|
nuclear@0
|
233 Vector3 tang = (cylvec(theta + 0.1, 0.0) - cylvec(theta - 0.1, 0.0)).normalized();
|
nuclear@0
|
234
|
nuclear@0
|
235 *varr++ = pos;
|
nuclear@0
|
236 *narr++ = Vector3(0, 1, 0);
|
nuclear@0
|
237 *tarr++ = tang;
|
nuclear@0
|
238 *uvarr++ = Vector2(u * urange, v);
|
nuclear@0
|
239
|
nuclear@0
|
240 pos.y = -height / 2.0;
|
nuclear@0
|
241 *varr++ = pos;
|
nuclear@0
|
242 *narr++ = Vector3(0, -1, 0);
|
nuclear@0
|
243 *tarr++ = -tang;
|
nuclear@0
|
244 *uvarr++ = Vector2(u * urange, v);
|
nuclear@0
|
245
|
nuclear@0
|
246 if(i < usub && j < capsub) {
|
nuclear@0
|
247 unsigned int idx = num_body_verts + (i * capvverts + j) * 2;
|
nuclear@0
|
248
|
nuclear@0
|
249 unsigned int vidx[4] = {
|
nuclear@0
|
250 idx,
|
nuclear@0
|
251 idx + capvverts * 2,
|
nuclear@0
|
252 idx + (capvverts + 1) * 2,
|
nuclear@0
|
253 idx + 2
|
nuclear@0
|
254 };
|
nuclear@0
|
255
|
nuclear@0
|
256 *idxarr++ = vidx[0];
|
nuclear@0
|
257 *idxarr++ = vidx[2];
|
nuclear@0
|
258 *idxarr++ = vidx[1];
|
nuclear@0
|
259 *idxarr++ = vidx[0];
|
nuclear@0
|
260 *idxarr++ = vidx[3];
|
nuclear@0
|
261 *idxarr++ = vidx[2];
|
nuclear@0
|
262
|
nuclear@0
|
263 *idxarr++ = vidx[0] + 1;
|
nuclear@0
|
264 *idxarr++ = vidx[1] + 1;
|
nuclear@0
|
265 *idxarr++ = vidx[2] + 1;
|
nuclear@0
|
266 *idxarr++ = vidx[0] + 1;
|
nuclear@0
|
267 *idxarr++ = vidx[2] + 1;
|
nuclear@0
|
268 *idxarr++ = vidx[3] + 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 // -------- cone --------
|
nuclear@0
|
278
|
nuclear@0
|
279 static Vector3 conevec(float theta, float y, float height)
|
nuclear@0
|
280 {
|
nuclear@0
|
281 float scale = 1.0 - y / height;
|
nuclear@0
|
282 return Vector3(sin(theta) * scale, y, cos(theta) * scale);
|
nuclear@0
|
283 }
|
nuclear@0
|
284
|
nuclear@0
|
285 void gen_cone(Mesh *mesh, float rad, float height, int usub, int vsub, int capsub, float urange, float vrange)
|
nuclear@0
|
286 {
|
nuclear@0
|
287 if(usub < 4) usub = 4;
|
nuclear@0
|
288 if(vsub < 1) vsub = 1;
|
nuclear@0
|
289
|
nuclear@0
|
290 int uverts = usub + 1;
|
nuclear@0
|
291 int vverts = vsub + 1;
|
nuclear@0
|
292
|
nuclear@0
|
293 int num_body_verts = uverts * vverts;
|
nuclear@0
|
294 int num_body_quads = usub * vsub;
|
nuclear@0
|
295 int num_body_tri = num_body_quads * 2;
|
nuclear@0
|
296
|
nuclear@0
|
297 int capvverts = capsub ? capsub + 1 : 0;
|
nuclear@0
|
298 int num_cap_verts = uverts * capvverts;
|
nuclear@0
|
299 int num_cap_quads = usub * capsub;
|
nuclear@0
|
300 int num_cap_tri = num_cap_quads * 2;
|
nuclear@0
|
301
|
nuclear@0
|
302 int num_verts = num_body_verts + num_cap_verts;
|
nuclear@0
|
303 int num_tri = num_body_tri + num_cap_tri;
|
nuclear@0
|
304
|
nuclear@0
|
305 mesh->clear();
|
nuclear@0
|
306 Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0);
|
nuclear@0
|
307 Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0);
|
nuclear@0
|
308 Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0);
|
nuclear@0
|
309 Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0);
|
nuclear@0
|
310 unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0);
|
nuclear@0
|
311
|
nuclear@0
|
312 float du = urange / (float)(uverts - 1);
|
nuclear@0
|
313 float dv = vrange / (float)(vverts - 1);
|
nuclear@0
|
314
|
nuclear@0
|
315 float u = 0.0;
|
nuclear@0
|
316 for(int i=0; i<uverts; i++) {
|
nuclear@0
|
317 float theta = SURAD(u);
|
nuclear@0
|
318
|
nuclear@0
|
319 float v = 0.0;
|
nuclear@0
|
320 for(int j=0; j<vverts; j++) {
|
nuclear@0
|
321 float y = v * height;
|
nuclear@0
|
322 Vector3 pos = conevec(theta, y, height);
|
nuclear@0
|
323
|
nuclear@0
|
324 Vector3 tang = (conevec(theta + 0.1, 0.0, height) - conevec(theta - 0.1, 0.0, height)).normalized();
|
nuclear@0
|
325 Vector3 bitang = (conevec(theta, y + 0.1, height) - pos).normalized();
|
nuclear@0
|
326
|
nuclear@0
|
327 *varr++ = Vector3(pos.x * rad, pos.y, pos.z * rad);
|
nuclear@0
|
328 *narr++ = cross_product(tang, bitang);
|
nuclear@0
|
329 *tarr++ = tang;
|
nuclear@0
|
330 *uvarr++ = Vector2(u * urange, v * vrange);
|
nuclear@0
|
331
|
nuclear@0
|
332 if(i < usub && j < vsub) {
|
nuclear@0
|
333 int idx = i * vverts + j;
|
nuclear@0
|
334
|
nuclear@0
|
335 *idxarr++ = idx;
|
nuclear@0
|
336 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
337 *idxarr++ = idx + 1;
|
nuclear@0
|
338
|
nuclear@0
|
339 *idxarr++ = idx;
|
nuclear@0
|
340 *idxarr++ = idx + vverts;
|
nuclear@0
|
341 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
342 }
|
nuclear@0
|
343
|
nuclear@0
|
344 v += dv;
|
nuclear@0
|
345 }
|
nuclear@0
|
346 u += du;
|
nuclear@0
|
347 }
|
nuclear@0
|
348
|
nuclear@0
|
349
|
nuclear@0
|
350 // now the bottom cap!
|
nuclear@0
|
351 if(!capsub) {
|
nuclear@0
|
352 return;
|
nuclear@0
|
353 }
|
nuclear@0
|
354
|
nuclear@0
|
355 dv = 1.0 / (float)(capvverts - 1);
|
nuclear@0
|
356
|
nuclear@0
|
357 u = 0.0;
|
nuclear@0
|
358 for(int i=0; i<uverts; i++) {
|
nuclear@0
|
359 float theta = SURAD(u);
|
nuclear@0
|
360
|
nuclear@0
|
361 float v = 0.0;
|
nuclear@0
|
362 for(int j=0; j<capvverts; j++) {
|
nuclear@0
|
363 float r = v * rad;
|
nuclear@0
|
364
|
nuclear@0
|
365 Vector3 pos = conevec(theta, 0.0, height) * r;
|
nuclear@0
|
366 Vector3 tang = (cylvec(theta + 0.1, 0.0) - cylvec(theta - 0.1, 0.0)).normalized();
|
nuclear@0
|
367
|
nuclear@0
|
368 *varr++ = pos;
|
nuclear@0
|
369 *narr++ = Vector3(0, -1, 0);
|
nuclear@0
|
370 *tarr++ = tang;
|
nuclear@0
|
371 *uvarr++ = Vector2(u * urange, v);
|
nuclear@0
|
372
|
nuclear@0
|
373 if(i < usub && j < capsub) {
|
nuclear@0
|
374 unsigned int idx = num_body_verts + i * capvverts + j;
|
nuclear@0
|
375
|
nuclear@0
|
376 unsigned int vidx[4] = {
|
nuclear@0
|
377 idx,
|
nuclear@0
|
378 idx + capvverts,
|
nuclear@0
|
379 idx + (capvverts + 1),
|
nuclear@0
|
380 idx + 1
|
nuclear@0
|
381 };
|
nuclear@0
|
382
|
nuclear@0
|
383 *idxarr++ = vidx[0];
|
nuclear@0
|
384 *idxarr++ = vidx[1];
|
nuclear@0
|
385 *idxarr++ = vidx[2];
|
nuclear@0
|
386 *idxarr++ = vidx[0];
|
nuclear@0
|
387 *idxarr++ = vidx[2];
|
nuclear@0
|
388 *idxarr++ = vidx[3];
|
nuclear@0
|
389 }
|
nuclear@0
|
390
|
nuclear@0
|
391 v += dv;
|
nuclear@0
|
392 }
|
nuclear@0
|
393 u += du;
|
nuclear@0
|
394 }
|
nuclear@0
|
395 }
|
nuclear@0
|
396
|
nuclear@0
|
397
|
nuclear@0
|
398 // -------- plane --------
|
nuclear@0
|
399
|
nuclear@0
|
400 void gen_plane(Mesh *mesh, float width, float height, int usub, int vsub)
|
nuclear@0
|
401 {
|
nuclear@0
|
402 gen_heightmap(mesh, width, height, usub, vsub, 0);
|
nuclear@0
|
403 }
|
nuclear@0
|
404
|
nuclear@0
|
405
|
nuclear@0
|
406 // ----- heightmap ------
|
nuclear@0
|
407
|
nuclear@0
|
408 void gen_heightmap(Mesh *mesh, float width, float height, int usub, int vsub, float (*hf)(float, float, void*), void *hfdata)
|
nuclear@0
|
409 {
|
nuclear@0
|
410 if(usub < 1) usub = 1;
|
nuclear@0
|
411 if(vsub < 1) vsub = 1;
|
nuclear@0
|
412
|
nuclear@0
|
413 mesh->clear();
|
nuclear@0
|
414
|
nuclear@0
|
415 int uverts = usub + 1;
|
nuclear@0
|
416 int vverts = vsub + 1;
|
nuclear@0
|
417 int num_verts = uverts * vverts;
|
nuclear@0
|
418
|
nuclear@0
|
419 int num_quads = usub * vsub;
|
nuclear@0
|
420 int num_tri = num_quads * 2;
|
nuclear@0
|
421
|
nuclear@0
|
422 Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0);
|
nuclear@0
|
423 Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0);
|
nuclear@0
|
424 Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0);
|
nuclear@0
|
425 Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0);
|
nuclear@0
|
426 unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0);
|
nuclear@0
|
427
|
nuclear@0
|
428 float du = 1.0 / (float)usub;
|
nuclear@0
|
429 float dv = 1.0 / (float)vsub;
|
nuclear@0
|
430
|
nuclear@0
|
431 float u = 0.0;
|
nuclear@0
|
432 for(int i=0; i<uverts; i++) {
|
nuclear@0
|
433 float v = 0.0;
|
nuclear@0
|
434 for(int j=0; j<vverts; j++) {
|
nuclear@0
|
435 float x = (u - 0.5) * width;
|
nuclear@0
|
436 float y = (v - 0.5) * height;
|
nuclear@0
|
437 float z = hf ? hf(u, v, hfdata) : 0.0;
|
nuclear@0
|
438
|
nuclear@0
|
439 Vector3 normal = Vector3(0, 0, 1);
|
nuclear@0
|
440 if(hf) {
|
nuclear@0
|
441 float u1z = hf(u + du, v, hfdata);
|
nuclear@0
|
442 float v1z = hf(u, v + dv, hfdata);
|
nuclear@0
|
443
|
nuclear@0
|
444 Vector3 tang = Vector3(du * width, 0, u1z - z);
|
nuclear@0
|
445 Vector3 bitan = Vector3(0, dv * height, v1z - z);
|
nuclear@0
|
446 normal = cross_product(tang, bitan).normalized();
|
nuclear@0
|
447 }
|
nuclear@0
|
448
|
nuclear@0
|
449 *varr++ = Vector3(x, y, z);
|
nuclear@0
|
450 *narr++ = normal;
|
nuclear@0
|
451 *tarr++ = Vector3(1, 0, 0);
|
nuclear@0
|
452 *uvarr++ = Vector2(u, v);
|
nuclear@0
|
453
|
nuclear@0
|
454 if(i < usub && j < vsub) {
|
nuclear@0
|
455 int idx = i * vverts + j;
|
nuclear@0
|
456
|
nuclear@0
|
457 *idxarr++ = idx;
|
nuclear@0
|
458 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
459 *idxarr++ = idx + 1;
|
nuclear@0
|
460
|
nuclear@0
|
461 *idxarr++ = idx;
|
nuclear@0
|
462 *idxarr++ = idx + vverts;
|
nuclear@0
|
463 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
464 }
|
nuclear@0
|
465
|
nuclear@0
|
466 v += dv;
|
nuclear@0
|
467 }
|
nuclear@0
|
468 u += du;
|
nuclear@0
|
469 }
|
nuclear@0
|
470 }
|
nuclear@0
|
471
|
nuclear@0
|
472 // ----- box ------
|
nuclear@0
|
473 void gen_box(Mesh *mesh, float xsz, float ysz, float zsz, int usub, int vsub)
|
nuclear@0
|
474 {
|
nuclear@0
|
475 static const float face_angles[][2] = {
|
nuclear@0
|
476 {0, 0},
|
nuclear@0
|
477 {M_PI / 2.0, 0},
|
nuclear@0
|
478 {M_PI, 0},
|
nuclear@0
|
479 {3.0 * M_PI / 2.0, 0},
|
nuclear@0
|
480 {0, M_PI / 2.0},
|
nuclear@0
|
481 {0, -M_PI / 2.0}
|
nuclear@0
|
482 };
|
nuclear@0
|
483
|
nuclear@0
|
484 if(usub < 1) usub = 1;
|
nuclear@0
|
485 if(vsub < 1) vsub = 1;
|
nuclear@0
|
486
|
nuclear@0
|
487 mesh->clear();
|
nuclear@0
|
488
|
nuclear@0
|
489 for(int i=0; i<6; i++) {
|
nuclear@0
|
490 Matrix4x4 xform, dir_xform;
|
nuclear@0
|
491 Mesh m;
|
nuclear@0
|
492
|
nuclear@0
|
493 gen_plane(&m, 1, 1, usub, vsub);
|
nuclear@0
|
494 xform.rotate(Vector3(face_angles[i][1], face_angles[i][0], 0));
|
nuclear@0
|
495 dir_xform = xform;
|
nuclear@0
|
496 xform.translate(Vector3(0, 0, 0.5));
|
nuclear@0
|
497 m.apply_xform(xform, dir_xform);
|
nuclear@0
|
498
|
nuclear@0
|
499 mesh->append(m);
|
nuclear@0
|
500 }
|
nuclear@0
|
501
|
nuclear@0
|
502 Matrix4x4 scale;
|
nuclear@0
|
503 scale.set_scaling(Vector3(xsz, ysz, zsz));
|
nuclear@0
|
504 mesh->apply_xform(scale, Matrix4x4::identity);
|
nuclear@0
|
505 }
|
nuclear@0
|
506
|
nuclear@0
|
507 /*
|
nuclear@0
|
508 void gen_box(Mesh *mesh, float xsz, float ysz, float zsz)
|
nuclear@0
|
509 {
|
nuclear@0
|
510 mesh->clear();
|
nuclear@0
|
511
|
nuclear@0
|
512 const int num_faces = 6;
|
nuclear@0
|
513 int num_verts = num_faces * 4;
|
nuclear@0
|
514 int num_tri = num_faces * 2;
|
nuclear@0
|
515
|
nuclear@0
|
516 float x = xsz / 2.0;
|
nuclear@0
|
517 float y = ysz / 2.0;
|
nuclear@0
|
518 float z = zsz / 2.0;
|
nuclear@0
|
519
|
nuclear@0
|
520 Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0);
|
nuclear@0
|
521 Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0);
|
nuclear@0
|
522 Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0);
|
nuclear@0
|
523 Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0);
|
nuclear@0
|
524 unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0);
|
nuclear@0
|
525
|
nuclear@0
|
526 static const Vector2 uv[] = { Vector2(0, 0), Vector2(1, 0), Vector2(1, 1), Vector2(0, 1) };
|
nuclear@0
|
527
|
nuclear@0
|
528 // front
|
nuclear@0
|
529 for(int i=0; i<4; i++) {
|
nuclear@0
|
530 *narr++ = Vector3(0, 0, 1);
|
nuclear@0
|
531 *tarr++ = Vector3(1, 0, 0);
|
nuclear@0
|
532 *uvarr++ = uv[i];
|
nuclear@0
|
533 }
|
nuclear@0
|
534 *varr++ = Vector3(-x, -y, z);
|
nuclear@0
|
535 *varr++ = Vector3(x, -y, z);
|
nuclear@0
|
536 *varr++ = Vector3(x, y, z);
|
nuclear@0
|
537 *varr++ = Vector3(-x, y, z);
|
nuclear@0
|
538 // right
|
nuclear@0
|
539 for(int i=0; i<4; i++) {
|
nuclear@0
|
540 *narr++ = Vector3(1, 0, 0);
|
nuclear@0
|
541 *tarr++ = Vector3(0, 0, -1);
|
nuclear@0
|
542 *uvarr++ = uv[i];
|
nuclear@0
|
543 }
|
nuclear@0
|
544 *varr++ = Vector3(x, -y, z);
|
nuclear@0
|
545 *varr++ = Vector3(x, -y, -z);
|
nuclear@0
|
546 *varr++ = Vector3(x, y, -z);
|
nuclear@0
|
547 *varr++ = Vector3(x, y, z);
|
nuclear@0
|
548 // back
|
nuclear@0
|
549 for(int i=0; i<4; i++) {
|
nuclear@0
|
550 *narr++ = Vector3(0, 0, -1);
|
nuclear@0
|
551 *tarr++ = Vector3(-1, 0, 0);
|
nuclear@0
|
552 *uvarr++ = uv[i];
|
nuclear@0
|
553 }
|
nuclear@0
|
554 *varr++ = Vector3(x, -y, -z);
|
nuclear@0
|
555 *varr++ = Vector3(-x, -y, -z);
|
nuclear@0
|
556 *varr++ = Vector3(-x, y, -z);
|
nuclear@0
|
557 *varr++ = Vector3(x, y, -z);
|
nuclear@0
|
558 // left
|
nuclear@0
|
559 for(int i=0; i<4; i++) {
|
nuclear@0
|
560 *narr++ = Vector3(-1, 0, 0);
|
nuclear@0
|
561 *tarr++ = Vector3(0, 0, 1);
|
nuclear@0
|
562 *uvarr++ = uv[i];
|
nuclear@0
|
563 }
|
nuclear@0
|
564 *varr++ = Vector3(-x, -y, -z);
|
nuclear@0
|
565 *varr++ = Vector3(-x, -y, z);
|
nuclear@0
|
566 *varr++ = Vector3(-x, y, z);
|
nuclear@0
|
567 *varr++ = Vector3(-x, y, -z);
|
nuclear@0
|
568 // top
|
nuclear@0
|
569 for(int i=0; i<4; i++) {
|
nuclear@0
|
570 *narr++ = Vector3(0, 1, 0);
|
nuclear@0
|
571 *tarr++ = Vector3(1, 0, 0);
|
nuclear@0
|
572 *uvarr++ = uv[i];
|
nuclear@0
|
573 }
|
nuclear@0
|
574 *varr++ = Vector3(-x, y, z);
|
nuclear@0
|
575 *varr++ = Vector3(x, y, z);
|
nuclear@0
|
576 *varr++ = Vector3(x, y, -z);
|
nuclear@0
|
577 *varr++ = Vector3(-x, y, -z);
|
nuclear@0
|
578 // bottom
|
nuclear@0
|
579 for(int i=0; i<4; i++) {
|
nuclear@0
|
580 *narr++ = Vector3(0, -1, 0);
|
nuclear@0
|
581 *tarr++ = Vector3(1, 0, 0);
|
nuclear@0
|
582 *uvarr++ = uv[i];
|
nuclear@0
|
583 }
|
nuclear@0
|
584 *varr++ = Vector3(-x, -y, -z);
|
nuclear@0
|
585 *varr++ = Vector3(x, -y, -z);
|
nuclear@0
|
586 *varr++ = Vector3(x, -y, z);
|
nuclear@0
|
587 *varr++ = Vector3(-x, -y, z);
|
nuclear@0
|
588
|
nuclear@0
|
589 // index array
|
nuclear@0
|
590 static const int faceidx[] = {0, 1, 2, 0, 2, 3};
|
nuclear@0
|
591 for(int i=0; i<num_faces; i++) {
|
nuclear@0
|
592 for(int j=0; j<6; j++) {
|
nuclear@0
|
593 *idxarr++ = faceidx[j] + i * 4;
|
nuclear@0
|
594 }
|
nuclear@0
|
595 }
|
nuclear@0
|
596 }
|
nuclear@0
|
597 */
|
nuclear@0
|
598
|
nuclear@0
|
599 static inline Vector3 rev_vert(float u, float v, Vector2 (*rf)(float, float, void*), void *cls)
|
nuclear@0
|
600 {
|
nuclear@0
|
601 Vector2 pos = rf(u, v, cls);
|
nuclear@0
|
602
|
nuclear@0
|
603 float angle = u * 2.0 * M_PI;
|
nuclear@0
|
604 float x = pos.x * cos(angle);
|
nuclear@0
|
605 float y = pos.y;
|
nuclear@0
|
606 float z = pos.x * sin(angle);
|
nuclear@0
|
607
|
nuclear@0
|
608 return Vector3(x, y, z);
|
nuclear@0
|
609 }
|
nuclear@0
|
610
|
nuclear@0
|
611 // ------ surface of revolution -------
|
nuclear@0
|
612 void gen_revol(Mesh *mesh, int usub, int vsub, Vector2 (*rfunc)(float, float, void*), void *cls)
|
nuclear@0
|
613 {
|
nuclear@0
|
614 gen_revol(mesh, usub, vsub, rfunc, 0, cls);
|
nuclear@0
|
615 }
|
nuclear@0
|
616
|
nuclear@0
|
617 void gen_revol(Mesh *mesh, int usub, int vsub, Vector2 (*rfunc)(float, float, void*),
|
nuclear@0
|
618 Vector2 (*nfunc)(float, float, void*), void *cls)
|
nuclear@0
|
619 {
|
nuclear@0
|
620 if(!rfunc) return;
|
nuclear@0
|
621 if(usub < 3) usub = 3;
|
nuclear@0
|
622 if(vsub < 1) vsub = 1;
|
nuclear@0
|
623
|
nuclear@0
|
624 mesh->clear();
|
nuclear@0
|
625
|
nuclear@0
|
626 int uverts = usub + 1;
|
nuclear@0
|
627 int vverts = vsub + 1;
|
nuclear@0
|
628 int num_verts = uverts * vverts;
|
nuclear@0
|
629
|
nuclear@0
|
630 int num_quads = usub * vsub;
|
nuclear@0
|
631 int num_tri = num_quads * 2;
|
nuclear@0
|
632
|
nuclear@0
|
633 Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0);
|
nuclear@0
|
634 Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0);
|
nuclear@0
|
635 Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0);
|
nuclear@0
|
636 Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0);
|
nuclear@0
|
637 unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0);
|
nuclear@0
|
638
|
nuclear@0
|
639 float du = 1.0 / (float)(uverts - 1);
|
nuclear@0
|
640 float dv = 1.0 / (float)(vverts - 1);
|
nuclear@0
|
641
|
nuclear@0
|
642 float u = 0.0;
|
nuclear@0
|
643 for(int i=0; i<uverts; i++) {
|
nuclear@0
|
644 float v = 0.0;
|
nuclear@0
|
645 for(int j=0; j<vverts; j++) {
|
nuclear@0
|
646 Vector3 pos = rev_vert(u, v, rfunc, cls);
|
nuclear@0
|
647
|
nuclear@0
|
648 Vector3 nextu = rev_vert(fmod(u + du, 1.0), v, rfunc, cls);
|
nuclear@0
|
649 Vector3 tang = nextu - pos;
|
nuclear@0
|
650 if(tang.length_sq() < 1e-6) {
|
nuclear@0
|
651 float new_v = v > 0.5 ? v - dv * 0.25 : v + dv * 0.25;
|
nuclear@0
|
652 nextu = rev_vert(fmod(u + du, 1.0), new_v, rfunc, cls);
|
nuclear@0
|
653 tang = nextu - pos;
|
nuclear@0
|
654 }
|
nuclear@0
|
655
|
nuclear@0
|
656 Vector3 normal;
|
nuclear@0
|
657 if(nfunc) {
|
nuclear@0
|
658 normal = rev_vert(u, v, nfunc, cls);
|
nuclear@0
|
659 } else {
|
nuclear@0
|
660 Vector3 nextv = rev_vert(u, v + dv, rfunc, cls);
|
nuclear@0
|
661 Vector3 bitan = nextv - pos;
|
nuclear@0
|
662 if(bitan.length_sq() < 1e-6) {
|
nuclear@0
|
663 nextv = rev_vert(u, v - dv, rfunc, cls);
|
nuclear@0
|
664 bitan = pos - nextv;
|
nuclear@0
|
665 }
|
nuclear@0
|
666
|
nuclear@0
|
667 normal = cross_product(tang, bitan);
|
nuclear@0
|
668 }
|
nuclear@0
|
669
|
nuclear@0
|
670 *varr++ = pos;
|
nuclear@0
|
671 *narr++ = normal.normalized();
|
nuclear@0
|
672 *tarr++ = tang.normalized();
|
nuclear@0
|
673 *uvarr++ = Vector2(u, v);
|
nuclear@0
|
674
|
nuclear@0
|
675 if(i < usub && j < vsub) {
|
nuclear@0
|
676 int idx = i * vverts + j;
|
nuclear@0
|
677
|
nuclear@0
|
678 *idxarr++ = idx;
|
nuclear@0
|
679 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
680 *idxarr++ = idx + 1;
|
nuclear@0
|
681
|
nuclear@0
|
682 *idxarr++ = idx;
|
nuclear@0
|
683 *idxarr++ = idx + vverts;
|
nuclear@0
|
684 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
685 }
|
nuclear@0
|
686
|
nuclear@0
|
687 v += dv;
|
nuclear@0
|
688 }
|
nuclear@0
|
689 u += du;
|
nuclear@0
|
690 }
|
nuclear@0
|
691 }
|
nuclear@0
|
692
|
nuclear@0
|
693
|
nuclear@0
|
694 static inline Vector3 sweep_vert(float u, float v, float height, Vector2 (*sf)(float, float, void*), void *cls)
|
nuclear@0
|
695 {
|
nuclear@0
|
696 Vector2 pos = sf(u, v, cls);
|
nuclear@0
|
697
|
nuclear@0
|
698 float x = pos.x;
|
nuclear@0
|
699 float y = v * height;
|
nuclear@0
|
700 float z = pos.y;
|
nuclear@0
|
701
|
nuclear@0
|
702 return Vector3(x, y, z);
|
nuclear@0
|
703 }
|
nuclear@0
|
704
|
nuclear@0
|
705 // ---- sweep shape along a path ----
|
nuclear@0
|
706 void gen_sweep(Mesh *mesh, float height, int usub, int vsub, Vector2 (*sfunc)(float, float, void*), void *cls)
|
nuclear@0
|
707 {
|
nuclear@0
|
708 if(!sfunc) return;
|
nuclear@0
|
709 if(usub < 3) usub = 3;
|
nuclear@0
|
710 if(vsub < 1) vsub = 1;
|
nuclear@0
|
711
|
nuclear@0
|
712 mesh->clear();
|
nuclear@0
|
713
|
nuclear@0
|
714 int uverts = usub + 1;
|
nuclear@0
|
715 int vverts = vsub + 1;
|
nuclear@0
|
716 int num_verts = uverts * vverts;
|
nuclear@0
|
717
|
nuclear@0
|
718 int num_quads = usub * vsub;
|
nuclear@0
|
719 int num_tri = num_quads * 2;
|
nuclear@0
|
720
|
nuclear@0
|
721 Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0);
|
nuclear@0
|
722 Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0);
|
nuclear@0
|
723 Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0);
|
nuclear@0
|
724 Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0);
|
nuclear@0
|
725 unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0);
|
nuclear@0
|
726
|
nuclear@0
|
727 float du = 1.0 / (float)(uverts - 1);
|
nuclear@0
|
728 float dv = 1.0 / (float)(vverts - 1);
|
nuclear@0
|
729
|
nuclear@0
|
730 float u = 0.0;
|
nuclear@0
|
731 for(int i=0; i<uverts; i++) {
|
nuclear@0
|
732 float v = 0.0;
|
nuclear@0
|
733 for(int j=0; j<vverts; j++) {
|
nuclear@0
|
734 Vector3 pos = sweep_vert(u, v, height, sfunc, cls);
|
nuclear@0
|
735
|
nuclear@0
|
736 Vector3 nextu = sweep_vert(fmod(u + du, 1.0), v, height, sfunc, cls);
|
nuclear@0
|
737 Vector3 tang = nextu - pos;
|
nuclear@0
|
738 if(tang.length_sq() < 1e-6) {
|
nuclear@0
|
739 float new_v = v > 0.5 ? v - dv * 0.25 : v + dv * 0.25;
|
nuclear@0
|
740 nextu = sweep_vert(fmod(u + du, 1.0), new_v, height, sfunc, cls);
|
nuclear@0
|
741 tang = nextu - pos;
|
nuclear@0
|
742 }
|
nuclear@0
|
743
|
nuclear@0
|
744 Vector3 normal;
|
nuclear@0
|
745 Vector3 nextv = sweep_vert(u, v + dv, height, sfunc, cls);
|
nuclear@0
|
746 Vector3 bitan = nextv - pos;
|
nuclear@0
|
747 if(bitan.length_sq() < 1e-6) {
|
nuclear@0
|
748 nextv = sweep_vert(u, v - dv, height, sfunc, cls);
|
nuclear@0
|
749 bitan = pos - nextv;
|
nuclear@0
|
750 }
|
nuclear@0
|
751
|
nuclear@0
|
752 normal = cross_product(tang, bitan);
|
nuclear@0
|
753
|
nuclear@0
|
754 *varr++ = pos;
|
nuclear@0
|
755 *narr++ = normal.normalized();
|
nuclear@0
|
756 *tarr++ = tang.normalized();
|
nuclear@0
|
757 *uvarr++ = Vector2(u, v);
|
nuclear@0
|
758
|
nuclear@0
|
759 if(i < usub && j < vsub) {
|
nuclear@0
|
760 int idx = i * vverts + j;
|
nuclear@0
|
761
|
nuclear@0
|
762 *idxarr++ = idx;
|
nuclear@0
|
763 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
764 *idxarr++ = idx + 1;
|
nuclear@0
|
765
|
nuclear@0
|
766 *idxarr++ = idx;
|
nuclear@0
|
767 *idxarr++ = idx + vverts;
|
nuclear@0
|
768 *idxarr++ = idx + vverts + 1;
|
nuclear@0
|
769 }
|
nuclear@0
|
770
|
nuclear@0
|
771 v += dv;
|
nuclear@0
|
772 }
|
nuclear@0
|
773 u += du;
|
nuclear@0
|
774 }
|
nuclear@0
|
775 }
|