This commit is contained in:
nephacks
2025-06-04 03:22:50 +02:00
parent f234f23848
commit f12416cffd
14243 changed files with 6446499 additions and 26 deletions

View File

@@ -0,0 +1,40 @@
// ----------------------------------------- //
// File generated by VPC //
// ----------------------------------------- //
Source file: F:\csgo_64\cstrike15_src\bonesetup\bone_constraints.cpp
Debug output file: F:\csgo_64\cstrike15_src\bonesetup\bone_constraints.cpp
Release output file: F:\csgo_64\cstrike15_src\bonesetup\bone_constraints.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\bonesetup\bone_decode.cpp
Debug output file: F:\csgo_64\cstrike15_src\bonesetup\bone_decode.cpp
Release output file: F:\csgo_64\cstrike15_src\bonesetup\bone_decode.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\bonesetup\bone_ik.cpp
Debug output file: F:\csgo_64\cstrike15_src\bonesetup\bone_ik.cpp
Release output file: F:\csgo_64\cstrike15_src\bonesetup\bone_ik.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\bonesetup\bone_setup.cpp
Debug output file: F:\csgo_64\cstrike15_src\bonesetup\bone_setup.cpp
Release output file: F:\csgo_64\cstrike15_src\bonesetup\bone_setup.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\bonesetup\bone_utils.cpp
Debug output file: F:\csgo_64\cstrike15_src\bonesetup\bone_utils.cpp
Release output file: F:\csgo_64\cstrike15_src\bonesetup\bone_utils.cpp
Containing unity file:
PCH file:
Source file: F:\csgo_64\cstrike15_src\common\debug_lib_check.cpp
Debug output file: F:\csgo_64\cstrike15_src\common\debug_lib_check.cpp
Release output file: F:\csgo_64\cstrike15_src\common\debug_lib_check.cpp
Containing unity file:
PCH file:

View File

@@ -0,0 +1,898 @@
//============ Copyright (c) Valve Corporation, All rights reserved. ============
//
// Routines used for various prodcedural bones but meant to be called from
// datamodel or maya as well
//
// In a separate source file so linking bonesetup.lib doesn't get more than
// needed
//
//===============================================================================
// Valve includes
#include "mathlib/mathlib.h"
#include "mathlib/vector.h"
#include "tier1/strtools.h"
#include "bone_setup.h"
#include "bone_constraints.h"
#include "bone_accessor.h"
#include "studio.h"
#include "tier0/tslist.h"
#include "tier0/miniprofiler.h"
#include "bone_utils.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
//=============================================================================
//=============================================================================
//
// CConstraintBones
//
//=============================================================================
//=============================================================================
//-----------------------------------------------------------------------------
// Compute the aggregate target position and orientation from the weighted target list and return
// the resulting position and orientation in addition to updating the target dag.
// All passed arrays must be nTargetCount in length
//-----------------------------------------------------------------------------
float CConstraintBones::ComputeTargetPosition(
Vector &vTargetPosition,
int nTargetCount,
float *flTargetWeights,
Vector *vTargetPositions,
Vector *vTargetOffsets )
{
vTargetPosition = vec3_origin;
float flWeightSum = 0.0;
for ( int i = 0; i < nTargetCount; ++i )
{
vTargetPosition += ( flTargetWeights[i] * ( vTargetPositions[i] + vTargetOffsets[i] ) );
flWeightSum += flTargetWeights[i];
}
if ( flWeightSum > 0.0f )
{
vTargetPosition *= 1.0f / flWeightSum;
}
return MIN( 1.0f, flWeightSum );
}
//-----------------------------------------------------------------------------
// Compute the aggregate target orientation from the weighted target list and
// return the total weight
// All passed arrays must be nTargetCount in length
//-----------------------------------------------------------------------------
float CConstraintBones::ComputeTargetOrientation(
Quaternion &qTargetOrientation,
int nTargetCount,
float *pflTargetWeights,
Quaternion *pqTargetOrientations,
Quaternion *pqTargetOffsets )
{
// If there is only one target, for efficiency don't bother with the weighting
if ( nTargetCount == 1 )
{
QuaternionMult( pqTargetOrientations[0], pqTargetOffsets[0], qTargetOrientation );
return MIN( 1.0f, pflTargetWeights[0] );
}
qTargetOrientation = quat_identity;
// If no targets, return identity quaternion and weight of 0
if ( nTargetCount <= 0 )
return 0.0f;
Quaternion *pQuats = reinterpret_cast< Quaternion * >( stackalloc( nTargetCount * sizeof( Quaternion ) ) );
float flWeightSum = 0.0f;
for ( int i = 0; i < nTargetCount; ++i )
{
QuaternionMult( pqTargetOrientations[i], pqTargetOffsets[i], pQuats[i] );
flWeightSum += pflTargetWeights[i];
}
QuaternionAverageExponential( qTargetOrientation, nTargetCount, pQuats, pflTargetWeights );
return MIN( 1.0f, flWeightSum );
}
//-----------------------------------------------------------------------------
// Compute the aggregate target position and orientation from the weighted
// target list and return the total weight
// All passed arrays must be nTargetCount in length
//-----------------------------------------------------------------------------
float CConstraintBones::ComputeTargetPositionOrientation(
Vector &vTargetPosition,
Quaternion &qTargetOrientation,
int nTargetCount,
float *pflTargetWeights,
Vector *pvTargetPositions,
Vector *pvTargetOffsets,
Quaternion *pqTargetOrientations,
Quaternion *pqTargetOffsets )
{
Quaternion *pQuats = reinterpret_cast< Quaternion *>( stackalloc( nTargetCount * sizeof( Quaternion ) ) );
float flWeightSum = 0.0f;
vTargetPosition = vec3_origin;
qTargetOrientation = quat_identity;
for ( int i = 0; i < nTargetCount; ++i )
{
float flWeight = pflTargetWeights[i];
matrix3x4a_t mTarget;
AngleMatrix( RadianEuler(pqTargetOrientations[i]), pvTargetPositions[i], mTarget );
matrix3x4a_t mOffset;
AngleMatrix( RadianEuler(pqTargetOffsets[i]), pvTargetOffsets[i], mOffset );
matrix3x4a_t mAbs;
ConcatTransforms( mTarget, mOffset, mAbs );
Vector vPos;
MatrixAngles( mAbs, pQuats[i], vPos );
vTargetPosition += ( flWeight * vPos );
// For normalization
flWeightSum += flWeight;
}
if ( flWeightSum > 0.0f )
{
vTargetPosition *= 1.0f / flWeightSum;
}
QuaternionAverageExponential( qTargetOrientation, nTargetCount, pQuats, pflTargetWeights );
return MIN( 1.0f, flWeightSum );
}
//-----------------------------------------------------------------------------
// Compute the aggregate target position and orientation from the weighted
// target list and return the total weight
// All passed arrays must be nTargetCount in length
//-----------------------------------------------------------------------------
float CConstraintBones::ComputeTargetPositionOrientation(
Vector &vTargetPosition,
Quaternion &qTargetOrientation,
int nTargetCount,
float *pflTargetWeights,
matrix3x4a_t *pmTargets,
matrix3x4a_t *pmOffsets )
{
Quaternion *pQuats = reinterpret_cast< Quaternion *>( stackalloc( nTargetCount * sizeof( Quaternion ) ) );
float flWeightSum = 0.0f;
vTargetPosition = vec3_origin;
qTargetOrientation = quat_identity;
matrix3x4a_t mAbs;
Vector vPos;
for ( int i = 0; i < nTargetCount; ++i )
{
float flWeight = pflTargetWeights[i];
ConcatTransforms( pmTargets[i], pmOffsets[i], mAbs );
MatrixAngles( mAbs, pQuats[i], vPos );
vTargetPosition += ( flWeight * vPos );
// For normalization
flWeightSum += flWeight;
}
if ( flWeightSum > 0.0f )
{
vTargetPosition *= 1.0f / flWeightSum;
}
QuaternionAverageExponential( qTargetOrientation, nTargetCount, pQuats, pflTargetWeights );
return MIN( 1.0f, flWeightSum );
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CConstraintBones::ComputeAimConstraintOffset(
Quaternion &qAimOffset,
bool bPreserveOffset,
const Vector &vTargetWorldPos,
const matrix3x4_t &mSlaveParentToWorld,
const Vector &vUp,
const Vector &vSlaveLocalPos,
const Quaternion &qSlaveLocal,
matrix3x4_t *pmUpToWorld,
AimConstraintUpType_t eUpType )
{
if ( !bPreserveOffset )
{
qAimOffset = quat_identity;
return;
}
// Calculate the desired orientation based the target position
Quaternion qAim;
ComputeAimConstraint( qAim, vTargetWorldPos, mSlaveParentToWorld, vUp, vSlaveLocalPos, pmUpToWorld, eUpType );
// Compute the difference between the slave's current orientation and the target orientation
Quaternion qAimInv;
QuaternionInvert( qAim, qAimInv );
QuaternionMult( qAimInv, qSlaveLocal, qAimOffset );
RadianEuler eAim(qAim);
RadianEuler eSlaveLocal(qSlaveLocal);
RadianEuler eAimOffset(qAimOffset);
}
//-----------------------------------------------------------------------------
// Calculate the orientation needed to make a transform where the y
// vector of the transform matches the forward vector and the z vector matches
// the up reference vector as closely as possible. The x vector will be in the
// plane defined by using the forward vector as the normal.
//-----------------------------------------------------------------------------
void CConstraintBones::ComputeAimConstraintAimAt(
Quaternion &qAim,
const Vector &vForward,
const Vector &vReferenceUp )
{
Vector vFwd = vForward;
vFwd.NormalizeInPlace();
const float flRatio = DotProduct( vFwd, vReferenceUp );
Vector vUp = vReferenceUp - ( vFwd * flRatio );
vUp.NormalizeInPlace();
Vector vRight = vFwd.Cross( vUp );
vRight.NormalizeInPlace();
const Vector &vX = vRight;
const Vector &vY = vFwd;
const Vector &vZ = vUp;
const float flTr = vX.x + vY.y + vZ.z;
qAim.Init( vY.z - vZ.y , vZ.x - vX.z, vX.y - vY.x, flTr + 1.0f );
const float flRadius = qAim[0] * qAim[0] + qAim[1] * qAim[1] + qAim[2] * qAim[2] + qAim[3] * qAim[3];
if ( flRadius > FLT_EPSILON )
{
QuaternionNormalize( qAim );
}
else
{
matrix3x4_t mRot;
MatrixSetColumn( vX, 0, mRot );
MatrixSetColumn( vY, 1, mRot );
MatrixSetColumn( vZ, 2, mRot );
MatrixQuaternion( mRot, qAim );
}
}
//-----------------------------------------------------------------------------
// Given the various parameters, computes the local vForward & vReferenceUp
// and calls ComputeAimConstraintAimAt
//-----------------------------------------------------------------------------
void CConstraintBones::ComputeAimConstraint(
Quaternion &qAim,
const Vector &vTargetWorldPos,
const matrix3x4_t &mParentToWorld,
const Vector &vUp,
const Vector &vSlaveLocalPos,
const matrix3x4_t *pmUpToWorld,
AimConstraintUpType_t eUpType )
{
matrix3x4_t mWorldToParent;
MatrixInvert( mParentToWorld, mWorldToParent );
// If the up vector is in world space, convert it into local space
Vector vWorldUp;
ComputeWorldUpVector( &vWorldUp, mParentToWorld, vUp, vSlaveLocalPos, pmUpToWorld, eUpType );
Vector vLocalUp;
VectorRotate( vWorldUp, mWorldToParent, vLocalUp );
// Convert the target's world space position into the local space of the slave.
Vector vTargetLocalPos;
VectorTransform( vTargetWorldPos, mWorldToParent, vTargetLocalPos );
// Compute the local space forward vector
Vector vLocalForward = vTargetLocalPos - vSlaveLocalPos;
vLocalForward.NormalizeInPlace();
// Compute the orientation
CConstraintBones::ComputeAimConstraintAimAt( qAim, vLocalForward, vLocalUp );
RadianEuler e(qAim);
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
void CConstraintBones::ComputeWorldUpVector(
Vector *pvWorldUp,
const matrix3x4_t & mParentToWorld,
const Vector &vUp,
const Vector &vSlaveLocalPos,
const matrix3x4_t *pmUpToWorld,
AimConstraintUpType_t eUpType )
{
switch ( eUpType )
{
case AC_UP_TYPE_VECTOR:
VectorCopy( vUp, *pvWorldUp );
break;
case AC_UP_TYPE_OBJECT:
if ( pmUpToWorld )
{
Vector vUpObjectWorldPos;
MatrixPosition( *pmUpToWorld, vUpObjectWorldPos );
Vector vSlaveWorldPos;
VectorTransform( vSlaveLocalPos, mParentToWorld, vSlaveWorldPos );
VectorSubtract( vUpObjectWorldPos, vSlaveWorldPos, *pvWorldUp );
VectorNormalize( *pvWorldUp );
}
else
{
VectorCopy( vUp, *pvWorldUp );
}
break;
case AC_UP_TYPE_PARENT_ROTATION:
VectorRotate( vUp, mParentToWorld, *pvWorldUp );
break;
default:
case AC_UP_TYPE_OBJECT_ROTATION:
if ( pmUpToWorld )
{
VectorRotate( vUp, *pmUpToWorld, *pvWorldUp );
}
else
{
VectorCopy( vUp, *pvWorldUp );
}
break;
}
}
//=============================================================================
//=============================================================================
//
// CStudioConstraintBones
//
//=============================================================================
//=============================================================================
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
float CStudioConstraintBones::ComputeTargetPosition(
Vector &vTargetPosition,
mstudioconstrainttarget_t *pTargets,
int nTargetCount,
CBoneAccessor &boneToWorld )
{
float *pflTargetWeights = reinterpret_cast< float * >( stackalloc( nTargetCount * sizeof( float ) ) );
Vector *pvTargetPositions = reinterpret_cast< Vector * >( stackalloc( nTargetCount * sizeof( Vector ) ) );
Vector *pvTargetOffsets = reinterpret_cast< Vector * >( stackalloc( nTargetCount * sizeof( Vector ) ) );
mstudioconstrainttarget_t *pTarget;
for ( int i = 0; i < nTargetCount; ++i )
{
pTarget = pTargets + i;
pflTargetWeights[i] = pTarget->m_flWeight;
pvTargetOffsets[i] = pTarget->m_vOffset;
MatrixPosition( boneToWorld.GetBone( pTarget->m_nBone ), pvTargetPositions[i] );
}
return CConstraintBones::ComputeTargetPosition( vTargetPosition, nTargetCount, pflTargetWeights, pvTargetPositions, pvTargetOffsets );
}
//=============================================================================
// CStudioConstraintBones : Studio Interface Functions
//=============================================================================
//-----------------------------------------------------------------------------
// studio interface
//-----------------------------------------------------------------------------
float CStudioConstraintBones::ComputeTargetOrientation(
Quaternion &qTargetOrientation,
mstudioconstrainttarget_t *pTargets,
int nTargetCount,
CBoneAccessor &boneToWorld )
{
float *pflTargetWeights = reinterpret_cast< float * >( stackalloc( nTargetCount * sizeof( float ) ) );
Quaternion *pqTargetOrientations = reinterpret_cast< Quaternion * >( stackalloc( nTargetCount * sizeof( Quaternion ) ) );
Quaternion *pqTargetOffsets = reinterpret_cast< Quaternion * >( stackalloc( nTargetCount * sizeof( Quaternion ) ) );
mstudioconstrainttarget_t *pTarget;
for ( int i = 0; i < nTargetCount; ++i )
{
pTarget = pTargets + i;
pflTargetWeights[i] = pTarget->m_flWeight;
pqTargetOffsets[i] = pTarget->m_qOffset;
MatrixQuaternion( boneToWorld.GetBone( pTarget->m_nBone ), pqTargetOrientations[i] );
}
return CConstraintBones::ComputeTargetOrientation( qTargetOrientation, nTargetCount, pflTargetWeights, pqTargetOrientations, pqTargetOffsets );
}
//-----------------------------------------------------------------------------
// studio interface
//-----------------------------------------------------------------------------
float CStudioConstraintBones::ComputeTargetPositionOrientation(
Vector &vTargetPosition,
Quaternion &qTargetOrientation,
mstudioconstrainttarget_t *pTargets,
int nTargetCount,
CBoneAccessor &boneToWorld )
{
float *pflTargetWeights = reinterpret_cast< float * >( stackalloc( nTargetCount * sizeof( float ) ) );
matrix3x4a_t *pmTargets = reinterpret_cast< matrix3x4a_t * >( stackalloc( nTargetCount * sizeof( matrix3x4a_t ) ) );
matrix3x4a_t *pmOffsets = reinterpret_cast< matrix3x4a_t * >( stackalloc( nTargetCount * sizeof( matrix3x4a_t ) ) );
mstudioconstrainttarget_t *pTarget = pTargets;
for ( int i = 0; i < nTargetCount; ++i, ++pTarget )
{
pflTargetWeights[i] = pTarget->m_flWeight;
QuaternionMatrix( pTarget->m_qOffset, pTarget->m_vOffset, pmOffsets[i] );
pmTargets[i] = boneToWorld.GetBone( pTarget->m_nBone );
}
return CConstraintBones::ComputeTargetPositionOrientation( vTargetPosition, qTargetOrientation, nTargetCount, pflTargetWeights, pmTargets, pmOffsets );
}
//-----------------------------------------------------------------------------
// studio interface
//-----------------------------------------------------------------------------
void CStudioConstraintBones::ComputeBaseWorldMatrix(
matrix3x4a_t &mBaseWorldMatrix,
mstudioconstraintslave_t *pSlave,
CBoneAccessor &boneToWorld,
const CStudioHdr *pStudioHdr,
const matrix3x4_t *pmViewTransform /* = NULL */ )
{
// studiomdl shouldn't create mstudioconstraintslave_t's with invalid bone indices
Assert( pSlave->m_nBone >= 0 && pSlave->m_nBone < MAXSTUDIOBONES );
const int nBoneParent = pStudioHdr->boneParent( pSlave->m_nBone );
if ( nBoneParent < 0 )
{
if ( pmViewTransform )
{
matrix3x4a_t mTmp;
QuaternionMatrix( pSlave->m_qBaseOrientation, pSlave->m_vBasePosition, mTmp );
ConcatTransforms( *pmViewTransform, mTmp, mBaseWorldMatrix );
}
else
{
QuaternionMatrix( pSlave->m_qBaseOrientation, pSlave->m_vBasePosition, mBaseWorldMatrix );
}
}
else
{
matrix3x4a_t mTmp;
QuaternionMatrix( pSlave->m_qBaseOrientation, pSlave->m_vBasePosition, mTmp );
ConcatTransforms( boneToWorld.GetBone( nBoneParent ), mTmp, mBaseWorldMatrix );
}
}
//-----------------------------------------------------------------------------
// studio interface
//-----------------------------------------------------------------------------
void CStudioConstraintBones::ComputePointConstraint(
const mstudiobone_t *pBones,
int nBone,
CBoneAccessor &boneToWorld,
const CStudioHdr *pStudioHdr )
{
BONE_PROFILE_FUNC();
mstudiopointconstraint_t *pProc = ( mstudiopointconstraint_t * )pBones[nBone].pProcedure();
// Calculate the current target position and the total weight
// of the the targets contributing to the target position.
Vector vTargetPosition;
const float flWeight = CStudioConstraintBones::ComputeTargetPosition( vTargetPosition, pProc->pTarget( 0 ), pProc->m_nTargetCount, boneToWorld );
Vector vFinalPosition;
matrix3x4a_t &mBaseWorldMatrix = boneToWorld.GetBoneForWrite( nBone );
CStudioConstraintBones::ComputeBaseWorldMatrix( mBaseWorldMatrix, &( pProc->m_slave ), boneToWorld, pStudioHdr );
// Blend between the target position and the base position using the target weight
if ( flWeight < 1.0f )
{
Vector vBasePosition;
MatrixPosition( mBaseWorldMatrix, vBasePosition );
vFinalPosition = Lerp( flWeight, vBasePosition, vTargetPosition );
}
else
{
vFinalPosition = vTargetPosition;
}
// Update the bone the new position.
PositionMatrix( vFinalPosition, mBaseWorldMatrix );
}
//-----------------------------------------------------------------------------
// studio interface
//-----------------------------------------------------------------------------
void CStudioConstraintBones::ComputeOrientConstraint(
const mstudiobone_t *pBones,
int nBone,
CBoneAccessor &boneToWorld,
const CStudioHdr *pStudioHdr,
const matrix3x4_t *pmViewTransform )
{
BONE_PROFILE_FUNC();
mstudioorientconstraint_t *pProc = ( mstudioorientconstraint_t * )pBones[nBone].pProcedure();
// Calculate the current target position and the total weight
// of the the targets contributing to the target position.
Quaternion qTargetOrientation;
const float flWeight = CStudioConstraintBones::ComputeTargetOrientation( qTargetOrientation, pProc->pTarget( 0 ), pProc->m_nTargetCount, boneToWorld );
// Blend between the target orientation and the base orientation using the target weight
Quaternion qFinalOrientation;
matrix3x4a_t &mBaseWorldMatrix = boneToWorld.GetBoneForWrite( nBone );
CStudioConstraintBones::ComputeBaseWorldMatrix( mBaseWorldMatrix, &( pProc->m_slave ), boneToWorld, pStudioHdr, pmViewTransform );
if ( flWeight < 1.0f )
{
Quaternion qBaseOrientation;
MatrixQuaternion( mBaseWorldMatrix, qBaseOrientation );
QuaternionSlerp( qBaseOrientation, qTargetOrientation, flWeight, qFinalOrientation );
}
else
{
qFinalOrientation = qTargetOrientation;
}
// Quaternion matrix wipes out the translate component
Vector vTmpPosition;
MatrixPosition( mBaseWorldMatrix, vTmpPosition );
QuaternionMatrix( qFinalOrientation, vTmpPosition, mBaseWorldMatrix );
}
//-----------------------------------------------------------------------------
// studio interface
//
// pmViewTransform is for hlmv which modifies the actual parentless bones
// to position things in the viewer
//
// TODO: Split into hlmv and "normal" versions, i.e. hlmv needs ViewTransform
//-----------------------------------------------------------------------------
void CStudioConstraintBones::ComputeAimConstraint(
const mstudiobone_t *pBones,
int nBone,
CBoneAccessor &boneToWorld,
const CStudioHdr *pStudioHdr,
const matrix3x4_t *pmViewTransform,
AimConstraintUpType_t eType )
{
BONE_PROFILE_FUNC();
mstudioaimconstraint_t *pProc = ( mstudioaimconstraint_t * )pBones[nBone].pProcedure();
// Calculate the current target position and the total weight
// of the the targets contributing to the target position.
Vector vTargetPos;
const float flWeight = CStudioConstraintBones::ComputeTargetPosition( vTargetPos, pProc->pTarget( 0 ), pProc->m_nTargetCount, boneToWorld );
Vector vTargetWorldPos;
matrix3x4a_t mSlaveParentToWorld;
const int nParentBone = pBones[nBone].parent;
if ( pmViewTransform )
{
matrix3x4_t mInv;
MatrixInvert( *pmViewTransform, mInv );
VectorTransform( vTargetPos, mInv, vTargetWorldPos );
if ( nParentBone >= 0 )
{
ConcatTransforms( mInv, boneToWorld[nParentBone], mSlaveParentToWorld );
}
else
{
SetIdentityMatrix( mSlaveParentToWorld );
}
}
else
{
VectorCopy( vTargetPos, vTargetWorldPos );
if ( nParentBone >= 0 )
{
MatrixCopy( boneToWorld[nParentBone], mSlaveParentToWorld );
}
else
{
SetIdentityMatrix( mSlaveParentToWorld );
}
}
Quaternion qTargetOrientation;
CConstraintBones::ComputeAimConstraint(
qTargetOrientation,
vTargetWorldPos,
mSlaveParentToWorld,
pProc->m_vUp,
pProc->m_slave.m_vBasePosition,
pProc->m_nUpSpaceTarget >= 0 ? &boneToWorld[ pProc->m_nUpSpaceTarget ] : NULL,
eType );
// Add in initial offset
Quaternion qOffsetOrientation;
QuaternionMult( qTargetOrientation, pProc->m_qAimOffset, qOffsetOrientation );
// Add in parent matrix
Quaternion qParentToWorld;
MatrixQuaternion( mSlaveParentToWorld, qParentToWorld );
Quaternion qTmp;
QuaternionMult( qParentToWorld, qOffsetOrientation, qTmp );
qOffsetOrientation = qTmp;
// Blend between the target orientation and the base orientation using the target weight
Quaternion qFinalOrientation;
matrix3x4a_t &mBaseWorldMatrix = boneToWorld.GetBoneForWrite( nBone );
CStudioConstraintBones::ComputeBaseWorldMatrix( mBaseWorldMatrix, &( pProc->m_slave ), boneToWorld, pStudioHdr, pmViewTransform );
if ( flWeight < 1.0f )
{
Quaternion qBaseOrientation;
MatrixQuaternion( mBaseWorldMatrix, qBaseOrientation );
QuaternionSlerp( qBaseOrientation, qOffsetOrientation, flWeight, qFinalOrientation );
}
else
{
qFinalOrientation = qOffsetOrientation;
}
if ( pmViewTransform )
{
Quaternion qTmp0;
Quaternion qTmp1;
MatrixQuaternion( *pmViewTransform, qTmp0 );
QuaternionMult( qTmp0, qFinalOrientation, qTmp1 );
qFinalOrientation = qTmp1;
}
// Quaternion matrix wipes out the translate component
Vector vTmpPosition;
MatrixPosition( mBaseWorldMatrix, vTmpPosition );
QuaternionMatrix( qFinalOrientation, vTmpPosition, mBaseWorldMatrix );
}
//-----------------------------------------------------------------------------
// studio interface
//-----------------------------------------------------------------------------
void CStudioConstraintBones::ComputeParentConstraint(
const mstudiobone_t *pBones,
int nBone,
CBoneAccessor &boneToWorld,
const CStudioHdr *pStudioHdr )
{
BONE_PROFILE_FUNC();
mstudioorientconstraint_t *pProc = ( mstudioorientconstraint_t * )pBones[nBone].pProcedure();
// Calculate the current target position and the total weight
// of the the targets contributing to the target position.
Vector vTargetPosition;
Quaternion qTargetOrientation;
const float flWeight = CStudioConstraintBones::ComputeTargetPositionOrientation( vTargetPosition, qTargetOrientation, pProc->pTarget( 0 ), pProc->m_nTargetCount, boneToWorld );
// Blend between the target orientation and the base orientation using the target weight
Quaternion qFinalOrientation;
Vector vFinalPosition;
matrix3x4a_t &mBaseWorldMatrix = boneToWorld.GetBoneForWrite( nBone );
CStudioConstraintBones::ComputeBaseWorldMatrix( mBaseWorldMatrix, &( pProc->m_slave ), boneToWorld, pStudioHdr );
if ( flWeight < 1.0f )
{
Vector vBasePosition;
Quaternion qBaseOrientation;
MatrixAngles( mBaseWorldMatrix, qBaseOrientation, vBasePosition );
QuaternionSlerp( qBaseOrientation, qTargetOrientation, flWeight, qFinalOrientation );
VectorLerp( vBasePosition, vTargetPosition, flWeight, vFinalPosition );
}
else
{
qFinalOrientation = qTargetOrientation;
vFinalPosition = vTargetPosition;
}
QuaternionMatrix( qFinalOrientation, vFinalPosition, mBaseWorldMatrix );
}
//-----------------------------------------------------------------------------
//
// Twist bones are bones which take a portion of the rotation around a specified
// axis.
//
// The axis is defined as the vector between a parent and child bone
// The twist bones must also be children of the parent
//
// + parent
// |
// +--+ twist 0.25
// |
// +--+ twist 0.5
// |
// +--+ twist 0.75
// |
// +--+ child
//
// If inverse is false each twist takes a portion of the child rotation around
// the specified axis
//
// If inverse is true each twist takes a portion of the parent rotation around
// the specified axis from a specified reference orientation
//
// All specified matrices & Quaternions are local to the bone, they are not
// worldToBone transformations
//
// pqTwists, pflWeights, pqTwistBinds are all pointers to arrays which must be
// at least nCount in size
//
// This code is called directly from:
// maya, datamodel & CalcProceduralBone/DoTwistBones
//-----------------------------------------------------------------------------
void ComputeTwistBones(
Quaternion *pqTwists,
int nCount,
bool bInverse,
const Vector &vUp,
const Quaternion &qParent,
const matrix3x4_t &mChild,
const Quaternion &qBaseInv,
const float *pflWeights,
const Quaternion *pqTwistBinds )
{
const float flEps = FLT_EPSILON * 10.0f;
const float flEpsSq = flEps * flEps;
Vector vUpRotate;
Vector vLocalTranslation;
Vector vRotatedTranslation;
Quaternion qTmp0;
Quaternion qTmp1;
{
Quaternion qChild;
MatrixAngles( mChild, qChild, vLocalTranslation );
// Check for 0 length translation - perhaps use Vector::IsZero?
if ( vLocalTranslation.LengthSqr() < flEpsSq )
{
// No translation, can't compute rotation axis, do nothing
V_memcpy( pqTwists, pqTwistBinds, nCount * sizeof( Quaternion ) );
return;
}
VectorNormalize( vLocalTranslation );
if ( bInverse )
{
QuaternionMult( qBaseInv, qParent, qTmp0 );
VectorRotate( vUp, qTmp0, vUpRotate );
VectorRotate( vLocalTranslation, qTmp0, vRotatedTranslation );
}
else
{
QuaternionMult( qBaseInv, qChild, qTmp0 );
VectorRotate( vUp, qTmp0, vUpRotate );
VectorRotate( vLocalTranslation, qBaseInv, vRotatedTranslation );
}
}
// If the specified up axis and the rotated translation vector are parallel then quit
if ( 1.0f - FloatMakePositive( DotProduct( vRotatedTranslation, vUp ) ) < flEps )
{
V_memcpy( pqTwists, pqTwistBinds, nCount * sizeof( Quaternion ) );
return;
}
// If the rotated up axis and the rotated translation vector are parallel then quit
if ( 1.0f - FloatMakePositive( DotProduct( vRotatedTranslation, vUpRotate ) ) < flEps )
{
V_memcpy( pqTwists, pqTwistBinds, nCount * sizeof( Quaternion ) );
return;
}
// Project Up (V) & Rotated Up (V) into the plane defined by the
// rotated up vector (N)
//
// U = V - ( V dot N ) N;
//
// U is V projected into plane with normal N
Vector vTmp0;
vTmp0 = vRotatedTranslation;
Vector vUpProject;
vTmp0 *= DotProduct( vUp, vRotatedTranslation );
VectorSubtract( vUp, vTmp0, vUpProject );
VectorNormalize( vUpProject );
vTmp0 = vRotatedTranslation;
Vector vUpRotateProject;
vTmp0 *= DotProduct( vUpRotate, vRotatedTranslation );
VectorSubtract( vUpRotate, vTmp0, vUpRotateProject );
VectorNormalize( vUpRotateProject );
if ( VectorsAreEqual( vUpProject, vUpRotateProject, 0.001 ) )
{
V_memcpy( pqTwists, pqTwistBinds, nCount * sizeof( Quaternion ) );
}
else
{
CrossProduct( vUpProject, vUpRotateProject, vTmp0 );
VectorNormalize( vTmp0 );
const float flDot = DotProduct( vUpProject, vUpRotateProject );
const float flAngle = DotProduct( vTmp0, vRotatedTranslation ) < 0.0f ? -acos( flDot ) : acos( flDot );
AxisAngleQuaternion( vLocalTranslation, RAD2DEG( flAngle ), qTmp0 );
if ( bInverse )
{
for ( int i = 0; i < nCount; ++i )
{
QuaternionScale( qTmp0, pflWeights[i] - 1.0f, qTmp1 );
QuaternionMult( qTmp1, pqTwistBinds[i], pqTwists[i] );
}
}
else
{
for ( int i = 0; i < nCount; ++i )
{
QuaternionScale( qTmp0, pflWeights[i], qTmp1 );
QuaternionMult( qTmp1, pqTwistBinds[i], pqTwists[i] );
}
}
}
}

1681
bonesetup/bone_decode.cpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2226
bonesetup/bone_ik.cpp Normal file

File diff suppressed because it is too large Load Diff

1509
bonesetup/bone_ik_PS3.cpp Normal file

File diff suppressed because it is too large Load Diff

1559
bonesetup/bone_setup.cpp Normal file

File diff suppressed because it is too large Load Diff

1556
bonesetup/bone_setup_PS3.cpp Normal file

File diff suppressed because it is too large Load Diff

3745
bonesetup/bone_utils.cpp Normal file

File diff suppressed because it is too large Load Diff

91
bonesetup/bone_utils.h Normal file
View File

@@ -0,0 +1,91 @@
DLL_IMPORT CLinkedMiniProfiler *g_pPhysicsMiniProfilers;
#if 0
#define BONE_PROFILE(ID) static CLinkedMiniProfiler s_miniprofiler_##ID(#ID, &g_pPhysicsMiniProfilers); \
CMiniProfilerGuard mpguard_##ID(&s_miniprofiler_##ID);
#define BONE_PROFILE_LOOP(ID,COUNT) static CLinkedMiniProfiler s_miniprofiler_##ID(#ID, &g_pPhysicsMiniProfilers); \
CMiniProfilerGuard mpguard_##ID(&s_miniprofiler_##ID,(COUNT));
#define BONE_PROFILE_FUNC() static CLinkedMiniProfiler s_miniprofiler_FUNC(__FUNCTION__, &g_pPhysicsMiniProfilers); \
CMiniProfilerGuard mpguard_##ID(&s_miniprofiler_FUNC);
#else
#define BONE_PROFILE(ID)
#define BONE_PROFILE_LOOP(ID,COUNT)
#define BONE_PROFILE_FUNC()
#endif
template <typename T>
class CBoneSetupMemoryPool
{
public:
T *Alloc()
{
T *p = (T *)m_FreeBlocks.Pop();
if ( !p )
{
p = (T *)MemAlloc_AllocAligned( sizeof( T ) * MAXSTUDIOBONES, 16 );
if ( ((size_t)p) % MAX(TSLIST_NODE_ALIGNMENT,16) != 0 )
DebuggerBreak();
}
return p;
}
void Free( T *p )
{
m_FreeBlocks.Push( (TSLNodeBase_t *)p );
}
private:
CTSListBase m_FreeBlocks;
};
extern CBoneSetupMemoryPool<BoneQuaternionAligned> g_QuaternionPool;
extern CBoneSetupMemoryPool<BoneVector> g_VectorPool;
extern CBoneSetupMemoryPool<matrix3x4a_t> g_MatrixPool;
void CalcDecompressedAnimation( const mstudiocompressedikerror_t *pCompressed, int iFrame, float fraq, BoneVector &pos, BoneQuaternion &q );
void QuaternionAccumulate( const Quaternion &p, float s, const Quaternion &q, Quaternion &qt );
void CalcAnimation( const CStudioHdr *pStudioHdr, BoneVector *pos, BoneQuaternion *q, mstudioseqdesc_t &seqdesc, int sequence, int animation, float cycle, int boneMask );
void BlendBones( const CStudioHdr *pStudioHdr, BoneQuaternionAligned q1[MAXSTUDIOBONES], BoneVector pos1[MAXSTUDIOBONES], mstudioseqdesc_t &seqdesc, int sequence, const BoneQuaternionAligned q2[MAXSTUDIOBONES], const BoneVector pos2[MAXSTUDIOBONES], float s, int boneMask );
void ScaleBones( const CStudioHdr *pStudioHdr, BoneQuaternion q1[MAXSTUDIOBONES], BoneVector pos1[MAXSTUDIOBONES], int sequence, float s, int boneMask );
void CalcPose( const CStudioHdr *pStudioHdr, CIKContext *pIKContext, BoneVector pos[], BoneQuaternionAligned q[], int sequence, float cycle, const float poseParameter[], int boneMask, float flWeight = 1.0f, float flTime = 0.0f );
bool CalcPoseSingle( const CStudioHdr *pStudioHdr, BoneVector pos[], BoneQuaternionAligned q[], mstudioseqdesc_t &seqdesc, int sequence, float cycle, const float poseParameter[], int boneMask, float flTime );
void CalcBoneAdj( const CStudioHdr *pStudioHdr, BoneVector pos[], BoneQuaternion q[], const float controllers[], int boneMask );
void BuildBoneChainPartial(
const CStudioHdr *pStudioHdr,
const matrix3x4_t &rootxform,
const BoneVector pos[],
const BoneQuaternion q[],
int iBone,
matrix3x4_t *pBoneToWorld,
CBoneBitList &boneComputed,
int iRoot );
class CBoneSetup
{
public:
CBoneSetup( const CStudioHdr *pStudioHdr, int boneMask, const float poseParameter[], IPoseDebugger *pPoseDebugger = NULL );
void InitPose( BoneVector pos[], BoneQuaternionAligned q[] );
void AccumulatePose( BoneVector pos[], BoneQuaternion q[], int sequence, float cycle, float flWeight, float flTime, CIKContext *pIKContext );
void CalcAutoplaySequences( BoneVector pos[], BoneQuaternion q[], float flRealTime, CIKContext *pIKContext );
private:
void AddSequenceLayers( BoneVector pos[], BoneQuaternion q[], mstudioseqdesc_t &seqdesc, int sequence, float cycle, float flWeight, float flTime, CIKContext *pIKContext );
void AddLocalLayers( BoneVector pos[], BoneQuaternion q[], mstudioseqdesc_t &seqdesc, int sequence, float cycle, float flWeight, float flTime, CIKContext *pIKContext );
public:
const CStudioHdr *m_pStudioHdr;
int m_boneMask;
const float *m_flPoseParameter;
IPoseDebugger *m_pPoseDebugger;
};

2120
bonesetup/bone_utils_PS3.cpp Normal file

File diff suppressed because it is too large Load Diff

359
bonesetup/bone_utils_PS3.h Normal file
View File

@@ -0,0 +1,359 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef BONE_UTILS_PS3_H
#define BONE_UTILS_PS3_H
#ifndef _PS3
#error "This header is for PS3 target only"
#endif
#include "vjobs_interface.h"
#if defined(__SPU__)
#include "ps3/spu_job_shared.h"
#include "cell/dma.h"
#endif
#if 1
#define DotProduct_PS3 DotProduct
#define MatrixAngles_PS3 MatrixAngles
#define VectorRotate_PS3 VectorRotate
#define VectorSubtract_PS3 VectorSubtract
#define MatrixPosition_PS3 MatrixPosition
#define _VMX_VectorNormalize_PS3 _VMX_VectorNormalize
#define VectorNormalize_PS3 VectorNormalize
#define VectorMultiply_PS3 VectorMultiply
#define VectorScale_PS3 VectorScale
#define VectorMAInline_PS3 VectorMAInline
#define VectorMA_PS3 VectorMA
#define SimpleSpline_PS3 SimpleSpline
#define ConcatTransforms_PS3 ConcatTransforms
#define ConcatTransforms_Aligned_PS3 ConcatTransforms_Aligned
//#define QuaternionMatrix_PS3 QuaternionMatrix
//#define QuaternionAlign_PS3 QuaternionAlign
//#define QuaternionSlerp_PS3 QuaternionSlerp
//#define QuaternionSlerpNoAlign_PS3 QuaternionSlerpNoAlign
//#define QuaternionNormalize_PS3 QuaternionNormalize
//#define QuaternionBlend_PS3 QuaternionBlend
//#define QuaternionBlendNoAlign_PS3 QuaternionBlendNoAlign
//#define QuaternionIdentityBlend_PS3 QuaternionIdentityBlend
//#define QuaternionScale_PS3 QuaternionScale
//#define QuaternionAdd_PS3 QuaternionAdd
//#define QuaternionDotProduct_PS3 QuaternionDotProduct
//#define QuaternionMult_PS3 QuaternionMult
#define MatrixSetColumn_PS3 MatrixSetColumn
#define MatrixGetColumn_PS3 MatrixGetColumn
#define MatrixInvert_PS3 MatrixInvert
#define VectorRotate_PS3 VectorRotate
#define AngleMatrix_PS3 AngleMatrix
#define AngleQuaternion_PS3 AngleQuaternion
#define Hermite_Spline_PS3 Hermite_Spline
#define Hermite_SplineBasis_PS3 Hermite_SplineBasis
#define SetIdentityMatrix_PS3 SetIdentityMatrix
FORCEINLINE Vector Lerp_PS3( float flPercent, Vector const &A, Vector const &B )
{
return A + (B - A) * flPercent;
}
#endif
// from mathlib.h, mathlib_base.cpp
#if 0
FORCEINLINE float DotProduct_PS3(const Vector& a, const Vector& b)
{
// return( a.x*b.x + a.y*b.y + a.z*b.z );
return a.Dot(b);
}
FORCEINLINE float DotProduct_PS3(const float* a, const float* b)
{
return( a[0]*b[0] + a[1]*b[1] + a[2]*b[2] );
}
void ConcatTransforms_PS3( const matrix3x4a_t &m0, const matrix3x4a_t &m1, matrix3x4a_t &out );
void ConcatTransforms_Aligned_PS3( const matrix3x4a_t &m0, const matrix3x4a_t &m1, matrix3x4a_t &out );
void MatrixAngles_PS3( const matrix3x4_t & matrix, float *angles ); // !!!!
void MatrixAngles_PS3( const matrix3x4_t& matrix, RadianEuler &angles, Vector &position );
void MatrixAngles_PS3( const matrix3x4_t &matrix, Quaternion &q, Vector &pos );
inline void MatrixAngles_PS3( const matrix3x4_t &matrix, RadianEuler &angles )
{
MatrixAngles_PS3( matrix, &angles.x );
angles.Init( DEG2RAD( angles.z ), DEG2RAD( angles.x ), DEG2RAD( angles.y ) );
}
void MatrixGetColumn_PS3( const matrix3x4_t& in, int column, Vector &out );
void MatrixSetColumn_PS3( const Vector &in, int column, matrix3x4_t& out );
void MatrixInvert_PS3( const matrix3x4_t& in, matrix3x4_t& out );
void VectorRotate_PS3( const float *in1, const matrix3x4_t & in2, float *out);
inline void VectorRotate_PS3( const Vector& in1, const matrix3x4_t &in2, Vector &out)
{
VectorRotate_PS3( &in1.x, in2, &out.x );
}
FORCEINLINE void VectorSubtract_PS3( const Vector& a, const Vector& b, Vector& c )
{
c.x = a.x - b.x;
c.y = a.y - b.y;
c.z = a.z - b.z;
}
inline void MatrixPosition_PS3( const matrix3x4_t &matrix, Vector &position )
{
position[0] = matrix[0][3];
position[1] = matrix[1][3];
position[2] = matrix[2][3];
}
FORCEINLINE float _VMX_VectorNormalize_PS3( Vector &vec )
{
vec_float4 vIn;
vec_float4 v0, v1;
vector unsigned char permMask;
v0 = vec_ld( 0, vec.Base() );
permMask = vec_lvsl( 0, vec.Base() );
v1 = vec_ld( 11, vec.Base() );
vIn = vec_perm(v0, v1, permMask);
float mag = vmathV3Length((VmathVector3 *)&vIn);
float den = 1.f / (mag + FLT_EPSILON );
vec.x *= den;
vec.y *= den;
vec.z *= den;
return mag;
}
FORCEINLINE float VectorNormalize_PS3( Vector& v )
{
return _VMX_VectorNormalize_PS3( v );
}
FORCEINLINE void VectorMultiply_PS3( const Vector& a, float b, Vector& c )
{
c.x = a.x * b;
c.y = a.y * b;
c.z = a.z * b;
}
FORCEINLINE void VectorMultiply_PS3( const Vector& a, const Vector& b, Vector& c )
{
c.x = a.x * b.x;
c.y = a.y * b.y;
c.z = a.z * b.z;
}
inline void VectorScale_PS3 ( const Vector& in, float scale, Vector& result )
{
VectorMultiply_PS3( in, scale, result );
}
FORCEINLINE Vector Lerp_PS3( float flPercent, Vector const &A, Vector const &B )
{
return A + (B - A) * flPercent;
}
FORCEINLINE void VectorMAInline_PS3( const float* start, float scale, const float* direction, float* dest )
{
dest[0]=start[0]+direction[0]*scale;
dest[1]=start[1]+direction[1]*scale;
dest[2]=start[2]+direction[2]*scale;
}
FORCEINLINE void VectorMAInline_PS3( const Vector& start, float scale, const Vector& direction, Vector& dest )
{
dest.x=start.x+direction.x*scale;
dest.y=start.y+direction.y*scale;
dest.z=start.z+direction.z*scale;
}
FORCEINLINE void VectorMA_PS3( const Vector& start, float scale, const Vector& direction, Vector& dest )
{
VectorMAInline_PS3(start, scale, direction, dest);
}
FORCEINLINE void VectorMA_PS3( const float * start, float scale, const float *direction, float *dest )
{
VectorMAInline_PS3(start, scale, direction, dest);
}
void AngleMatrix_PS3( RadianEuler const &angles, const Vector &position, matrix3x4_t& matrix );
void AngleMatrix_PS3( const RadianEuler& angles, matrix3x4_t& matrix );
void AngleMatrix_PS3( const QAngle &angles, const Vector &position, matrix3x4_t& matrix );
void AngleMatrix_PS3( const QAngle &angles, matrix3x4_t& matrix );
void AngleQuaternion_PS3( const RadianEuler &angles, Quaternion &outQuat );
void Hermite_Spline_PS3( const Vector &p1, const Vector &p2, const Vector &d1, const Vector &d2, float t, Vector& output );
float Hermite_Spline_PS3( float p1, float p2, float d1, float d2, float t );
void Hermite_SplineBasis_PS3( float t, float basis[4] );
void Hermite_Spline_PS3( const Vector &p0, const Vector &p1, const Vector &p2, float t, Vector& output );
float Hermite_Spline_PS3( float p0, float p1, float p2, float t );
void Hermite_Spline_PS3( const Quaternion &q0, const Quaternion &q1, const Quaternion &q2, float t, Quaternion &output );
inline float SimpleSpline_PS3( float value )
{
float valueSquared = value * value;
// Nice little ease-in, ease-out spline-like curve
return (3.0f * valueSquared - 2.0f * valueSquared * value);
}
#endif
void QuaternionMatrix_PS3( const Quaternion &q, const Vector &pos, matrix3x4a_t& matrix );
void QuaternionAlign_PS3( const Quaternion &p, const Quaternion &q, QuaternionAligned &qt );
void QuaternionSlerp_PS3( const Quaternion &p, const Quaternion &q, float t, Quaternion &qt );
void QuaternionSlerpNoAlign_PS3( const Quaternion &p, const Quaternion &q, float t, Quaternion &qt );
float QuaternionNormalize_PS3( Quaternion &q );
void QuaternionBlend_PS3( const Quaternion &p, const Quaternion &q, float t, Quaternion &qt );
void QuaternionBlendNoAlign_PS3( const Quaternion &p, const Quaternion &q, float t, Quaternion &qt );
void QuaternionIdentityBlend_PS3( const Quaternion &p, float t, Quaternion &qt );
void QuaternionScale_PS3( const Quaternion &p, float t, Quaternion &q );
void QuaternionAdd_PS3( const Quaternion &p, const Quaternion &q, Quaternion &qt );
float QuaternionDotProduct_PS3( const Quaternion &p, const Quaternion &q );
void QuaternionMult_PS3( const Quaternion &p, const Quaternion &q, Quaternion &qt );
void AddDependencies_SPU( bonejob_SPU *pBonejobSPU, accumposeentry_SPU *pPoseEntry, float flWeight = 1.0f );
//void AddDependencies_PPU( CStudioHdr *pHdr, float m_flTime, int m_boneMask, mstudioseqdesc_t &seqdesc, int iSequence, float flCycle, const float poseParameters[], float flWeight );
void GetBoneMapBoneWeight_SPU( bonejob_SPU *pSPUJob, accumposeentry_SPU *pPoseEntry, int *&pLS_boneMap, float *&pLS_boneWeight );
void CalcDecompressedAnimation_PS3( void *pEA_Compressed, const mstudiocompressedikerror_t_PS3 *pLS_Compressed, int iFrame, float fraq, BoneVector &pos, BoneQuaternion &q );
void QuaternionAccumulate_PS3( const Quaternion &p, float s, const Quaternion &q, Quaternion &qt );
void CalcAnimation_PS3( const bonejob_SPU *pBonejob, const accumposeentry_SPU *pPoseEntry, BoneVector *pos, BoneQuaternion *q, const int *boneMap, const float *boneWeight, int animIndex, float cycle, int boneMask );
void BlendBones_PS3( const bonejob_SPU *pBonejob, const accumposeentry_SPU *pPoseEntry, BoneQuaternion *q1, BoneVector *pos1, const int *boneMap, const float *boneWeight, const BoneQuaternion *q2, const BoneVector *pos2, float s, int boneMask );
void ScaleBones_PS3( const bonejob_SPU *pBonejob, const accumposeentry_SPU *pPoseEntry, BoneQuaternion *q1, BoneVector *pos1, const int *boneMap, const float *boneWeight, float s, int boneMask );
// void CalcPose( const CStudioHdr *pStudioHdr, CIKContext *pIKContext, Vector pos[], BoneQuaternion q[], int sequence, float cycle, const float poseParameter[], int boneMask, float flWeight = 1.0f, float flTime = 0.0f );
//bool CalcPoseSingle( const CStudioHdr *pStudioHdr, Vector pos[], BoneQuaternion q[], mstudioseqdesc_t &seqdesc, int sequence, float cycle, const float poseParameter[], int boneMask, float flTime );
// void CalcBoneAdj( const CStudioHdr *pStudioHdr, Vector pos[], Quaternion q[], const float controllers[], int boneMask );
void BuildBoneChainPartial_PS3(
const int *pBoneParent,
const matrix3x4a_t &rootxform,
const BoneVector pos[],
const BoneQuaternion q[],
int iBone,
matrix3x4a_t *pBoneToWorld,
CBoneBitList_PS3 &boneComputed,
int iRoot );
struct PS3BoneJobData;
#define BONEJOB_ERROR_EXCEEDEDPQSTACK (1<<0)
#define BONEJOB_ERROR_EXCEEDEDMAXCALLS (1<<1)
#define BONEJOB_ERROR_LOCALHIER (1<<2)
#if !defined(__SPU__)
class CBoneSetup_PS3
{
public:
CBoneSetup_PS3( const CStudioHdr *pStudioHdr, int boneMask, const float poseParameter[], bonejob_SPU *pBoneJobSPU );
void CalcAutoplaySequences_AddPoseCalls( float flRealTime );
void AccumulatePose_AddToBoneJob( bonejob_SPU* pSPUJob, int sequence, float cycle, float flWeight, CIKContext *pIKContext, int pqStackLevel );
int RunAccumulatePoseJobs_PPU( bonejob_SPU *pBoneJob );
int RunAccumulatePoseJobs_SPU( bonejob_SPU *pBoneJob, job_accumpose::JobDescriptor_t *pJobDescriptor );
private:
bool SetAnimData( accumposeentry_SPU *pPoseEntry, const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int sequence, int x, int y, int animIndex, float weight );
bool CalcPoseSingle( accumposeentry_SPU *pPoseEntry, const CStudioHdr *pStudioHdr, mstudioseqdesc_t &seqdesc, int sequence, float cycle, const float poseParameter[], float flTime );
int AddSequenceLayers( bonejob_SPU *pSPUJob, mstudioseqdesc_t &seqdesc, int sequence, float cycle, float flWeight, CIKContext *pIKContext, int pqStackLevel );
int AddLocalLayers( bonejob_SPU *pSPUJob, mstudioseqdesc_t &seqdesc, int sequence, float cycle, float flWeight, CIKContext *pIKContext, int pqStackLevel );
public:
const CStudioHdr *m_pStudioHdr;
int m_boneMask;
const float *m_flPoseParameter;
bonejob_SPU *m_pBoneJobSPU;
int m_errorFlags; // accpose call failure flags (if so do not run on SPU, could be for a number of reasons, right now => exceeded PQ stack, or an anim uses the local hierarchy path
};
#endif // #if !defined(__SPU__)
//-------------------------------------------------------------------------------------------------------------
// SPU dummy funcs
//-------------------------------------------------------------------------------------------------------------
#define DMATAG_ANIM_SYNC_BONEMAPWEIGHT (DMATAG_ANIM+1)
#define DMATAG_ANIM_SYNC_POSQ (DMATAG_ANIM+2)
FORCEINLINE void *SPUmemcpy_UnalignedGet( void *ls, uint32 ea, uint32_t size )
{
void *aligned_ls;
aligned_ls = (void *)((uint32)ls | (ea & 0xf)); // + 0xf in case ls not 16B aligned
#if defined(__SPU__)
//spu_printf("GET ls:0x%x, ea:0x%x, size:%d\n", (uint32_t)aligned_ls, ea, size);
// SPU
cellDmaUnalignedGet( aligned_ls, ea, size, DMATAG_SYNC, 0, 0 );
cellDmaWaitTagStatusAny( 1 << DMATAG_SYNC );
#else
// PPU
memcpy( aligned_ls, (void *)ea, size );
#endif
return aligned_ls;
}
FORCEINLINE void *SPUmemcpy_UnalignedGet_MustSync( void *ls, uint32 ea, uint32_t size, uint32_t dmatag )
{
void *aligned_ls;
aligned_ls = (void *)((uint32)ls | (ea & 0xf)); // + 0xf in case ls not 16B aligned
#if defined(__SPU__)
//spu_printf("GET ls:0x%x, ea:0x%x, size:%d\n", (uint32_t)aligned_ls, ea, size);
// SPU
cellDmaUnalignedGet( aligned_ls, ea, size, dmatag, 0, 0 );
#else
// PPU
memcpy( aligned_ls, (void *)ea, size );
#endif
return aligned_ls;
}
FORCEINLINE void SPUmemcpy_Sync( uint32_t dmatag )
{
#if defined(__SPU__)
// cellDmaWaitTagStatusAll( 1 << dmatag );
cellDmaWaitTagStatusAll( dmatag );
#endif
}
FORCEINLINE void SPUmemcpy_UnalignedPut( void *ls, uint32 ea, uint32_t size )
{
#if defined(__SPU__)
//spu_printf("PUT ls:0x%x, ea:0x%x, size:%d\n", (uint32_t)ls, ea, size);
// SPU
cellDmaUnalignedPut( ls, ea, size, DMATAG_SYNC, 0, 0 );
cellDmaWaitTagStatusAny( 1 << DMATAG_SYNC );
#else
Assert(((uint32)ls&0xf) == ea&0xf);
// PPU
memcpy( (void *)ea, ls, size );
#endif
}
//=============================================================================//
//
//
//
//
//
//=============================================================================//
#endif

47
bonesetup/bonesetup.vpc Normal file
View File

@@ -0,0 +1,47 @@
//-----------------------------------------------------------------------------
// MATHLIB.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$macro SRCDIR ".."
$include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
$Configuration
{
$Compiler
{
$AdditionalIncludeDirectories "$BASE;..\public"
}
}
$Project "bonesetup"
{
$Folder "Source Files"
{
$File "bone_setup_PS3.cpp" [$PS3]
$File "bone_ik_PS3.cpp" [$PS3]
$File "bone_utils_PS3.cpp" [$PS3]
$File "bone_decode_PS3.cpp" [$PS3]
$File "bone_setup.cpp"
$File "bone_ik.cpp"
$File "bone_utils.cpp"
$File "bone_decode.cpp"
$File "bone_constraints.cpp"
}
$Folder "Header Files"
{
$File "bone_utils.h"
$File "bone_utils_PS3.h" [$PS3]
}
$Folder "Public Header Files"
{
$File "$SRCDIR\public\bone_setup.h" [$WINDOWS||$POSIX]
$File "$SRCDIR\public\bone_setup_PS3.h" [$PS3]
}
}

View File

@@ -0,0 +1,13 @@
"vpc_cache"
{
"CacheVersion" "1"
"win32"
{
"CRCFile" "bonesetup.vcxproj.vpc_crc"
"OutputFiles"
{
"0" "bonesetup.vcxproj"
"1" "bonesetup.vcxproj.filters"
}
}
}

2
bonesetup/vsi.nul Normal file
View File

@@ -0,0 +1,2 @@
SN Visual Studio Integration
IMPORTANT: Do not remove the custom build step for this file