ld33_umonster
changeset 10:1b30bd381667 tip
sweep curve mesh gen and dragon horns
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Thu, 27 Aug 2015 05:25:04 +0300 |
parents | 4f6168f3ca82 |
children | |
files | src/dragon.cc src/meshgen.cc src/meshgen.h |
diffstat | 3 files changed, 144 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- a/src/dragon.cc Thu Aug 27 01:58:26 2015 +0300 1.2 +++ b/src/dragon.cc Thu Aug 27 05:25:04 2015 +0300 1.3 @@ -4,7 +4,9 @@ 1.4 #include "metasurf.h" 1.5 #include "geom.h" 1.6 #include "game.h" 1.7 +#include "object.h" 1.8 #include "shadow.h" 1.9 +#include "meshgen.h" 1.10 1.11 #define VOXEL_PAD 1.0f 1.12 #define DYN_FCOUNT 64 1.13 @@ -19,6 +21,9 @@ 1.14 static Vector3 bezier(const Vector3 &a, const Vector3 &b, const Vector3 &c, const Vector3 &d, float t); 1.15 static float mseval(struct metasurface *ms, float x, float y, float z); 1.16 static void msvertex(struct metasurface *ms, float x, float y, float z); 1.17 +static void gen_detail_meshes(); 1.18 + 1.19 +static std::vector<Object*> detail_obj; 1.20 1.21 1.22 Dragon::Dragon() 1.23 @@ -48,6 +53,10 @@ 1.24 msurf_set_threshold(msurf, 1.0); 1.25 msurf_eval_func(msurf, mseval); 1.26 msurf_vertex_func(msurf, msvertex); 1.27 + 1.28 + if(detail_obj.empty()) { 1.29 + gen_detail_meshes(); 1.30 + } 1.31 } 1.32 1.33 Dragon::~Dragon() 1.34 @@ -214,6 +223,17 @@ 1.35 glPopAttrib(); 1.36 if(cur_sdr) glUseProgram(cur_sdr); 1.37 } 1.38 + 1.39 + // draw detail objects 1.40 + for(size_t i=0; i<detail_obj.size(); i++) { 1.41 + detail_obj[i]->xform().set_translation(head_pos); 1.42 + 1.43 + if(dbg_wireframe) { 1.44 + detail_obj[i]->draw_wire(); 1.45 + } else { 1.46 + detail_obj[i]->draw(); 1.47 + } 1.48 + } 1.49 } 1.50 1.51 void Dragon::flush_dynvbo() const 1.52 @@ -290,3 +310,40 @@ 1.53 dragon->flush_dynvbo(); 1.54 } 1.55 } 1.56 + 1.57 + 1.58 +#define HORN_RAD 0.15f 1.59 +static Vector2 horn_sweep(float u, float v, void *cls) 1.60 +{ 1.61 + float t = 1.0f - v; 1.62 + float angle = u * 2.0 * M_PI; 1.63 + float x = sin(angle) * t * HORN_RAD; 1.64 + float y = cos(angle) * t * HORN_RAD; 1.65 + return Vector2(x, y + smoothstep(0.3, 1.0, v) * 0.5); 1.66 +} 1.67 + 1.68 +static void gen_detail_meshes() 1.69 +{ 1.70 + Mesh *mesh; 1.71 + Object *obj; 1.72 + Matrix4x4 xform; 1.73 + 1.74 + for(int i=0; i<2; i++) { 1.75 + float sign = i ? 1.0f : -1.0f; 1.76 + 1.77 + mesh = new Mesh; 1.78 + gen_sweep(mesh, 2, 6, 6, horn_sweep, 0); 1.79 + xform.set_translation(Vector3(0.5 * sign, 1.5, 3)); 1.80 + xform.rotate(Vector3(DEG_TO_RAD(25), 0, 0)); 1.81 + xform.rotate(Vector3(0, 0, DEG_TO_RAD(15) * -sign)); 1.82 + mesh->apply_xform(xform, Matrix4x4::identity); 1.83 + 1.84 + obj = new Object; 1.85 + obj->set_mesh(mesh); 1.86 + obj->mtl.diffuse = Vector3(1.0, 0.85, 0.8); 1.87 + obj->mtl.specular = Vector3(1, 1, 1); 1.88 + obj->mtl.shininess = 60.0; 1.89 + 1.90 + detail_obj.push_back(obj); 1.91 + } 1.92 +}
2.1 --- a/src/meshgen.cc Thu Aug 27 01:58:26 2015 +0300 2.2 +++ b/src/meshgen.cc Thu Aug 27 05:25:04 2015 +0300 2.3 @@ -689,3 +689,87 @@ 2.4 u += du; 2.5 } 2.6 } 2.7 + 2.8 + 2.9 +static inline Vector3 sweep_vert(float u, float v, float height, Vector2 (*sf)(float, float, void*), void *cls) 2.10 +{ 2.11 + Vector2 pos = sf(u, v, cls); 2.12 + 2.13 + float x = pos.x; 2.14 + float y = v * height; 2.15 + float z = pos.y; 2.16 + 2.17 + return Vector3(x, y, z); 2.18 +} 2.19 + 2.20 +// ---- sweep shape along a path ---- 2.21 +void gen_sweep(Mesh *mesh, float height, int usub, int vsub, Vector2 (*sfunc)(float, float, void*), void *cls) 2.22 +{ 2.23 + if(!sfunc) return; 2.24 + if(usub < 3) usub = 3; 2.25 + if(vsub < 1) vsub = 1; 2.26 + 2.27 + mesh->clear(); 2.28 + 2.29 + int uverts = usub + 1; 2.30 + int vverts = vsub + 1; 2.31 + int num_verts = uverts * vverts; 2.32 + 2.33 + int num_quads = usub * vsub; 2.34 + int num_tri = num_quads * 2; 2.35 + 2.36 + Vector3 *varr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_VERTEX, 3, num_verts, 0); 2.37 + Vector3 *narr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_NORMAL, 3, num_verts, 0); 2.38 + Vector3 *tarr = (Vector3*)mesh->set_attrib_data(MESH_ATTR_TANGENT, 3, num_verts, 0); 2.39 + Vector2 *uvarr = (Vector2*)mesh->set_attrib_data(MESH_ATTR_TEXCOORD, 2, num_verts, 0); 2.40 + unsigned int *idxarr = mesh->set_index_data(num_tri * 3, 0); 2.41 + 2.42 + float du = 1.0 / (float)(uverts - 1); 2.43 + float dv = 1.0 / (float)(vverts - 1); 2.44 + 2.45 + float u = 0.0; 2.46 + for(int i=0; i<uverts; i++) { 2.47 + float v = 0.0; 2.48 + for(int j=0; j<vverts; j++) { 2.49 + Vector3 pos = sweep_vert(u, v, height, sfunc, cls); 2.50 + 2.51 + Vector3 nextu = sweep_vert(fmod(u + du, 1.0), v, height, sfunc, cls); 2.52 + Vector3 tang = nextu - pos; 2.53 + if(tang.length_sq() < 1e-6) { 2.54 + float new_v = v > 0.5 ? v - dv * 0.25 : v + dv * 0.25; 2.55 + nextu = sweep_vert(fmod(u + du, 1.0), new_v, height, sfunc, cls); 2.56 + tang = nextu - pos; 2.57 + } 2.58 + 2.59 + Vector3 normal; 2.60 + Vector3 nextv = sweep_vert(u, v + dv, height, sfunc, cls); 2.61 + Vector3 bitan = nextv - pos; 2.62 + if(bitan.length_sq() < 1e-6) { 2.63 + nextv = sweep_vert(u, v - dv, height, sfunc, cls); 2.64 + bitan = pos - nextv; 2.65 + } 2.66 + 2.67 + normal = cross_product(tang, bitan); 2.68 + 2.69 + *varr++ = pos; 2.70 + *narr++ = normal.normalized(); 2.71 + *tarr++ = tang.normalized(); 2.72 + *uvarr++ = Vector2(u, v); 2.73 + 2.74 + if(i < usub && j < vsub) { 2.75 + int idx = i * vverts + j; 2.76 + 2.77 + *idxarr++ = idx; 2.78 + *idxarr++ = idx + vverts + 1; 2.79 + *idxarr++ = idx + 1; 2.80 + 2.81 + *idxarr++ = idx; 2.82 + *idxarr++ = idx + vverts; 2.83 + *idxarr++ = idx + vverts + 1; 2.84 + } 2.85 + 2.86 + v += dv; 2.87 + } 2.88 + u += du; 2.89 + } 2.90 +}
3.1 --- a/src/meshgen.h Thu Aug 27 01:58:26 2015 +0300 3.2 +++ b/src/meshgen.h Thu Aug 27 05:25:04 2015 +0300 3.3 @@ -16,4 +16,7 @@ 3.4 void gen_revol(Mesh *mesh, int usub, int vsub, Vector2 (*rfunc)(float, float, void*), void *cls = 0); 3.5 void gen_revol(Mesh *mesh, int usub, int vsub, Vector2 (*rfunc)(float, float, void*), Vector2 (*nfunc)(float, float, void*), void *cls); 3.6 3.7 +/* callback args: (float u, float v, void *cls) -> Vector2 XZ offset u,v in [0, 1] */ 3.8 +void gen_sweep(Mesh *mesh, float height, int usub, int vsub, Vector2 (*sfunc)(float, float, void*), void *cls = 0); 3.9 + 3.10 #endif // MESHGEN_H_