00001 /* 00002 Sebastien Loisel's Toolchest 00003 Copyright (C) 1998 Sebastien Loisel 00004 00005 $Header: /home/gtc/public_html/gtc-cvs/toolchest/include/gtcmesh.h,v 1.11 2000/06/25 05:11:52 loisel Exp $ 00006 */ 00007 00027 /* Meshes! */ 00028 00029 #ifndef Z_BASEMESH_H 00030 #define Z_BASEMESH_H 00031 00032 #include <gtcutils.h> 00033 00034 /* gtcSimpleMesh: a 3d graphical mesh. 00035 This holds all the information that GTC needs to draw a textured mesh 00036 with vertex normals and all that. A special feature is also the vertex 00037 weights. The crucial API function is gtc_put_simple_mesh. If you fill in the 00038 various fields properly, you won't need any function but 00039 gtc_put_mesh() (and 00040 some OpenGL setup code). Here is a description of all the entries of the 00041 struct and what gtc_put_mesh does with it. 00042 00043 name: This field isn't used by gtc_put_mesh but is useful to have around for 00044 some of the mesh loading facilities (more specifically, the .asc and .ase 00045 import functions). 00046 00047 v: vertices, an array of gtcReal[3] -- each vertex is given an x, y and z 00048 coordinate. 00049 00050 n: normals, an array of gtcReal[3] -- each vertex is given a normal, and 00051 this is the (x,y,z) coordinates of a given vertex's normal. If this pointer 00052 is zero, normals aren't sent to OpenGL. 00053 00054 t: texture coordinates, an array of gtcReal[3] -- each vertex is given 00055 some texture coordinates. If the pointer is zero, texture coordinates are 00056 not sent to OpenGL. 00057 00058 w: weights: an array of gtcReal[numw]. This is for skeleton animations. 00059 In a skeleton animation, each bone is represented by an affine transform. 00060 Each vertex is affected by one or more bones. If there are n bones, there 00061 are n affine transforms, A[0] through A[n-1], that can affect a vertex v. 00062 The net affine transform affecting vertex v[k] is given by the formula 00063 A = w[k][0]*A[0] + w[k][1]*A[1] + ... + w[k][n-1]*A[n-1]. 00064 That is, with the above A, the transformed vertex v will be Av. 00065 00066 f: face index. The k_th triangle of the mesh is (f[k][0],f[k][1],f[k][2]), 00067 these three integers tell you which vertices to use to form that triangle. 00068 To use backface culling, try to orient these properly. 00069 00070 numf: number of faces. 00071 00072 numv: number of vertices. 00073 00074 numw: number of weights. If zero, there's one affine transform and the 00075 weight is one for all vertices. This is the fast path (if the hardware 00076 supports it, this has a shot at being hardware accelerated and transformed 00077 by the hardware geometry engine). If there are weights, unless some 00078 geometry accelerated card manufacturer puts in an extension for this 00079 precise purpose, the vertices have to be transformed in software. 00080 00081 texid: a texture id. If zero, unused, otherwise, this is the OpenGL texture 00082 id to use for the mesh. Note there's only one texture per gtcSimpleMesh. 00083 00084 Note. If a vertex is transformed by a 3x3 matrix A then its normal needs 00085 to be transformed by (A^-1)' (' is transpose). Sadly, there's a matrix 00086 inverse in that computation. If every vertex is transformed through the 00087 same matrix, that's ok. If every vertex is transformed through a different 00088 matrix (as is the case when weights are used), that would involve one 00089 matrix inversion per vertex, which is expensive. An approximation is used. 00090 */ 00091 00102 typedef struct 00103 { 00105 char *name; 00107 gtcReal (*v)[3]; 00109 gtcReal (*n)[3]; 00111 gtcReal (*t)[2]; 00113 gtcReal *w; 00115 int (*f)[3]; 00117 int numf, 00119 numv, 00121 numw, 00123 texid; 00124 } gtcSimpleMesh; 00125 00126 /* gtc_put_simple_mesh_wremap: puts the mesh to the screen. The matrices 00127 are sent by pointer, that is, A[0] is a pointer to the first matrix, 00128 A[1] a pointer to the second, etc... If m->numw=1, you only need to 00129 send a single matrix. An[k] needs to point to a matrix whose linear part is 00130 equal to (A[k]^-1)' where the apostrophe denotes the matrix transpose. This 00131 functions will never use hardware geometry transform -- the vertices and 00132 normals are transformed in software. Don't use this function if m->numw=0. 00133 */ 00134 00136 void gtc_put_mesh(int f[][3], gtcReal v[][3], gtcReal n[][3], int texid, 00137 gtcReal t[][2], int numf); 00143 void gtc_put_simple_mesh_wremap(gtcSimpleMesh *m, gtcReal (*A[])[4][4], 00144 gtcReal (*An[])[4][4]); 00154 void gtc_put_simple_mesh(gtcSimpleMesh *m, gtcReal A[][4][4]); 00156 typedef gtcReal (*I_dont_know_all_I_need_to_know)[4][4]; 00158 I_dont_know_all_I_need_to_know gtc_prep_An(int numw, gtcReal A[][4][4]); 00160 void gtc_put_simple_mesh_easy(gtcSimpleMesh *m, gtcReal A[4][4]); 00161 00163 void gtc_normalize_mesh(gtcReal v[][3], int numv); 00165 void gtc_normalize_simple_mesh(gtcSimpleMesh *m); 00166 00168 gtcSimpleMesh *gtc_simple_mesh_new(char *name, int numf, int numv); 00170 gtcSimpleMesh *gtc_simple_mesh_tex_new(char *name, int numf, int numv); 00172 gtcSimpleMesh *gtc_simple_mesh_w_new(char *name, int numf, int numv, int numw); 00174 gtcSimpleMesh *gtc_simple_mesh_wtex_new(char *name, int numf, 00175 int numv, int numw); 00177 void gtc_simple_texcoord(gtcSimpleMesh *m); 00179 void gtc_simple_mesh_free(gtcSimpleMesh *m); 00180 00181 /* Basic vector functionality here */ 00183 gtcReal gtc_dot(gtcReal a[], gtcReal b[], int n); /* dot product */ 00185 void gtc_cross(gtcReal a[3], gtcReal b[3], gtcReal r[3]); /* cross product */ 00187 void gtc_add(gtcReal a[], gtcReal b[], gtcReal r[], int n); /* vector addition */ 00189 void gtc_sub(gtcReal a[], gtcReal b[], gtcReal r[], int n); /* difference */ 00191 gtcReal gtc_norm(gtcReal a[], int n); /* norm */ 00193 void gtc_addscale(gtcReal s, gtcReal a[], gtcReal r[], int n); 00194 /* add and scale: r+=s*a; */ 00196 void gtc_zero(gtcReal z[], int n); /* zeroes the vector */ 00198 void gtc_copy(gtcReal a[], gtcReal r[], int n); /* copies the vector */ 00199 00200 /* Setting normals */ 00202 void gtc_cum_face(int f[3], gtcReal v[][3], gtcReal n[][3]); 00203 /* Adds a face's normal (properly scaled) to its vertices */ 00205 void gtc_set_normals(int f[][3], gtcReal v[][3], gtcReal n[][3], 00206 int numf, int numv); /* Set all vertex normals. */ 00207 00209 void gtc_make_face(int f[], int a, int b, int c); 00210 /* This one takes four vertices and spits back a mesh of the tetrahedron 00211 of these four vertices. */ 00213 void gtc_tetrahedron(gtcReal v[4][3], int f[4][3]); 00214 00216 void gtc_simple_GL_setup(void); 00217 /* Before calling putmesh, you should set up GL so that it understands what 00218 you're saying. This function does exactly that, for a simple example 00219 with some lights. */ 00220 00221 /* gtc_GL_setup: I know I'm against wrappers but this one was very useful 00222 so I made it anyway. You tell it if you want the various options 00223 (GL_NORMALIZE, GL_SMOOTH, GL_LIGHTING, GL_CULL) by passing a 1 (for yes) 00224 or a zero (for no) in the appropriate parameter. near, far are the near 00225 and far clipping planes. fov is the (vertical) field of vision in degrees, 00226 the horizontal field of vision is computed from the vertical one, the 00227 width of the viewport and assuming that the aspect ratio is 1:1. if 00228 clear==1 then it will also call glClear. */ 00253 void gtc_GL_setup(int normalize, int smooth, int lighting, int cull, int clear, 00254 gtcReal near, gtcReal far, gtcReal fov, gtcReal w_div_h); 00255 /* gtc_GL_setupall: calls gtc_GL_setup with all options and reasonable near, 00256 far, fov. */ 00258 void gtc_GL_setupall(gtcReal w_div_h); 00259 00260 #if 0 00261 int gtctricollide(gtcvec u1, gtcvec u2, gtcvec u3, 00262 gtcvec v1, gtcvec v2, gtcvec v3); 00263 #endif 00264 00265 /* Mesh transform */ 00267 void gtc_apply(gtcReal A[4][4], gtcReal v[3], gtcReal r[3]); 00268 /* transform a single vector */ 00270 void gtc_xform_pos(gtcReal A[4][4], gtcReal v[][3], gtcReal r[][3], int numv); 00272 void gtc_combine(gtcReal a[4][4], gtcReal b[4][4], gtcReal r[4][4]); 00273 /* affine group multiplication */ 00275 void gtc_rot(gtcReal x, gtcReal y, gtcReal z, gtcReal theta, gtcReal R[4][4]); 00276 /* generates a rotation about (x,y,z) by theta (in radians). */ 00278 void gtc_redress(gtcReal r[4][4]); 00280 void gtc_xlat(gtcReal x, gtcReal y, gtcReal z, gtcReal T[4][4]); 00281 /* makes a translation */ 00283 void gtc_ident(gtcReal I[4][4]); /* returns the identity */ 00285 void gtcaffinecopy(gtcReal A[4][4], gtcReal R[4][4]); /* copies */ 00287 gtcReal gtc_determinant_3(gtcReal A[4][4]); 00288 /* Computes the determinant of the 3x3 linear transform */ 00290 void gtc_invert(gtcReal A[4][4], gtcReal R[4][4]); /* inverses */ 00292 int gtc_check_ortho(gtcReal A[4][4], gtcReal epsilon); 00293 /* Checks if the linear part of A is orthogonal. Tolerance epsilon. */ 00295 int gtc_check_rot(gtcReal A[4][4], gtcReal epsilon); 00296 /* Checks if the linear part of A is a rotation 00297 (=orthogonal of determinant 1). */ 00298 00300 char *gtc_first_tok(char *s); 00302 char *gtc_next_tok(char *s); 00303 00304 /* Quaternions. Quaternions can be used to represent rotations. If 00305 a matrix is not a rotation then do not try to convert it to a 00306 quaternion, you'll get garbage. To check if a matrix is a rotation, 00307 use gtc_check_rot above. */ 00308 00310 void gtc_quaternion_to_matrix(gtcReal Q[4], gtcReal M[4][4]); 00312 void gtc_matrix_to_quaternion(gtcReal M[4][4], gtcReal Q[4]); 00313 00315 gtcSimpleMesh *gtc_stars(void); 00316 00317 #endif 00318
1.2.8.1 written by Dimitri van Heesch,
© 1997-2001