//Base code for the Catmull-Clark subdivion assignment for cpe 572 //Use a 3d array of Vector3s, 2 dimensions are the surface the third is the level of subdivision //Only supports subdivision up to 4 levels (starts out at level 0) //only draws wireframe and uses aswd camera movement but no rotations //ASSIGNMENT: compute the correct re-positioning of geometric values per level given the Catmull-Clark rules //ZJW 4/29/10 #include #include #include #include #include #include #include #include #include #include using namespace std; /* structure to store a 3d point, note that for this assignment, the vector also stores a level which is used to denote which level of subdivion has been computed on that point (to not displace a point twice), given the data structure we are using */ typedef struct Vector3 { float x; float y; float z; int level; Vector3(float in_x, float in_y, float in_z) : x(in_x), y(in_y), z(in_z), level(0) {} Vector3() : x(0), y(0), z(0), level(0) {} Vector3(const Vector3& in_v) : x(in_v.x), y(in_v.y), z(in_v.z), level(0) {} Vector3(float in) : x(in), y(in), z(in), level(0) {} inline Vector3& operator =(const Vector3& v2) { x = v2.x; y=v2.y; z=v2.z; level =v2.level; return *this;} inline void set(float in_x, float in_y, float in_z) { x = in_x; y = in_y; z = in_z; level = 0;} } Vector3; #define FLT_MIN 1.1754E-38F #define FLT_MAX 1.1754E+38F int GW; int GH; //for camera changes instead Vector3 eye, la; char strPop[256]; //helper functions for working with vectors Vector3 cross(const Vector3& a, const Vector3& b) { Vector3 c; c.x = a.y*b.z - a.z*b.y; c.y = a.z*b.x - a.x*b.z; c.z = a.x*b.y - a.y*b.x; return(c); } float dot(const Vector3& a, const Vector3& b) { return(a.x*b.x + a.y*b.y + a.z*b.z); } float length(const Vector3& a) { return(sqrt(dot(a, a))); } Vector3 normalize(const Vector3& a) { Vector3 u; float mag_a = length(a); u.x = a.x/mag_a; u.y = a.y/mag_a; u.z = a.z/mag_a; return(u); } void PrintVec(const Vector3 v1) { printf("vec: %f %f %f\n", v1.x, v1.y, v1.z); } void renderBitmapCharacher(float x, float y, float z, void *font,char *string) { char *c; glRasterPos3f(x, y,z); for (c=string; *c != '\0'; c++) { glutBitmapCharacter(font, *c); } } //storage for the data points for our Catmull-Clark Subdivision surface (up to 4 levels of subdivision) Vector3 CCSurf[17][17][4]; //Globals for the global extents of the patch int L, R, T, B; int DrawLevel; /*assumes ordering as 3--------2 | | | | 0--------1 */ void InitCCSurf() { int level=0; L=B=0; R=T=16; CCSurf[L][B][level] = Vector3(-1, 0, 1); CCSurf[R][B][level] = Vector3(1, 0, 1); CCSurf[R][T][level] = Vector3(1, 0, -1); CCSurf[L][T][level] = Vector3(-1, 0, -1); //setting center for interesting geometry and edge midpoints - kind of weird CCSurf[(R-L)/2][(T-B)/2][level] = Vector3(0, 1, 0); CCSurf[(R-L)/2][B][level] = Vector3(0, 0, 1); CCSurf[R][(T-B)/2][level] = Vector3(1, 0, 0); CCSurf[(R-L)/2][T][level] = Vector3(0, 0, -1); CCSurf[L][(T-B)/2][level] = Vector3(-1, 0, 0); } /*Routine to draw a given portion of a patch at a given level*/ void DrawPatch(int Lev, int Lft, int Rght, int Bot, int Top) { int i, j, skip; Vector3 v1, v2,norm; skip = (Rght-Lft)/powf(2,(Lev+1)); for (i=Lft; i