Example #1
0
static int
test_inverse (const vec3_t angles, const vec3_t scale,
				 const vec3_t translation)
{
	int         i;
	quat_t      rotation;
	mat4_t      mat, inv, I, res;

	AngleQuat (angles, rotation);
	Mat4Init (rotation, scale, translation, mat);

	Mat4Identity (I);
	Mat4Inverse (mat, inv);
	Mat4Mult (mat, inv, res);

	for (i = 0; i < 4 * 4; i++)
		if (!compare (I[i], res[i]))
			goto fail;

	return 1;
fail:
	printf ("\n\n(%g %g %g) (%g %g %g) (%g %g %g)\n",
			VectorExpand (angles), VectorExpand (scale),
			VectorExpand (translation));
	printf ("  [%g %g %g %g]\n  [%g %g %g %g]\n"
			"  [%g %g %g %g]\n  [%g %g %g %g]\n\n", Mat4Expand (mat));
	printf ("  [%g %g %g %g]\n  [%g %g %g %g]\n"
			"  [%g %g %g %g]\n  [%g %g %g %g]\n\n", Mat4Expand (inv));
	printf ("  [%g %g %g %g]\n  [%g %g %g %g]\n"
			"  [%g %g %g %g]\n  [%g %g %g %g]\n\n", Mat4Expand (res));
	return 0;
}
Example #2
0
static qboolean
load_iqm_meshes (model_t *mod, const iqmheader *hdr, byte *buffer)
{
	iqm_t      *iqm = (iqm_t *) mod->aliashdr;
	iqmtriangle *tris;
	iqmmesh    *meshes;
	iqmjoint   *joints;
	uint32_t    i;

	if (!load_iqm_vertex_arrays (mod, hdr, buffer))
		return false;
	if (!(tris = get_triangles (hdr, buffer)))
		return false;
	iqm->num_elements = hdr->num_triangles * 3;
	iqm->elements = malloc (hdr->num_triangles * 3 * sizeof (uint16_t));
	for (i = 0; i < hdr->num_triangles; i++)
		VectorCopy (tris[i].vertex, iqm->elements + i * 3);
	if (!(meshes = get_meshes (hdr, buffer)))
		return false;
	iqm->num_meshes = hdr->num_meshes;
	iqm->meshes = malloc (hdr->num_meshes * sizeof (iqmmesh));
	memcpy (iqm->meshes, meshes, hdr->num_meshes * sizeof (iqmmesh));
	if (!(joints = get_joints (hdr, buffer)))
		return false;
	iqm->num_joints = hdr->num_joints;
	iqm->joints = malloc (iqm->num_joints * sizeof (iqmjoint));
	iqm->baseframe = malloc (iqm->num_joints * sizeof (mat4_t));
	iqm->inverse_baseframe = malloc (iqm->num_joints * sizeof (mat4_t));
	memcpy (iqm->joints, joints, iqm->num_joints * sizeof (iqmjoint));
	for (i = 0; i < hdr->num_joints; i++) {
		iqmjoint   *j = &iqm->joints[i];
		mat4_t     *bf = &iqm->baseframe[i];
		mat4_t     *ibf = &iqm->inverse_baseframe[i];
		quat_t      t;
		float       ilen;
		ilen = 1.0 / sqrt(QDotProduct (j->rotate, j->rotate));
		QuatScale (j->rotate, ilen, t);
		Mat4Init (t, j->scale, j->translate, *bf);
		Mat4Inverse (*bf, *ibf);
		if (j->parent >= 0) {
			Mat4Mult (iqm->baseframe[j->parent], *bf, *bf);
			Mat4Mult (*ibf, iqm->inverse_baseframe[j->parent], *ibf);
		}
	}
	return true;
}
Example #3
0
	//--------------------------------------------------------------------------------------------------------------
	//更新节点矩阵
	void FKFastcall BoundNode::_UpdateMatrix()
	{
		//从根节点递归更新所有需要更新的节点
		BoundNode* pNode = NULL;

		//如果该节点局部坐标矩阵需要更新
		if( mbUpdateLocalMatrix )
		{
			//设置旋转矩阵
			static Matrix4 matRota;
			mOrientation.GetRotationMatrix4( &matRota );

			//设置缩放矩阵
			static Matrix4 matScl;
			matScl.SetScaling( mScale.x, mScale.y, mScale.z );

			//生成当前节点局部坐标矩阵
			Mat4TransMat4( &mLocalMatrix, &matScl, &matRota );

			//设置局部坐标矩阵平移
			mLocalMatrix._41 = mPosition.x;	mLocalMatrix._42 = mPosition.y;	mLocalMatrix._43 = mPosition.z;

			mbUpdateLocalMatrix = false;

			//更新该节点的世界矩阵
			goto UpdateWorldMatrix;
		}
		//或者该节点的子节点需要更新
		else if( mbUpdateChildMatrix )
		{
			//更新所有子节点的矩阵
			BoundNodeList::Iterator it = mChildNodeList.Begin();
			BoundNodeList::Iterator itend = mChildNodeList.End();
			for(; it!=itend; ++it )
				(*it)->_UpdateMatrix();

			mbUpdateChildMatrix = false;
		}

		//如果该节点的世界坐标矩阵需要更新
		if( mbUpdateWorldMatrix )
		{
UpdateWorldMatrix:
			//与父级矩阵级联生成该节点世界坐标矩阵
			if( mpParentNode != NULL )
				Mat4TransMat4( &mWorldMatrix, &mLocalMatrix, &mpParentNode->mWorldMatrix );
			else
				mWorldMatrix = mLocalMatrix;

			Mat4Inverse( &mInvWorldMatrix, &mWorldMatrix );

			//更新所有子节点的世界坐标矩阵(如需要则会同时更新其局部坐标矩阵)
			BoundNodeList::Iterator it = mChildNodeList.Begin();
			BoundNodeList::Iterator itend = mChildNodeList.End();
			for(; it!=itend; ++it )
			{
				pNode = *it;
				pNode->mbUpdateWorldMatrix = true;
				pNode->_UpdateMatrix();
			}

			mbUpdateWorldMatrix = false;

			//更新所有碰撞体世界坐标包围盒
			_UpdateBoundVolumeBox();
		}
	}