Ejemplo n.º 1
0
// calculates the bone matrices for the given mesh
std::vector<aiMatrix4x4>& Animator::GetBoneMatrices(aiNode* node, int nodeMeshIndex)
{
    if (nodeMeshIndex < node->mNumMeshes)
    {
        unsigned int meshIndex = node->mMeshes[nodeMeshIndex];
        
        if ((mainScene != NULL) && (meshIndex < mainScene->mNumMeshes))
        {
            const aiMesh* mesh = mainScene->mMeshes[meshIndex];
            
            for (unsigned int i = 0; i < boneTransforms.size(); i++)
            {
                boneTransforms[i] = aiMatrix4x4();
            }
            
            // resize array and initialise it with identity matrices
            boneTransforms.resize(mesh->mNumBones, aiMatrix4x4());
            
            // calculate the mesh's inverse global transform
            aiMatrix4x4 mGlobalInverseMeshTransform = GetGlobalTransform(node);
            mGlobalInverseMeshTransform.Inverse();
            
            // calculate transform from mesh coordinates in bind pose to mesh coordinates in skinned pose
            for (unsigned int i = 0; i < mesh->mNumBones; i++)
            {
                const aiBone* bone = mesh->mBones[i];
                const aiMatrix4x4& mCurrentGlobalTransform = GetGlobalTransform(mapBoneNodesByName[bone->mName.data]);
                boneTransforms[i] = mGlobalInverseMeshTransform * mCurrentGlobalTransform * bone->mOffsetMatrix;
            }
        }
    }
    
    //and return the result
    return boneTransforms;
}
// ------------------------------------------------------------------------------------------------
// Calculates the bone matrices for the given mesh. 
const std::vector<aiMatrix4x4>& SceneAnimator::GetBoneMatrices(const aiNode* pNode, size_t pMeshIndex /* = 0 */)
{
	ai_assert(pMeshIndex < pNode->mNumMeshes);
	size_t meshIndex = pNode->mMeshes[pMeshIndex];
	ai_assert(meshIndex < mScene->mNumMeshes);
	const aiMesh* mesh = mScene->mMeshes[meshIndex];

	// resize array and initialise it with identity matrices
	mTransforms.resize(mesh->mNumBones, aiMatrix4x4());

	// calculate the mesh's inverse global transform
	aiMatrix4x4 globalInverseMeshTransform = GetGlobalTransform(pNode);
	globalInverseMeshTransform.Inverse();

	// Bone matrices transform from mesh coordinates in bind pose to mesh coordinates in skinned pose
	// Therefore the formula is offsetMatrix * currentGlobalTransform * inverseCurrentMeshTransform
	for (size_t a = 0; a < mesh->mNumBones; ++a)
	{
		const aiBone* bone = mesh->mBones[a];
		const aiMatrix4x4& currentGlobalTransform = GetGlobalTransform(mBoneNodesByName[bone->mName.data]);
		mTransforms[a] = globalInverseMeshTransform * currentGlobalTransform * bone->mOffsetMatrix;
	}

	// and return the result
	return mTransforms;
}
Ejemplo n.º 3
0
void CCharacter::ShowPlayerVectors() const
{
	TMatrix m = GetGlobalTransform();

	Vector vecUp = GetUpVector();
	Vector vecRight = m.GetForwardVector().Cross(vecUp).Normalized();
	Vector vecForward = vecUp.Cross(vecRight).Normalized();
	m.SetColumn(0, vecForward);
	m.SetColumn(1, vecUp);
	m.SetColumn(2, vecRight);

	CCharacter* pLocalCharacter = Game()->GetLocalPlayer()->GetCharacter();

	TVector vecEyeHeight = GetUpVector() * EyeHeight();

	CRenderingContext c(GameServer()->GetRenderer());

	c.Translate((GetGlobalOrigin() - pLocalCharacter->GetGlobalOrigin()));
	c.SetColor(Color(255, 255, 255));
	c.BeginRenderDebugLines();
	c.Vertex(Vector(0,0,0));
	c.Vertex((float)EyeHeight() * vecUp);
	c.EndRender();

	if (!GetGlobalVelocity().IsZero())
	{
		c.BeginRenderDebugLines();
		c.Vertex(vecEyeHeight);
		c.Vertex(vecEyeHeight + GetGlobalVelocity());
		c.EndRender();
	}

	c.SetColor(Color(255, 0, 0));
	c.BeginRenderDebugLines();
	c.Vertex(vecEyeHeight);
	c.Vertex(vecEyeHeight + vecForward);
	c.EndRender();

	c.SetColor(Color(0, 255, 0));
	c.BeginRenderDebugLines();
	c.Vertex(vecEyeHeight);
	c.Vertex(vecEyeHeight + vecRight);
	c.EndRender();

	c.SetColor(Color(0, 0, 255));
	c.BeginRenderDebugLines();
	c.Vertex(vecEyeHeight);
	c.Vertex(vecEyeHeight + vecUp);
	c.EndRender();

	TVector vecPoint, vecNormal;
	if (Game()->TraceLine(GetGlobalOrigin(), GetGlobalOrigin() - GetUpVector()*100, vecPoint, vecNormal, NULL))
	{
		c.Translate(vecPoint - GetGlobalOrigin());
		c.Scale(0.1f, 0.1f, 0.1f);
		c.SetColor(Color(255, 255, 255));
		c.RenderSphere();
	}
}
Ejemplo n.º 4
0
CScalableMatrix CSPCharacter::GetScalableRenderTransform() const
{
	CSPCharacter* pCharacter = SPGame()->GetLocalPlayerCharacter();
	CScalableVector vecCharacterOrigin = pCharacter->GetGlobalOrigin();

	CScalableMatrix mTransform = GetGlobalTransform();
	mTransform.SetTranslation(mTransform.GetTranslation() - vecCharacterOrigin);

	return mTransform;
}
Ejemplo n.º 5
0
void CSPCharacter::LockViewToPlanet()
{
	// Now lock the roll value to the planet.
	CPlanet* pNearestPlanet = GetNearestPlanet();
	if (!pNearestPlanet)
		return;

	Matrix4x4 mGlobalRotation = GetGlobalTransform();
	mGlobalRotation.SetTranslation(CScalableVector());

	// Construct a "local space" for the planet
	Vector vecPlanetUp = GetUpVector();
	Vector vecPlanetForward = mGlobalRotation.GetForwardVector();
	Vector vecPlanetRight = vecPlanetForward.Cross(vecPlanetUp).Normalized();
	vecPlanetForward = vecPlanetUp.Cross(vecPlanetRight).Normalized();

	Matrix4x4 mPlanet(vecPlanetForward, vecPlanetUp, vecPlanetRight);
	Matrix4x4 mPlanetInverse = mPlanet;
	mPlanetInverse.InvertTR();

	// Bring our current view angles into that local space
	Matrix4x4 mLocalRotation = mPlanetInverse * mGlobalRotation;
	EAngle angLocalRotation = mLocalRotation.GetAngles();

	// Lock them so that the roll is 0
	// I'm sure there's a way to do this without converting to euler but at this point I don't care.
	angLocalRotation.r = 0;
	Matrix4x4 mLockedLocalRotation;
	mLockedLocalRotation.SetAngles(angLocalRotation);

	// Bring it back out to global space
	Matrix4x4 mLockedRotation = mPlanet * mLockedLocalRotation;

	// Only use the changed r value to avoid floating point crap
	EAngle angNewLockedRotation = GetGlobalAngles();
	EAngle angOverloadRotation = mLockedRotation.GetAngles();

	// Lerp our way there
	float flTimeToLocked = 1;
	if (GameServer()->GetGameTime() - m_flLastEnteredAtmosphere > flTimeToLocked)
		angNewLockedRotation.r = angOverloadRotation.r;
	else
		angNewLockedRotation.r = RemapValClamped(SLerp(GameServer()->GetGameTime() - m_flLastEnteredAtmosphere, 0.3f), 0, flTimeToLocked, m_flRollFromSpace, angOverloadRotation.r);

	SetGlobalAngles(angNewLockedRotation);
}
Ejemplo n.º 6
0
HRESULT CBoundingBox::PutData(enum BOUND_FORMAT nFormat, FWULONG nSize, /*[in, size_is(nSize)]*/ BYTE *pBuf)
{
#define BUFAABB		((struct BOUND_AABB*)pBuf)
#define BUFOBB		((struct BOUND_OBB*)pBuf)
#define BUFOBB_8	((struct BOUND_OBB_8*)pBuf)
#define BUFSPHERE	((struct BOUND_SPHERE*)pBuf)
#define BUFCYLINDER	((struct BOUND_CYLINDER*)pBuf)

	switch (nFormat)
	{
		case BOUND_FORMAT_AABB:
			if (nSize != sizeof(BOUND_AABB)) return ERROR(FW_E_FORMAT);
			m_obb.vecSize.x = fabs(BUFAABB->vecMax.x - BUFAABB->vecMin.x) * 0.5f;
			m_obb.vecSize.y = fabs(BUFAABB->vecMax.y - BUFAABB->vecMin.y) * 0.5f;
			m_obb.vecSize.z = fabs(BUFAABB->vecMax.z - BUFAABB->vecMin.z) * 0.5f;
			memset(m_obb.M, 0, sizeof(m_obb.M));
			m_obb.M[3][0] = (BUFAABB->vecMin.x + BUFAABB->vecMax.x) * 0.5f;
			m_obb.M[3][1] = (BUFAABB->vecMin.y + BUFAABB->vecMax.y) * 0.5f;
			m_obb.M[3][2] = (BUFAABB->vecMin.z + BUFAABB->vecMax.z) * 0.5f;
			m_obb.M[0][0] = m_obb.M[1][1] = m_obb.M[2][2] = m_obb.M[3][3] = 1.0f;
			break;

		case BOUND_FORMAT_OBB:
			if (nSize != sizeof(BOUND_OBB)) return ERROR(FW_E_FORMAT);
			memcpy(&m_obb, pBuf, sizeof(m_obb));
			break;

		case BOUND_FORMAT_OBB_8:
			if (nSize != sizeof(BOUND_OBB)) return ERROR(FW_E_FORMAT);
			return ERROR(FW_E_FORMAT);

		case BOUND_FORMAT_SPHERE:
			if (nSize != sizeof(BOUND_SPHERE)) return ERROR(FW_E_FORMAT);
			m_obb.vecSize.x = m_obb.vecSize.y = m_obb.vecSize.z = BUFSPHERE->fRadius;
			memset(m_obb.M, 0, sizeof(m_obb.M));
			m_obb.M[3][0] = BUFSPHERE->vecCenter.x;
			m_obb.M[3][1] = BUFSPHERE->vecCenter.y;
			m_obb.M[3][2] = BUFSPHERE->vecCenter.z;
			m_obb.M[0][0] = m_obb.M[1][1] = m_obb.M[2][2] = m_obb.M[3][3] = 1.0f;
			break;

		case BOUND_FORMAT_CYLINDER:
			if (nSize != sizeof(BOUND_CYLINDER)) return ERROR(FW_E_FORMAT);
			return ERROR(FW_E_FORMAT);

		default:
			return ERROR(FW_E_FORMAT);
	}

	ITransform *pT = NULL;
	CreateCompatibleTransform(&pT);
	HRESULT h = GetGlobalTransform(pT);
	if (FAILED(h)) return ERROR(h);
	pT->Inverse();
	FWMATRIX  M, M1;
	pT->AsMatrix(M1);
	pT->Release();
	_Multiply(M, m_obb.M, M1);
	memcpy(m_obb.M, M, sizeof(M));
	return S_OK;
}
Ejemplo n.º 7
0
HRESULT CBoundingBox::GetData(enum BOUND_FORMAT nFormat, FWULONG nSize, /*[out, size_is(nSize)]*/ BYTE *pBuf)
{
#define BUFAABB		((struct BOUND_AABB*)pBuf)
#define BUFOBB		((struct BOUND_OBB*)pBuf)
#define BUFOBB_8	((struct BOUND_OBB_8*)pBuf)
#define BUFSPHERE	((struct BOUND_SPHERE*)pBuf)
#define BUFCYLINDER	((struct BOUND_CYLINDER*)pBuf)

	FWMATRIX M, M1;
	ITransform *pT = NULL;
	CreateCompatibleTransform(&pT);
	HRESULT h = GetGlobalTransform(pT);
	if (FAILED(h)) return ERROR(h);
	pT->AsMatrix(M1);
	pT->Release();
	_Multiply(M, m_obb.M, M1);

	switch (nFormat)
	{
		case BOUND_FORMAT_AABB:
			if (nSize != sizeof(BOUND_AABB)) return ERROR(FW_E_FORMAT);
			BUFAABB->vecMin.x = -m_obb.vecSize.x;
			BUFAABB->vecMin.y = -m_obb.vecSize.y;
			BUFAABB->vecMin.z = -m_obb.vecSize.z;
			BUFAABB->vecMax.x =  m_obb.vecSize.x;
			BUFAABB->vecMax.y =  m_obb.vecSize.y;
			BUFAABB->vecMax.z =  m_obb.vecSize.z;
			_Transform(&BUFAABB->vecMin, M);
			_Transform(&BUFAABB->vecMax, M);
			break;

		case BOUND_FORMAT_OBB:
			if (nSize != sizeof(BOUND_OBB)) return ERROR(FW_E_FORMAT);
			memcpy(BUFOBB->M, M, sizeof(M));
			memcpy(&BUFOBB->vecSize, &m_obb.vecSize, sizeof(m_obb.vecSize));
			break;

		case BOUND_FORMAT_OBB_8:
			BUFOBB_8->OBB[0].x = -m_obb.vecSize.x;	BUFOBB_8->OBB[0].y = -m_obb.vecSize.y;	BUFOBB_8->OBB[0].z = -m_obb.vecSize.z;
			BUFOBB_8->OBB[1].x =  m_obb.vecSize.x;	BUFOBB_8->OBB[1].y = -m_obb.vecSize.y;	BUFOBB_8->OBB[1].z = -m_obb.vecSize.z;
			BUFOBB_8->OBB[2].x = -m_obb.vecSize.x;	BUFOBB_8->OBB[2].y = -m_obb.vecSize.y;	BUFOBB_8->OBB[2].z =  m_obb.vecSize.z;
			BUFOBB_8->OBB[3].x =  m_obb.vecSize.x;	BUFOBB_8->OBB[3].y = -m_obb.vecSize.y;	BUFOBB_8->OBB[3].z =  m_obb.vecSize.z;
			BUFOBB_8->OBB[4].x = -m_obb.vecSize.x;	BUFOBB_8->OBB[4].y =  m_obb.vecSize.y;	BUFOBB_8->OBB[4].z = -m_obb.vecSize.z;
			BUFOBB_8->OBB[5].x =  m_obb.vecSize.x;	BUFOBB_8->OBB[5].y =  m_obb.vecSize.y;	BUFOBB_8->OBB[5].z = -m_obb.vecSize.z;
			BUFOBB_8->OBB[6].x = -m_obb.vecSize.x;	BUFOBB_8->OBB[6].y =  m_obb.vecSize.y;	BUFOBB_8->OBB[6].z =  m_obb.vecSize.z;
			BUFOBB_8->OBB[7].x =  m_obb.vecSize.x;	BUFOBB_8->OBB[7].y =  m_obb.vecSize.y;	BUFOBB_8->OBB[7].z =  m_obb.vecSize.z;
			for (int i = 0; i < 8; i++)
				_Transform(BUFOBB_8->OBB + i, M);
			break;

		case BOUND_FORMAT_SPHERE:
			if (nSize != sizeof(BOUND_SPHERE)) return ERROR(FW_E_FORMAT);
			BUFSPHERE->vecCenter.x = (FWFLOAT)M[3][0];
			BUFSPHERE->vecCenter.y = (FWFLOAT)M[3][1];
			BUFSPHERE->vecCenter.z = (FWFLOAT)M[3][2];
			// _Transform not needed here (no rotation)
			BUFSPHERE->fRadius = sqrt(m_obb.vecSize.x * m_obb.vecSize.x + m_obb.vecSize.y * m_obb.vecSize.y + m_obb.vecSize.z * m_obb.vecSize.z);
			break;

		case BOUND_FORMAT_CYLINDER:
			if (nSize != sizeof(BOUND_CYLINDER)) return ERROR(FW_E_FORMAT);
			BUFCYLINDER->vecPivot1.x = BUFCYLINDER->vecPivot1.z = BUFCYLINDER->vecPivot2.x = BUFCYLINDER->vecPivot2.z = 0.0f;
			BUFCYLINDER->vecPivot1.y = -m_obb.vecSize.y;
			BUFCYLINDER->vecPivot2.y =  m_obb.vecSize.y;
			_Transform(&BUFCYLINDER->vecPivot1, M);
			_Transform(&BUFCYLINDER->vecPivot2, M);
			BUFCYLINDER->fRadius = sqrt(m_obb.vecSize.x * m_obb.vecSize.x + m_obb.vecSize.z * m_obb.vecSize.z);
			break;

		default:
			return ERROR(FW_E_FORMAT);
	}

	return S_OK;
}
Ejemplo n.º 8
0
const Matrix4x4 CLevelEntity::GetPhysicsTransform() const
{
	return GetGlobalTransform();
}