clumodel.c

00001 #include <clu.h>
00002 
00003 CLmodel*   cluModelGenerateNormals(CLmodel* model)
00004 {
00005   GLuint i;
00006 
00007   for (i = 0; i < model->num_meshes; i++)
00008     cluMeshGenerateNormals(model->meshes[i]);
00009   
00010   return model;
00011 }
00012 
00013 CLmodel*   cluModelRemoveUnusedVertices(CLmodel* model)
00014 {
00015   GLuint i;
00016 
00017   for (i = 0; i < model->num_meshes; i++)
00018     cluMeshRemoveUnusedVertices(model->meshes[i]);
00019 
00020   return model;
00021 }
00022 
00023 GLfloat    cluModelWidth(CLmodel* model)
00024 {
00025   GLuint i;
00026   GLuint j;
00027   CLmesh* mesh;
00028   GLfloat min_x;
00029   GLfloat max_x;
00030 
00031   min_x = MAXFLOAT;
00032   max_x = -MAXFLOAT;
00033   
00034   for (i = 0 ; i < model->num_meshes; i++)
00035     {
00036       mesh = model->meshes[i];
00037       
00038       for (j = 0 ; j < mesh->num_vertices ; j++)
00039         {
00040           max_x = CL_MAX(max_x, mesh->vertices[j].x);
00041           min_x = CL_MIN(min_x, mesh->vertices[j].x);
00042         }
00043     }
00044 
00045   return max_x - min_x;
00046 }
00047 
00048 GLfloat cluModelHeight(CLmodel* model)
00049 {
00050   GLuint i;
00051   GLuint j;
00052   CLmesh* mesh;
00053   GLfloat min_y;
00054   GLfloat max_y;
00055 
00056   min_y = MAXFLOAT;
00057   max_y = -MAXFLOAT;
00058   
00059   for (i = 0 ; i < model->num_meshes; i++)
00060     {
00061       mesh = model->meshes[i];
00062       
00063       for (j = 0 ; j < mesh->num_vertices ; j++)
00064         {
00065           max_y = CL_MAX(max_y, mesh->vertices[j].y);
00066           min_y = CL_MIN(min_y, mesh->vertices[j].y);
00067         }
00068     }
00069 
00070   return max_y - min_y;
00071 }
00072 
00073 GLfloat cluModelDepth(CLmodel* model)
00074 {
00075   GLuint i;
00076   GLuint j;
00077   CLmesh* mesh;
00078   GLfloat min_z;
00079   GLfloat max_z;
00080 
00081   min_z = MAXFLOAT;
00082   max_z = -MAXFLOAT;
00083   
00084   for (i = 0 ; i < model->num_meshes; i++)
00085     {
00086       mesh = model->meshes[i];
00087       
00088       for (j = 0 ; j < mesh->num_vertices ; j++)
00089         {
00090           max_z = CL_MAX(max_z, mesh->vertices[j].z);
00091           min_z = CL_MIN(min_z, mesh->vertices[j].z);
00092         }
00093     }
00094 
00095   return max_z - min_z;
00096 }
00097 
00098 CLvertex* cluModelLocalOrigin(CLvertex* v, const CLmodel* model)
00099 {
00100   GLuint i;
00101   GLuint j;
00102   CLmesh* mesh;
00103   GLfloat min_x;
00104   GLfloat max_x;  
00105   GLfloat min_y;
00106   GLfloat max_y;
00107   GLfloat min_z;
00108   GLfloat max_z;
00109 
00110   min_x = MAXFLOAT;
00111   max_x = -MAXFLOAT;
00112   min_y = MAXFLOAT;
00113   max_y = -MAXFLOAT;
00114   min_z = MAXFLOAT;
00115   max_z = -MAXFLOAT;
00116 
00117   for (i = 0 ; i < model->num_meshes; i++)
00118     {
00119       mesh = model->meshes[i];
00120       
00121       for (j = 0; j < mesh->num_vertices; j++)
00122         {
00123           min_x = CL_MIN(min_x, mesh->vertices[j].x);
00124           max_x = CL_MAX(max_x, mesh->vertices[j].x);
00125           min_y = CL_MIN(min_y, mesh->vertices[j].y);
00126           max_y = CL_MAX(max_y, mesh->vertices[j].y);
00127           min_z = CL_MIN(min_z, mesh->vertices[j].z);
00128           max_z = CL_MAX(max_z, mesh->vertices[j].z);
00129         }
00130     }
00131 
00132   v->x = min_x + (max_x - min_x) / 2.0f;
00133   v->y = min_y + (max_y - min_y) / 2.0f;
00134   v->z = min_z + (max_z - min_z) / 2.0f;
00135       
00136   return v;
00137 }
00138 
00139 CLmodel* cluModelCentre(CLmodel* model)
00140 {
00141   CLvertex v;
00142 
00143   return cluModelSetOrigin(model, cluSetVertex(&v, 0.0f, 0.0f, 0.0f));
00144 }
00145 
00146 CLmodel*   cluModelSetOrigin(CLmodel* model, const CLvertex* origin)
00147 {
00148     unsigned int i;
00149     unsigned int j;
00150     CLmesh* mesh;
00151     CLvertex old_origin;
00152     CLnormal movement;
00153 
00154     /* find the models current origin */
00155     cluModelLocalOrigin((CLvertex*)&old_origin, model);
00156 
00157     /* find distance to move */
00158     cluNormalDifference(&movement, &old_origin, origin);
00159 
00160     /* move every vertex from every mesh */
00161     for (i = 0 ; i < model->num_meshes; i++)
00162     {
00163         mesh = model->meshes[i];
00164         
00165         for (j = 0; j < mesh->num_vertices; j++)
00166         {
00167             cluVertexSubtract(mesh->vertices + j, &movement);
00168         }
00169     }
00170     
00171     return model;
00172 }
00173 
00174 CLmodel* cluModelScaleUnitCube(CLmodel* model)
00175 {
00176   return cluModelScale(model, 
00177                        1.0f / (CL_MAX(cluModelWidth(model), 
00178                                       CL_MAX(cluModelHeight(model), 
00179                                              cluModelDepth(model)))));
00180 }
00181 
00182 CLmodel* cluModelScale(CLmodel* model, GLfloat scale)
00183 {
00184   unsigned int i;
00185 
00186   for (i = 0 ; i < model->num_meshes; i++)
00187     cluMeshScale(model->meshes[i], scale);
00188       
00189   return model;
00190 }
00191 
00192 CLmodel* cluModelResize(CLmodel* model, GLfloat sx, GLfloat sy, GLfloat sz)
00193 {
00194   unsigned int i;
00195 
00196   for (i = 0 ; i < model->num_meshes; i++)
00197     cluMeshResize(model->meshes[i], sx, sy, sz);
00198 
00199   return model;
00200 }
00201 
00205 CLmodel* cluModelMergeMeshes(CLmodel* model)
00206 {
00207     unsigned int i = 0;
00208     unsigned int j = 0;
00209     unsigned int k = 0;
00210     unsigned int num_vertices_count = 0;
00211     unsigned int primitivesets_count = 0;
00212     CLmesh* new_mesh = 0;
00213     
00214     GLboolean any_colours = GL_FALSE;
00215     GLboolean any_normals = GL_FALSE;
00216     GLboolean any_texcoords = GL_FALSE;
00217     GLboolean any_edgeflags = GL_FALSE;
00218     
00219     /* exit straight away if no merging is necessary */
00220     if (model->num_meshes == 1)
00221     {
00222         printf("%s() - No merging necessary\n", __FUNCTION__);
00223         return model;
00224     }
00225     
00226     /* 
00227        count the total num_vertices and primitive sets
00228        
00229        also keep track of whether any colours, normals, texcoords or edgeflags are present.
00230        if they are present for one mesh, then to keep the data we need to malloc space for all meshes
00231        
00232        put null values in the spots without data
00233     */
00234     
00235     for (i = 0 ; i < model->num_meshes ; i++)
00236     {
00237         num_vertices_count += model->meshes[i]->num_vertices;
00238         primitivesets_count += model->meshes[i]->num_primitivesets;
00239         
00240         any_colours = any_colours || model->meshes[i]->colours;
00241         any_normals = any_normals || model->meshes[i]->normals;
00242         any_texcoords = any_texcoords || model->meshes[i]->texcoords;
00243         any_edgeflags = any_edgeflags || model->meshes[i]->edgeflags;
00244     }
00245     
00246     /* make a new mesh with space for all of them */
00247     new_mesh = clDefaultMesh(clNewMesh());
00248     new_mesh->num_vertices = num_vertices_count;
00249     new_mesh->vertices = (CLvertex*)malloc(num_vertices_count * sizeof(CLvertex));
00250     
00251     if (any_colours)
00252         new_mesh->colours = (CLcolour*)malloc(num_vertices_count * sizeof(CLcolour));
00253     if (any_normals)
00254         new_mesh->normals = (CLnormal*)malloc(num_vertices_count * sizeof(CLnormal));
00255     if (any_texcoords)
00256         new_mesh->texcoords = (CLtexcoord*)malloc(num_vertices_count * sizeof(CLtexcoord));
00257     if (any_edgeflags)
00258         new_mesh->edgeflags = (CLedgeflag*)malloc(num_vertices_count * sizeof(CLedgeflag));
00259     
00260     new_mesh->num_primitivesets = primitivesets_count;
00261     new_mesh->primitivesets = (CLprimitiveset**)malloc(primitivesets_count * sizeof(CLprimitiveset*));
00262     
00263     /* malloc the primitive sets ready for copying later */
00264     for (i = 0 ; i < new_mesh->num_primitivesets ; i++)
00265     {
00266         new_mesh->primitivesets[i] = clDefaultPrimitiveSet(clNewPrimitiveSet());
00267     }
00268     
00269     /* copy vertices and others into new mesh */
00270     num_vertices_count = 0;
00271     
00272     for (i = 0 ; i < model->num_meshes ; i++)
00273     {
00274         memcpy(new_mesh->vertices + num_vertices_count, model->meshes[i]->vertices, model->meshes[i]->num_vertices * sizeof(CLvertex));
00275         
00276         if (any_colours)
00277         {
00278             if (model->meshes[i]->colours)
00279             {
00280                 memcpy(new_mesh->colours + num_vertices_count, model->meshes[i]->colours, model->meshes[i]->num_vertices * sizeof(CLcolour));
00281             }
00282             else
00283             {
00284                 for (j = 0 ; j < model->meshes[i]->num_vertices ; j++)
00285                 {
00286                     clDefaultColour(new_mesh->colours + num_vertices_count + j);
00287                 }
00288             }
00289         }
00290         
00291         if (any_normals)
00292         {
00293             if (model->meshes[i]->normals)
00294             {
00295                 memcpy(new_mesh->normals + num_vertices_count, model->meshes[i]->normals, model->meshes[i]->num_vertices * sizeof(CLnormal));
00296             }
00297             else
00298             {
00299                 for (j = 0 ; j < model->meshes[i]->num_vertices ; j++)
00300                 {
00301                     clDefaultNormal(new_mesh->normals + num_vertices_count + j);
00302                 }
00303             }
00304         }
00305         
00306         if (any_texcoords)
00307         {
00308             if (model->meshes[i]->texcoords)
00309             {
00310                 memcpy(new_mesh->texcoords + num_vertices_count, model->meshes[i]->texcoords, model->meshes[i]->num_vertices * sizeof(CLtexcoord));
00311             }
00312             else
00313             {
00314                 for (j = 0 ; j < model->meshes[i]->num_vertices ; j++)
00315                 {
00316                     clDefaultTexCoord(new_mesh->texcoords + num_vertices_count + j);
00317                 }
00318             }
00319         }
00320         
00321         if (any_edgeflags)
00322         {
00323             if (model->meshes[i]->edgeflags)
00324             {
00325                 memcpy(new_mesh->edgeflags + num_vertices_count, model->meshes[i]->edgeflags, model->meshes[i]->num_vertices * sizeof(CLedgeflag));
00326             }
00327             else
00328             {
00329                 for (j = 0 ; j < model->meshes[i]->num_vertices ; j++)
00330                 {
00331                     clDefaultEdgeFlag(new_mesh->edgeflags + num_vertices_count + j);
00332                 }
00333             }
00334         }
00335         
00336         num_vertices_count += model->meshes[i]->num_vertices;
00337     }
00338     
00339     /* copy primitive sets into new mesh */
00340     primitivesets_count = 0;
00341     num_vertices_count = 0;
00342     for (i = 0 ; i < model->num_meshes ; i++)
00343     {
00344         for (j = 0 ; j < model->meshes[i]->num_primitivesets ; j++)
00345         {
00346             new_mesh->primitivesets[primitivesets_count]->mode = model->meshes[i]->primitivesets[j]->mode;
00347             new_mesh->primitivesets[primitivesets_count]->num_indices = model->meshes[i]->primitivesets[j]->num_indices;
00348             new_mesh->primitivesets[primitivesets_count]->indices = (GLuint*)malloc(model->meshes[i]->primitivesets[j]->num_indices * sizeof(GLuint));
00349             memcpy(new_mesh->primitivesets[primitivesets_count]->indices, model->meshes[i]->primitivesets[j]->indices, model->meshes[i]->primitivesets[j]->num_indices * sizeof(GLuint));
00350 
00351             for (k = 0 ; k < new_mesh->primitivesets[primitivesets_count]->num_indices ; k++)
00352             {
00353                 /* printf("adding %u to index\n", num_vertices_count); */
00354                 new_mesh->primitivesets[primitivesets_count]->indices[k] += num_vertices_count;
00355             }
00356             primitivesets_count++;
00357         }
00358 
00359         num_vertices_count += model->meshes[i]->num_vertices;   
00360     }
00361     
00362     /* copy one material et al from old mesh to new */
00363     /*
00364       new_mesh->material_index = model->meshes[0]->material_index;
00365       new_mesh->texture_index = model->meshes[0]->texture_index;
00366       new_mesh->texture_env_mode = model->meshes[0]->texture_env_mode;
00367     */
00368 
00369     /* delete old meshes */
00370     for (i = 0 ; i < model->num_meshes ; i++)
00371     {
00372         clDeleteMesh(model->meshes[i]);
00373     }
00374     
00375     model->num_meshes = 1;
00376     model->meshes = (CLmesh**)realloc(model->meshes, sizeof(CLmesh*));
00377     
00378     /* point model to new mesh and vice versa */
00379     model->meshes[0] = new_mesh;
00380     /* what here ? */
00381 
00382     return model;
00383 }
00384 

Generated on Thu Dec 27 13:53:42 2007 for CLU by  doxygen 1.4.6