void CPhysicsObject::EnableMotion( bool enable )
{
	bool isMoveable = IsMotionEnabled();

	// no change
	if ( isMoveable == enable )
		return;

	BEGIN_IVP_ALLOCATION();
	m_pObject->set_pinned( enable ? IVP_FALSE : IVP_TRUE );
	END_IVP_ALLOCATION();

	RecheckCollisionFilter();
}
void CRagdollPropAttached::Detach()
{
	StopFollowingEntity();
	SetOwnerEntity( NULL );
	SetAbsAngles( vec3_angle );
	SetMoveType( MOVETYPE_VPHYSICS );
	physenv->DestroyConstraint( m_pAttachConstraint );
	m_pAttachConstraint = NULL;

	// Go non-solid
	SetCollisionGroup( COLLISION_GROUP_DEBRIS );
	Relink();
	RecheckCollisionFilter();
}
예제 #3
0
void CRagdollPropAttached::Detach()
{
	SetParent(NULL);
	SetOwnerEntity( NULL );
	SetAbsAngles( vec3_angle );
	SetMoveType( MOVETYPE_VPHYSICS );
	RemoveSolidFlags( FSOLID_NOT_SOLID );
	physenv->DestroyConstraint( m_pAttachConstraint );
	m_pAttachConstraint = NULL;
	const float dampingScale = 1.0f / ATTACHED_DAMPING_SCALE;
	for ( int i = 0; i < m_ragdoll.listCount; i++ )
	{
		float damping, rotdamping;
		m_ragdoll.list[i].pObject->GetDamping( &damping, &rotdamping );
		damping *= dampingScale;
		rotdamping *= dampingScale;
		m_ragdoll.list[i].pObject->SetDamping( &damping, &damping );
	}

	// Go non-solid
	SetCollisionGroup( COLLISION_GROUP_DEBRIS );
	RecheckCollisionFilter();
}
예제 #4
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();
}
예제 #5
0
void CRagdollProp::SetDebrisThink()
{
	SetCollisionGroup( COLLISION_GROUP_DEBRIS );
	RecheckCollisionFilter();
}