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_