コード例 #1
0
ファイル: r_entity.cpp プロジェクト: AresAndy/ufoai
/**
 * @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;
}
コード例 #2
0
/**
 * @brief Calculates the muzzle for the current weapon the actor is shooting with
 * @param[in] actor The actor that is shooting. Might not be @c nullptr
 * @param[out] muzzle The muzzle vector to spawn the particle at. Might not be @c nullptr. This is not
 * modified if there is no tag for the muzzle found for the weapon or item the actor has
 * in the hand (also see the given shoot type)
 * @param[in] shootType The shoot type to determine which tag of the actor should be used
 * to resolve the world coordinates. Also used to determine which item (or better which hand)
 * should be used to resolve the actor's item.
 */
static void CL_ActorGetMuzzle (const le_t* actor, vec3_t muzzle, shoot_types_t shootType)
{
	if (actor == nullptr)
		return;

	const Item* weapon;
	const char* tag;
	if (IS_SHOT_RIGHT(shootType)) {
		tag = "tag_rweapon";
		weapon = actor->getRightHandItem();
	} else {
		tag = "tag_lweapon";
		weapon = actor->getLeftHandItem();
	}

	if (!weapon || !weapon->def())
		return;

	const objDef_t* od = weapon->def();
	const model_t* model = cls.modelPool[od->idx];
	if (!model)
		Com_Error(ERR_DROP, "Model for item %s is not precached", od->id);

	/* not every weapon has a muzzle tag assigned */
	if (R_GetTagIndexByName(model, "tag_muzzle") == -1)
		return;

	float modifiedMatrix[16];
	if (!R_GetTagMatrix(actor->model1, tag, actor->as.frame, modifiedMatrix))
		Com_Error(ERR_DROP, "Could not find tag %s for actor model %s", tag, actor->model1->name);

	float mc[16];
	GLMatrixAssemble(actor->origin, actor->angles, mc);

	float matrix[16];
	GLMatrixMultiply(mc, modifiedMatrix, matrix);

	R_GetTagMatrix(model, "tag_muzzle", 0, modifiedMatrix);
	GLMatrixMultiply(matrix, modifiedMatrix, mc);

	muzzle[0] = mc[12];
	muzzle[1] = mc[13];
	muzzle[2] = mc[14];
}