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
00155 cluModelLocalOrigin((CLvertex*)&old_origin, model);
00156
00157
00158 cluNormalDifference(&movement, &old_origin, origin);
00159
00160
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
00220 if (model->num_meshes == 1)
00221 {
00222 printf("%s() - No merging necessary\n", __FUNCTION__);
00223 return model;
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
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
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
00264 for (i = 0 ; i < new_mesh->num_primitivesets ; i++)
00265 {
00266 new_mesh->primitivesets[i] = clDefaultPrimitiveSet(clNewPrimitiveSet());
00267 }
00268
00269
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
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
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
00363
00364
00365
00366
00367
00368
00369
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
00379 model->meshes[0] = new_mesh;
00380
00381
00382 return model;
00383 }
00384