void CRagdollProp::SetupBones( matrix3x4_t *pBoneToWorld, int boneMask )
{
	studiohdr_t *pStudioHdr = GetModelPtr( );
	bool sim[MAXSTUDIOBONES];
	memset( sim, 0, pStudioHdr->numbones );

	int i;

	for ( i = 0; i < m_ragdoll.listCount; i++ )
	{
		if ( RagdollGetBoneMatrix( m_ragdoll, pBoneToWorld, i ) )
		{
			sim[m_ragdoll.boneIndex[i]] = true;
		}
	}

	mstudiobone_t *pbones = pStudioHdr->pBone( 0 );
	for ( i = 0; i < pStudioHdr->numbones; i++ )
	{
		if ( sim[i] )
			continue;

		MatrixCopy( pBoneToWorld[pbones[i].parent], pBoneToWorld[ i ] );
	}
}
示例#2
0
文件: ragdoll.cpp 项目: BoXorz/MSS
void CRagdoll::RagdollBone( C_BaseEntity *ent, mstudiobone_t *pbones, int boneCount, bool *boneSimulated, CBoneAccessor &pBoneToWorld )
{
    for ( int i = 0; i < m_ragdoll.listCount; i++ )
    {
        if ( RagdollGetBoneMatrix( m_ragdoll, pBoneToWorld, i ) )
        {
            boneSimulated[m_ragdoll.boneIndex[i]] = true;
        }
    }
}
示例#3
0
void CRagdollProp::SetupBones( matrix3x4_t *pBoneToWorld, int boneMask )
{
	// no ragdoll, fall through to base class 
	if ( !m_ragdoll.listCount )
	{
		BaseClass::SetupBones( pBoneToWorld, boneMask );
		return;
	}

	// Not really ideal, but it'll work for now
	UpdateModelWidthScale();

	MDLCACHE_CRITICAL_SECTION();
	CStudioHdr *pStudioHdr = GetModelPtr( );
	bool sim[MAXSTUDIOBONES];
	memset( sim, 0, pStudioHdr->numbones() );

	int i;

	CBoneAccessor boneaccessor( pBoneToWorld );
	for ( i = 0; i < m_ragdoll.listCount; i++ )
	{
		// during restore this may be NULL
		if ( !m_ragdoll.list[i].pObject )
			continue;

		if ( RagdollGetBoneMatrix( m_ragdoll, boneaccessor, i ) )
		{
			sim[m_ragdoll.boneIndex[i]] = true;
		}
	}

	mstudiobone_t *pbones = pStudioHdr->pBone( 0 );
	for ( i = 0; i < pStudioHdr->numbones(); i++ )
	{
		if ( sim[i] )
			continue;
		
		if ( !(pbones[i].flags & boneMask) )
			continue;

		matrix3x4_t matBoneLocal;
		AngleMatrix( pbones[i].rot, pbones[i].pos, matBoneLocal );
		ConcatTransforms( pBoneToWorld[pbones[i].parent], matBoneLocal, pBoneToWorld[i]);
	}
}
void CRagdollProp::VPhysicsUpdate( IPhysicsObject *pPhysics )
{
	if ( m_lastUpdateTickCount == (unsigned int)gpGlobals->tickcount )
		return;

	m_lastUpdateTickCount = gpGlobals->tickcount;
	NetworkStateChanged();

	matrix3x4_t boneToWorld[MAXSTUDIOBONES];
	QAngle angles;
	for ( int i = 0; i < m_ragdoll.listCount; i++ )
	{
		RagdollGetBoneMatrix( m_ragdoll, boneToWorld, i );
		
		Vector vNewPos;
		MatrixAngles( boneToWorld[m_ragdoll.boneIndex[i]], angles, vNewPos );
		m_ragPos.Set( i, vNewPos );
		m_ragAngles.Set( i, angles );
	}

	m_allAsleep = RagdollIsAsleep( m_ragdoll );
	SetAbsOrigin( m_ragPos[0] );
	engine->RelinkEntity( pev, true );
}
示例#5
0
void CRagdollProp::VPhysicsUpdate( IPhysicsObject *pPhysics )
{
	if ( m_lastUpdateTickCount == (unsigned int)gpGlobals->tickcount )
		return;

	m_lastUpdateTickCount = gpGlobals->tickcount;
	//NetworkStateChanged();

	matrix3x4_t boneToWorld[MAXSTUDIOBONES];
	QAngle angles;
	Vector surroundingMins, surroundingMaxs;
	if ( m_ragdoll.pGroup->IsInErrorState() )
	{
		RagdollSolveSeparation( m_ragdoll, this );
	}

	int i;
	for ( i = 0; i < m_ragdoll.listCount; i++ )
	{
		CBoneAccessor boneaccessor( boneToWorld );
		RagdollGetBoneMatrix( m_ragdoll, boneaccessor, i );
		
		Vector vNewPos;
		MatrixAngles( boneToWorld[m_ragdoll.boneIndex[i]], angles, vNewPos );
		m_ragPos.Set( i, vNewPos );
		m_ragAngles.Set( i, angles );
	}

	// BUGBUG: Use the ragdollmins/maxs to do this instead of the collides
	m_allAsleep = RagdollIsAsleep( m_ragdoll );

	// Don't scream after you've come to rest
	if ( m_allAsleep )
	{
		m_strSourceClassName = NULL_STRING;
	}
	
	// Interactive debris converts back to debris when it comes to rest
	if ( m_allAsleep && GetCollisionGroup() == COLLISION_GROUP_INTERACTIVE_DEBRIS )
	{
		SetCollisionGroup( COLLISION_GROUP_DEBRIS );
		RecheckCollisionFilter();
		SetContextThink( NULL, gpGlobals->curtime, s_pDebrisContext );
	}

	Vector vecFullMins, vecFullMaxs;
	vecFullMins = m_ragPos[0];
	vecFullMaxs = m_ragPos[0];
	for ( i = 0; i < m_ragdoll.listCount; i++ )
	{
		Vector mins, maxs;
		matrix3x4_t update;
		m_ragdoll.list[i].pObject->GetPositionMatrix( &update );
		TransformAABB( update, m_ragdollMins[i], m_ragdollMaxs[i], mins, maxs );
		for ( int j = 0; j < 3; j++ )
		{
			if ( mins[j] < vecFullMins[j] )
			{
				vecFullMins[j] = mins[j];
			}
			if ( maxs[j] > vecFullMaxs[j] )
			{
				vecFullMaxs[j] = maxs[j];
			}
		}
	}

	SetAbsOrigin( m_ragPos[0] );
	SetAbsAngles( vec3_angle );
	const Vector &vecOrigin = CollisionProp()->GetCollisionOrigin();
	CollisionProp()->AddSolidFlags( FSOLID_FORCE_WORLD_ALIGNED );
	CollisionProp()->SetSurroundingBoundsType( USE_COLLISION_BOUNDS_NEVER_VPHYSICS );
	SetCollisionBounds( vecFullMins - vecOrigin, vecFullMaxs - vecOrigin );
	CollisionProp()->MarkSurroundingBoundsDirty();

	PhysicsTouchTriggers();
}