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 +}