tavli
diff src/meshgen.cc @ 11:a8e26f163f99
poulia
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 27 Jun 2015 08:01:51 +0300 |
parents | 3fcd7b4d631f |
children | ae1c60726c41 |
line diff
1.1 --- a/src/meshgen.cc Fri Jun 26 05:41:18 2015 +0300 1.2 +++ b/src/meshgen.cc Sat Jun 27 08:01:51 2015 +0300 1.3 @@ -485,3 +485,86 @@ 1.4 } 1.5 } 1.6 } 1.7 + 1.8 +static inline Vector3 rev_vert(float u, float v, Vector2 (*rf)(float, float, void*), void *cls) 1.9 +{ 1.10 + Vector2 pos = rf(u, v, cls); 1.11 + 1.12 + float angle = u * 2.0 * M_PI; 1.13 + float x = pos.x * cos(angle); 1.14 + float y = pos.y; 1.15 + float z = pos.x * sin(angle); 1.16 + 1.17 + return Vector3(x, y, z); 1.18 +} 1.19 + 1.20 +// ------ surface of revolution ------- 1.21 +void gen_revol(Mesh *mesh, int usub, int vsub, Vector2 (*rfunc)(float, float, void*), void *cls) 1.22 +{ 1.23 + if(!rfunc) return; 1.24 + if(usub < 3) usub = 3; 1.25 + if(vsub < 1) vsub = 1; 1.26 + 1.27 + mesh->clear(); 1.28 + 1.29 + int uverts = usub + 1; 1.30 + int vverts = vsub + 1; 1.31 + int num_verts = uverts * vverts; 1.32 + 1.33 + int num_quads = usub * vsub; 1.34 + int num_tri = num_quads * 2; 1.35 + 1.36 + Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0); 1.37 + Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0); 1.38 + Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0); 1.39 + Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0); 1.40 + unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0); 1.41 + 1.42 + float du = 1.0 / (float)(uverts - 1); 1.43 + float dv = 1.0 / (float)(vverts - 1); 1.44 + 1.45 + float u = 0.0; 1.46 + for(int i=0; i<uverts; i++) { 1.47 + float v = 0.0; 1.48 + for(int j=0; j<vverts; j++) { 1.49 + Vector3 pos = rev_vert(u, v, rfunc, cls); 1.50 + 1.51 + Vector3 nextu = rev_vert(fmod(u + du, 1.0), v, rfunc, cls); 1.52 + Vector3 tang = nextu - pos; 1.53 + if(tang.length_sq() < 1e-6) { 1.54 + float new_v = v > 0.5 ? v - dv * 0.25 : v + dv * 0.25; 1.55 + nextu = rev_vert(fmod(u + du, 1.0), new_v, rfunc, cls); 1.56 + tang = nextu - pos; 1.57 + } 1.58 + 1.59 + Vector3 nextv = rev_vert(u, v + dv, rfunc, cls); 1.60 + Vector3 bitan = nextv - pos; 1.61 + if(bitan.length_sq() < 1e-6) { 1.62 + nextv = rev_vert(u, v - dv, rfunc, cls); 1.63 + bitan = pos - nextv; 1.64 + } 1.65 + 1.66 + Vector3 normal = cross_product(tang, bitan); 1.67 + 1.68 + *varr++ = pos; 1.69 + *narr++ = normal.normalized(); 1.70 + *tarr++ = tang.normalized(); 1.71 + *uvarr++ = Vector2(u, v); 1.72 + 1.73 + if(i < usub && j < vsub) { 1.74 + int idx = i * vverts + j; 1.75 + 1.76 + *idxarr++ = idx; 1.77 + *idxarr++ = idx + vverts + 1; 1.78 + *idxarr++ = idx + 1; 1.79 + 1.80 + *idxarr++ = idx; 1.81 + *idxarr++ = idx + vverts; 1.82 + *idxarr++ = idx + vverts + 1; 1.83 + } 1.84 + 1.85 + v += dv; 1.86 + } 1.87 + u += du; 1.88 + } 1.89 +}