/* * @brief Loads the model by the specified name. */ r_model_t *R_LoadModel(const char *name) { r_model_t *mod; char key[MAX_QPATH]; size_t i; if (!name || !name[0]) { Com_Error(ERR_DROP, "R_LoadModel: NULL name\n"); } if (*name == '*') { g_snprintf(key, sizeof(key), "%s#%s", r_model_state.world->media.name, name + 1); } else { StripExtension(name, key); } if (!(mod = (r_model_t *) R_FindMedia(key))) { void *buf; const r_model_format_t *format = r_model_formats; for (i = 0; i < lengthof(r_model_formats); i++, format++) { StripExtension(name, key); strcat(key, format->extension); if (Fs_Load(key, &buf) != -1) break; } if (i == lengthof(r_model_formats)) { // not found if (strstr(name, "players/")) { Com_Debug("Failed to load player %s\n", name); } else { Com_Warn("Failed to load %s\n", name); } return NULL; } StripExtension(name, key); mod = (r_model_t *) R_AllocMedia(key, sizeof(r_model_t)); mod->media.Register = R_RegisterModel; mod->media.Free = R_FreeModel; mod->type = format->type; // load the materials first, so that we can resolve surfaces lists R_LoadMaterials(mod); // load it format->Load(mod, buf); // free the file Fs_Free(buf); // assemble vertex buffer objects from static arrays R_LoadVertexBuffers(mod); // calculate an approximate radius from the bounding box vec3_t tmp; VectorSubtract(mod->maxs, mod->mins, tmp); mod->radius = VectorLength(tmp) / 2.0; R_RegisterMedia((r_media_t *) mod); } return mod; }
/* * R_LoadModel */ r_model_t *R_LoadModel(const char *name) { r_model_format_t *format; r_model_t *mod; char n[MAX_QPATH]; void *buf; vec3_t tmp; unsigned short i; if (!name || !name[0]) { Com_Error(ERR_DROP, "R_LoadModel: NULL name."); } // inline models are fetched from a separate array if (name[0] == '*') { i = atoi(name + 1); if (i < 1 || !r_world_model || i >= r_world_model->num_submodels) { Com_Error(ERR_DROP, "R_LoadModel: Bad inline model number."); } return &r_inline_models[i]; } StripExtension(name, n); // search the currently loaded models for (i = 0, mod = r_models; i < r_num_models; i++, mod++) { if (!strcmp(n, mod->name)) return mod; } // find a free model slot spot for (i = 0, mod = r_models; i < r_num_models; i++, mod++) { if (!mod->name[0]) break; // free spot } if (i == r_num_models) { if (r_num_models == MAX_MOD_KNOWN) { Com_Error(ERR_DROP, "R_LoadModel: MAX_MOD_KNOWN reached."); } r_num_models++; } // load the file format = r_model_formats; for (i = 0; i < NUM_MODEL_FORMATS; i++, format++) { StripExtension(name, n); strcat(n, format->name); if (Fs_LoadFile(n, &buf) != -1) break; } if (i == NUM_MODEL_FORMATS) { // not found Com_Warn("R_LoadModel: Failed to load %s.\n", name); return NULL; } StripExtension(n, mod->name); r_load_model = mod; r_load_model->extra_data = R_HunkBegin(); format->load(mod, buf); r_load_model->extra_data_size = R_HunkEnd(r_load_model->extra_data); // assemble vertex buffer objects from static arrays R_LoadVertexBuffers(mod); // calculate an approximate radius from the bounding box VectorSubtract(mod->maxs, mod->mins, tmp); mod->radius = VectorLength(tmp) / 2.0; Fs_FreeFile(buf); return mod; }