char ENT_LoadEntity(entity_t* entity, const char* filename, uchar usage) { md5_mesh_t* meshCache = NULL; if (!filename) return 0; //Check mesh cache meshCache = ENT_Get(filename); if (meshCache) { entity->model = meshCache ; //printf("[ENT_LoadEntity] Cache hit MD5 '%s'.\n",filename); } else { entity->model = (md5_mesh_t*)calloc(1,sizeof(md5_mesh_t)) ; if (!MD5_LoadMesh(entity->model,filename)) { free(entity->model); Log_Printf("Unable to load mesh '%s'.\n",filename); return 0; } ENT_Put(entity->model,filename); } entity->usage = usage; entity->material = 0; entity->material = MATLIB_Get(entity->model->materialName); if (!entity->material) { Log_Printf("[ENT_LoadEntity *****ERROR******] Unknown material: '%s'.\n",entity->model->materialName); } if (usage == ENT_PARTIAL_DRAW) { entity->numIndices = entity->model->numIndices; entity->indices = (ushort*)calloc(entity->model->numIndices, sizeof(ushort)) ; memcpy(entity->indices, entity->model->indices, entity->numIndices * sizeof(ushort)); } MATLIB_MakeAvailable(entity->material); renderer.UpLoadEntityToGPU(entity); entity->xAxisRot = 0; entity->yAxisRot = 0; entity->zAxisRot = 0; return 1; }
char OBJ_Load(char* filename,entity_t* entity) { static vec3_t tmpVertices[DE_USHRT_MAX]; ushort num_vertices=0; static vec2_t tmpTextureCoor[DE_USHRT_MAX]; ushort num_textuCoor=0; int idata[9]; int i; ushort indiceOfCurrentVertex; filehandle_t* objFile ; obj_t* obj; objFile = FS_OpenFile(filename, "rt"); if (!objFile) { printf("Could not Load OBJ: '%s'.\n",filename); return 0; } OBJ_InitVerticeCache(); obj = (obj_t*)entity->model; obj->vertices = (obj_vertex_t*)calloc(DE_USHRT_MAX, sizeof(obj_vertex_t)); obj->num_vertices = 0; obj->indices = (ushort*)calloc(DE_USHRT_MAX, sizeof(ushort)); obj->num_indices = 0; LE_pushLexer(); LE_init(objFile); while (LE_hasMoreData()) { LE_readToken(); if (!strcmp("v",LE_getCurrentToken())) { tmpVertices[num_vertices][0] = LE_readReal(); tmpVertices[num_vertices][1] = LE_readReal(); tmpVertices[num_vertices][2] = LE_readReal(); num_vertices++; } else if (!strcmp("vt",LE_getCurrentToken())) { tmpTextureCoor[num_textuCoor][0] = LE_readReal(); tmpTextureCoor[num_textuCoor][1] = 1- LE_readReal(); num_textuCoor++; } else if (!strcmp("vn",LE_getCurrentToken())) { for(i=0;i<3;i++) LE_readReal(); //Drop it (like it's hot) } else if (!strcmp("f",LE_getCurrentToken())) { LE_SetWhiteCharValue('/', 1); for(i=0;i<9;i++) { idata[i] = LE_readReal(); idata[i]--; } #ifdef OBJ_FACE_CCW for(i=0;i<3;i++)//OBJ Standard: Couter-clockwise #else for(i=2;i>=0;i--) //Bugged expoter. #endif { indiceOfCurrentVertex = GetCacheVertex(idata[3*i],tmpTextureCoor[idata[3*i+1]]); //indiceOfCurrentVertex = obj->num_indices; if (indiceOfCurrentVertex+1 > obj->num_vertices) obj->num_vertices = indiceOfCurrentVertex+1; vectorCopy (tmpVertices[idata[3*i]] , obj->vertices[indiceOfCurrentVertex].position); //for(i=0;i<3;i++) //{ // printf("Vertices: %d, %d, %d.\n",obj->vertices[indiceOfCurrentVertex].position[0],obj->vertices[indiceOfCurrentVertex].position[1],obj->vertices[indiceOfCurrentVertex].position[2]); //} vector2Copy(tmpTextureCoor[idata[3*i+1]], obj->vertices[indiceOfCurrentVertex].textCoo); //printf("num_indices = %d, indice pointer=%d\n",obj->num_indices,indiceOfCurrentVertex); obj->indices[obj->num_indices++] = indiceOfCurrentVertex ; } LE_SetWhiteCharValue('/', 0); } else if (!strcmp("usemtl",LE_getCurrentToken())) { LE_readToken(); entity->material = MATLIB_Get(LE_getCurrentToken()); if (entity->material == 0) printf("************[OBJ Loader] Could not find material: '%s'\n",LE_getCurrentToken()); } } LE_popLexer(); FS_CloseFile(objFile); //Adjust size of vertices and indices obj->vertices = realloc(obj->vertices,obj->num_vertices * sizeof(obj_vertex_t)); obj->indices = realloc(obj->indices ,obj->num_indices * sizeof(ushort)); //printf("Obj %s has %d vertices.\n",filename,obj->num_vertices); //printf("Obj %s has %d indices.\n",filename,obj->num_indices); OBJ_DestroyVerticeCache(); //Generate lighting infos. OBJ_GenerateLightingInfo(obj); return 1; }
/** * Load an MD5 model from file. */ int ReadMD5Model (const char *filename, entity_t* entity )//md5_model_t *mdl) { FILE *fp; char buff[512]; int version; int curr_mesh = 0; int i,k,j,w; char* fullPath; md5_mesh_t* mesh; md5_model_t *mdl ; mdl = &((md5_object_t*)entity->model)->md5Model; fullPath = (char*)malloc((strlen(filename)+1+strlen(FS_Gamedir()) + 1) * sizeof(char)); fullPath[0] = '\0'; strcat(fullPath, FS_Gamedir()); strcat(fullPath, "/"); strcat(fullPath,filename); fp = fopen (fullPath, "rb"); if (!fp) { fprintf (stderr, "Error: couldn't open \"%s\"!\n", fullPath); fprintf (stderr, "Error: couldn't open \"%s\"!\n", filename); return 0; } while (!feof (fp)) { /* Read whole line */ fgets (buff, sizeof (buff), fp); if (sscanf (buff, " MD5Version %d", &version) == 1) { if (version != 10) { /* Bad version */ fprintf (stderr, "Error: bad model version\n"); fclose (fp); return 0; } } else if (sscanf (buff, " numJoints %d", &mdl->num_joints) == 1) { if (mdl->num_joints > 0) { /* Allocate memory for base skeleton joints */ mdl->baseSkel = (struct md5_joint_t *) calloc (mdl->num_joints, sizeof (struct md5_joint_t)); } } else if (sscanf (buff, " numMeshes %d", &mdl->num_meshes) == 1) { if (mdl->num_meshes > 0) { /* Allocate memory for meshes */ mdl->meshes = (struct md5_mesh_t *) calloc (mdl->num_meshes, sizeof (struct md5_mesh_t)); } } else if (strncmp (buff, "joints {", 8) == 0) { /* Read each joint */ for (i = 0; i < mdl->num_joints; ++i) { struct md5_joint_t *joint = &mdl->baseSkel[i]; /* Read whole line */ fgets (buff, sizeof (buff), fp); if (sscanf (buff, "%s %d ( %f %f %f ) ( %f %f %f )", joint->name, &joint->parent, &joint->pos[0], &joint->pos[1], &joint->pos[2], &joint->orient[0], &joint->orient[1], &joint->orient[2]) == 8) { /* Compute the w component */ Quat_computeW (joint->orient); } } } else if (strncmp (buff, "mesh {", 6) == 0) { struct md5_mesh_t *mesh = &mdl->meshes[curr_mesh]; int vert_index = 0; int tri_index = 0; int weight_index = 0; float fdata[4]; int idata[3]; mesh->bumpShader[0] = '\0'; while ((buff[0] != '}') && !feof (fp)) { /* Read whole line */ fgets (buff, sizeof (buff), fp); if (strstr (buff, "shader ")) { int quote = 0, j = 0; /* Copy the shader name whithout the quote marks */ for (i = 0; i < sizeof (buff) && (quote < 2); ++i) { if (buff[i] == '\"') quote++; if ((quote == 1) && (buff[i] != '\"')) mesh->shader[j++] = buff[i]; } entity->material = MATLIB_Get(mesh->shader); if (entity->material == 0) printf("[md5Loader] could not laod shader: '%s'\n",mesh->shader); } else if (strstr (buff, "bumpShader ") ) { int quote = 0, j = 0; // Copy the shader name whithout the quote marks for (i = 0; i < sizeof (buff) && (quote < 2); ++i) { if (buff[i] == '\"') quote++; if ((quote == 1) && (buff[i] != '\"')) mesh->bumpShader[j++] = buff[i]; } } else if (sscanf (buff, " numverts %d", &mesh->num_verts) == 1) { if (mesh->num_verts > 0) { /* Allocate memory for vertices */ mesh->vertices = (struct md5_vertex_t *) malloc (sizeof (struct md5_vertex_t) * mesh->num_verts); } } else if (sscanf (buff, " numtris %d", &mesh->num_tris) == 1) { if (mesh->num_tris > 0) { /* Allocate memory for triangles */ mesh->triangles = (struct md5_triangle_t *) malloc (sizeof (struct md5_triangle_t) * mesh->num_tris); } } else if (sscanf (buff, " numweights %d", &mesh->num_weights) == 1) { if (mesh->num_weights > 0) { /* Allocate memory for vertex weights */ mesh->weights = (struct md5_weight_t *) malloc (sizeof (struct md5_weight_t) * mesh->num_weights); } } else if (sscanf (buff, " vert %d ( %f %f ) %d %d", &vert_index, &fdata[0], &fdata[1], &idata[0], &idata[1]) == 5) { /* Copy vertex data */ mesh->vertices[vert_index].st[0] = fdata[0] * 32767; mesh->vertices[vert_index].st[1] = fdata[1] * 32767; mesh->vertices[vert_index].start = idata[0]; mesh->vertices[vert_index].count = idata[1]; } else if (sscanf (buff, " tri %d %d %d %d", &tri_index,&idata[0], &idata[1], &idata[2]) == 4) { /* Copy triangle data */ mesh->triangles[tri_index ].index[2] = idata[0]; mesh->triangles[tri_index ].index[1] = idata[1]; mesh->triangles[tri_index ].index[0] = idata[2]; } else if (sscanf (buff, " weight %d %d %f ( %f %f %f )", &weight_index, &idata[0], &fdata[3], &fdata[0], &fdata[1], &fdata[2]) == 6) { /* Copy vertex data */ mesh->weights[weight_index].joint = idata[0]; mesh->weights[weight_index].bias = fdata[3]; mesh->weights[weight_index].pos[0] = fdata[0]; mesh->weights[weight_index].pos[1] = fdata[1]; mesh->weights[weight_index].pos[2] = fdata[2]; } } curr_mesh++; } } fclose (fp); free(fullPath); //Load all textures for(i = 0 ; i < mdl->num_meshes ; i++) { mesh = &mdl->meshes[i]; mesh->vertexArray = malloc (sizeof (vertex_t) * mesh->num_verts); mesh->vertexIndices = malloc (sizeof (ushort) * mesh->num_tris * 3); /* Setup vertex indices */ for (k = 0, w = 0; w < mesh->num_tris; w++) { for (j = 0; j < 3; j++,k++) mesh->vertexIndices[k] = mesh->triangles[w].index[j]; } } return 1; }