Пример #1
0
    virtual void BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed )
    {
        VPROF_BUDGET( "C_ServerRagdollAttached::SetupBones", VPROF_BUDGETGROUP_CLIENT_ANIMATION );

        if ( !hdr )
            return;

        float frac = RemapVal( gpGlobals->curtime, m_parentTime, m_parentTime+ATTACH_INTERP_TIME, 0, 1 );
        frac = clamp( frac, 0.f, 1.f );
        // interpolate offset over some time
        Vector offset = m_vecOffset * (1-frac);

        C_BaseAnimating *parent = assert_cast< C_BaseAnimating* >( GetMoveParent() );
        Vector worldOrigin;
        worldOrigin.Init();


        if ( parent )
        {
            Assert( parent != this );
            parent->SetupBones( NULL, -1, BONE_USED_BY_ANYTHING, gpGlobals->curtime );

            matrix3x4_t boneToWorld;
            parent->GetCachedBoneMatrix( m_boneIndexAttached, boneToWorld );
            VectorTransform( m_attachmentPointBoneSpace, boneToWorld, worldOrigin );
        }
        BaseClass::BuildTransformations( hdr, pos, q, cameraTransform, boneMask, boneComputed );

        if ( parent )
        {
            int index = m_boneIndex[m_ragdollAttachedObjectIndex];
            const matrix3x4_t &matrix = GetBone( index );
            Vector ragOrigin;
            VectorTransform( m_attachmentPointRagdollSpace, matrix, ragOrigin );
            offset = worldOrigin - ragOrigin;
            // fixes culling
            SetAbsOrigin( worldOrigin );
            m_vecOffset = offset;
        }

        for ( int i = 0; i < hdr->numbones(); i++ )
        {
            if ( !( hdr->boneFlags( i ) & boneMask ) )
                continue;

            Vector pos;
            matrix3x4_t &matrix = GetBoneForWrite( i );
            MatrixGetColumn( matrix, 3, pos );
            pos += offset;
            MatrixSetColumn( pos, 3, matrix );
        }
    }
Пример #2
0
//-----------------------------------------------------------------------------
// Purpose: We need to slam our position!
//-----------------------------------------------------------------------------
void C_NPC_Puppet::BuildTransformations( CStudioHdr *pStudioHdr, Vector *pos, Quaternion q[], const matrix3x4_t& cameraTransform, int boneMask, CBoneBitList &boneComputed )
{
	if ( m_hAnimationTarget && m_nTargetAttachment != -1 )
	{
		C_BaseAnimating *pTarget = m_hAnimationTarget->GetBaseAnimating();
		if ( pTarget )
		{
			matrix3x4_t matTarget;
			pTarget->GetAttachment( m_nTargetAttachment, matTarget );

			MatrixCopy( matTarget, GetBoneForWrite( 0 ) );
			boneComputed.ClearAll(); // FIXME: Why is this calculated already?
			boneComputed.MarkBone( 0 );
		}
	}

	// Call the baseclass
	BaseClass::BuildTransformations( pStudioHdr, pos, q, cameraTransform, boneMask, boneComputed );
}
Пример #3
0
void C_ServerRagdoll::BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion q[], const matrix3x4_t &cameraTransform, int boneMask, CBoneBitList &boneComputed )
{
    if ( !hdr )
        return;
    matrix3x4_t bonematrix;
    bool boneSimulated[MAXSTUDIOBONES];

    // no bones have been simulated
    memset( boneSimulated, 0, sizeof(boneSimulated) );
    mstudiobone_t *pbones = hdr->pBone( 0 );

    mstudioseqdesc_t *pSeqDesc = NULL;
    if ( m_nOverlaySequence >= 0 && m_nOverlaySequence < hdr->GetNumSeq() )
    {
        pSeqDesc = &hdr->pSeqdesc( m_nOverlaySequence );
    }

    int i;
    for ( i = 0; i < m_elementCount; i++ )
    {
        int index = m_boneIndex[i];
        if ( index >= 0 )
        {
            if ( hdr->boneFlags(index) & boneMask )
            {
                boneSimulated[index] = true;
                matrix3x4_t &matrix = GetBoneForWrite( index );

                if ( m_flBlendWeightCurrent != 0.0f && pSeqDesc &&
                        // FIXME: this bone access is illegal
                        pSeqDesc->weight( index ) != 0.0f )
                {
                    // Use the animated bone position instead
                    boneSimulated[index] = false;
                }
                else
                {
                    AngleMatrix( m_ragAngles[i], m_ragPos[i], matrix );
                }
            }
        }
    }

    for ( i = 0; i < hdr->numbones(); i++ )
    {
        if ( !( hdr->boneFlags( i ) & boneMask ) )
            continue;

        // BUGBUG: Merge this code with the code in c_baseanimating somehow!!!
        // animate all non-simulated bones
        if ( boneSimulated[i] ||
                CalcProceduralBone( hdr, i, m_BoneAccessor ) )
        {
            continue;
        }
        else
        {
            QuaternionMatrix( q[i], pos[i], bonematrix );

            if (pbones[i].parent == -1)
            {
                ConcatTransforms( cameraTransform, bonematrix, GetBoneForWrite( i ) );
            }
            else
            {
                ConcatTransforms( GetBone( pbones[i].parent ), bonematrix, GetBoneForWrite( i ) );
            }
        }

        if ( pbones[i].parent == -1 )
        {
            // Apply client-side effects to the transformation matrix
            //	ApplyBoneMatrixTransform( GetBoneForWrite( i ) );
        }
    }
}
void C_GStringPlayerRagdoll::BuildTransformations( CStudioHdr *hdr, Vector *pos, Quaternion *q,
	const matrix3x4_t &cameraTransform, int boneMask, CBoneBitList &boneComputed )
{
	if ( !hdr )
		return;

	matrix3x4_t bonematrix;
	bool boneSimulated[MAXSTUDIOBONES];

	// no bones have been simulated
	memset( boneSimulated, 0, sizeof(boneSimulated) );
	mstudiobone_t *pbones = hdr->pBone( 0 );

	if ( m_pRagdoll )
	{
		// simulate bones and update flags
		int oldWritableBones = m_BoneAccessor.GetWritableBones();
		int oldReadableBones = m_BoneAccessor.GetReadableBones();
		m_BoneAccessor.SetWritableBones( BONE_USED_BY_ANYTHING );
		m_BoneAccessor.SetReadableBones( BONE_USED_BY_ANYTHING );
		
#if defined( REPLAY_ENABLED )
		// If we're playing back a demo, override the ragdoll bones with cached version if available - otherwise, simulate.
		if ( ( !engine->IsPlayingDemo() && !engine->IsPlayingTimeDemo() ) ||
				!CReplayRagdollCache::Instance().IsInitialized() ||
				!CReplayRagdollCache::Instance().GetFrame( this, engine->GetDemoPlaybackTick(), boneSimulated, &m_BoneAccessor ) )
#endif
		{
			m_pRagdoll->RagdollBone( this, pbones, hdr->numbones(), boneSimulated, m_BoneAccessor );
		}
		
		m_BoneAccessor.SetWritableBones( oldWritableBones );
		m_BoneAccessor.SetReadableBones( oldReadableBones );
	}

	// For EF_BONEMERGE entities, copy the bone matrices for any bones that have matching names.
	bool boneMerge = IsEffectActive(EF_BONEMERGE);
	if ( boneMerge || m_pBoneMergeCache )
	{
		if ( boneMerge )
		{
			if ( !m_pBoneMergeCache )
			{
				m_pBoneMergeCache = new CBoneMergeCache;
				m_pBoneMergeCache->Init( this );
			}
			m_pBoneMergeCache->MergeMatchingBones( boneMask );
		}
		else
		{
			delete m_pBoneMergeCache;
			m_pBoneMergeCache = NULL;
		}
	}

	for (int i = 0; i < hdr->numbones(); i++) 
	{
		if ( i == m_iBoneHead )
		{
			MatrixScaleBy( 0.01f, GetBoneForWrite( i ) );
		}

		// Only update bones reference by the bone mask.
		if ( !( hdr->boneFlags( i ) & boneMask ) )
		{
			continue;
		}

		if ( m_pBoneMergeCache && m_pBoneMergeCache->IsBoneMerged( i ) )
			continue;

		// animate all non-simulated bones
		if ( boneSimulated[i] || CalcProceduralBone( hdr, i, m_BoneAccessor ))
		{
			continue;
		}
		// skip bones that the IK has already setup
		else if (boneComputed.IsBoneMarked( i ))
		{
			// dummy operation, just used to verify in debug that this should have happened
			GetBoneForWrite( i );
		}
		else
		{
			QuaternionMatrix( q[i], pos[i], bonematrix );

			Assert( fabs( pos[i].x ) < 100000 );
			Assert( fabs( pos[i].y ) < 100000 );
			Assert( fabs( pos[i].z ) < 100000 );

			if ( (hdr->boneFlags( i ) & BONE_ALWAYS_PROCEDURAL) && 
					(hdr->pBone( i )->proctype & STUDIO_PROC_JIGGLE) )
			{
				//
				// Physics-based "jiggle" bone
				// Bone is assumed to be along the Z axis
				// Pitch around X, yaw around Y
				//

				// compute desired bone orientation
				matrix3x4_t goalMX;

				if (pbones[i].parent == -1) 
				{
					ConcatTransforms( cameraTransform, bonematrix, goalMX );
				} 
				else 
				{
					ConcatTransforms( GetBone( pbones[i].parent ), bonematrix, goalMX );
				}

				// get jiggle properties from QC data
				mstudiojigglebone_t *jiggleInfo = (mstudiojigglebone_t *)pbones[i].pProcedure( );

				if (!m_pJiggleBones)
				{
					m_pJiggleBones = new CJiggleBones;
				}

				// do jiggle physics
				m_pJiggleBones->BuildJiggleTransformations( i, gpGlobals->realtime, jiggleInfo, goalMX, GetBoneForWrite( i ) );

			}
			else if (hdr->boneParent(i) == -1) 
			{
				ConcatTransforms( cameraTransform, bonematrix, GetBoneForWrite( i ) );
			} 
			else 
			{
				ConcatTransforms( GetBone( hdr->boneParent(i) ), bonematrix, GetBoneForWrite( i ) );
			}
		}
	}
}