Exemple #1
0
/*
 * @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;
}
Exemple #2
0
/*
 * 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;
}