Ejemplo n.º 1
0
/**
 * @brief Calculates transformation matrix for the model and its tags
 * @note The transformation matrix is only calculated once
 */
static float* R_CalcTransform (entity_t* e)
{
	transform_t* t;
	float* mp;
	float mt[16], mc[16];

	/* check if this entity is already transformed */
	t = &e->transform;

	if (t->processing)
		Com_Error(ERR_DROP, "Ring in entity transformations!");

	if (t->done)
		return t->matrix;

	/* process this matrix */
	t->processing = true;
	mp = nullptr;

	/* do parent object transformations first */
	if (e->tagent) {
		/* tag transformation */
		const model_t* model = e->tagent->model;
		const mAliasTagOrientation_t* current = nullptr;
		const mAliasTagOrientation_t* old = nullptr;
		const animState_t* as = &e->tagent->as;

		R_GetTags(model, e->tagname, as->frame, as->oldframe, &current, &old);
		if (current != nullptr && old != nullptr) {
			float interpolated[16];

			/* parent transformation */
			mp = R_CalcTransform(e->tagent);

			/* do interpolation */
			R_InterpolateTransform(as->backlerp, model->alias.num_frames, current, old, interpolated);

			/* transform */
			GLMatrixMultiply(mp, interpolated, mt);
			mp = mt;
		}
	}

	GLMatrixAssemble(e->origin, e->angles, mc);

	/* combine transformations */
	if (mp)
		GLMatrixMultiply(mp, mc, t->matrix);
	else
		memcpy(t->matrix, mc, sizeof(float) * 16);

	/* matrix elements 12..14 contain (forward) translation vector, which is also the origin of model after transform */
	e->distanceFromViewOrigin = VectorDist(&t->matrix[12], refdef.viewOrigin);

	/* we're done */
	t->done = true;
	t->processing = false;

	return t->matrix;
}
Ejemplo n.º 2
0
/**
 * @brief Draws a model in 2d mode (for rendering model data from the ui)
 * @param[in,out] mi All the needed model information to render the model
 * @param[in,out] pmi The model information of the parent model. This is used
 * in those cases, where the model that should get rendered here is placed relativly
 * to an already existing model in the world.
 * @param[in] tagname If a parent model is given, a @c tagname is given in most cases, too. It's used
 * to transform the model location relative to the parent model location again. E.g. a
 * @c tagname of tag_rweapon will transform the location to the right hand of an actor.
 * @sa R_DrawAliasModel
 */
void R_DrawModelDirect (modelInfo_t * mi, modelInfo_t * pmi, const char *tagname)
{
	image_t *skin;
	mAliasMesh_t *mesh;

	if (Q_strnull(mi->name))
		return;

	/* register the model */
	mi->model = R_FindModel(mi->name);

	/* check if the model exists */
	if (!mi->model) {
		Com_Printf("No model found for '%s'\n", mi->name);
		return;
	}

	skin = R_AliasModelState(mi->model, &mi->mesh, &mi->frame, &mi->oldframe, &mi->skin);
	if (skin == NULL) {
		Com_Printf("Model '%s' is broken\n", mi->name);
		return;
	}

	glPushMatrix();
	glScalef(viddef.rx, viddef.ry, (viddef.rx + viddef.ry) / 2);

	R_Color(mi->color);

	if (pmi) {
		/* register the parent model */
		pmi->model = R_FindModel(pmi->name);

		/* transform - the next transform for the child model will be relative from the
		 * parent model location now */
		R_TransformModelDirect(pmi);

		/* tag transformation */
		if (tagname) {
			const mAliasTagOrientation_t *current = NULL;
			const mAliasTagOrientation_t *old = NULL;
			R_GetTags(pmi->model, tagname, pmi->frame, pmi->oldframe, &current, &old);
			if (current != NULL && old != NULL) {
				float interpolated[16];

				/* do interpolation */
				R_InterpolateTransform(pmi->backlerp, pmi->model->alias.num_frames, current, old, interpolated);

				/* transform */
				glMultMatrixf(interpolated);
				R_CheckError();
			}
		}
	}

	/* transform */
	R_TransformModelDirect(mi);

	/* we have to reenable this here - we are in 2d mode here already */
	glEnable(GL_DEPTH_TEST);

	/* draw it */
	R_BindTexture(skin->texnum);

	/* draw the model */
	mesh = &mi->model->alias.meshes[0];
	refdef.aliasCount += mesh->num_tris;
	if (mi->model->alias.num_frames == 1)
		R_DrawAliasStaticWithReset(mesh, vec4_origin);
	else
		R_DrawAliasFrameLerp(&mi->model->alias, mesh, mi->backlerp, mi->frame, mi->oldframe, vec4_origin);

	/* show model bounding box */
	if (r_showbox->integer)
		R_DrawBoundingBox(mi->model->alias.frames[mi->frame].mins, mi->model->alias.frames[mi->frame].maxs);

	glDisable(GL_DEPTH_TEST);

	glPopMatrix();

	R_Color(NULL);
}