void CRagdollPropAttached::InitRagdollAttached( IPhysicsObject *pAttached, const Vector &forceVector, int forceBone, matrix3x4_t *pPrevBones, matrix3x4_t *pBoneToWorld, float dt, int collisionGroup, CBaseAnimating *pFollow, int boneIndexRoot, const Vector &boneLocalOrigin, int parentBoneAttach, const Vector &worldAttachOrigin ) { int ragdollAttachedIndex = 0; if ( parentBoneAttach > 0 ) { studiohdr_t *pStudioHdr = GetModelPtr(); mstudiobone_t *pBone = pStudioHdr->pBone( parentBoneAttach ); ragdollAttachedIndex = pBone->physicsbone; } InitRagdoll( forceVector, forceBone, vec3_origin, pPrevBones, pBoneToWorld, dt, collisionGroup, false ); IPhysicsObject *pRefObject = m_ragdoll.list[ragdollAttachedIndex].pObject; Vector attachmentPointRagdollSpace; pRefObject->WorldToLocal( attachmentPointRagdollSpace, worldAttachOrigin ); constraint_ragdollparams_t constraint; constraint.Defaults(); matrix3x4_t tmp, worldToAttached, worldToReference, constraintToWorld; Vector offsetWS; pAttached->LocalToWorld( offsetWS, boneLocalOrigin ); AngleMatrix( QAngle(0, pFollow->GetAbsAngles().y, 0 ), offsetWS, constraintToWorld ); constraint.axes[0].SetAxisFriction( -2, 2, 20 ); constraint.axes[1].SetAxisFriction( 0, 0, 0 ); constraint.axes[2].SetAxisFriction( -15, 15, 20 ); pAttached->GetPositionMatrix( tmp ); MatrixInvert( tmp, worldToAttached ); pRefObject->GetPositionMatrix( tmp ); MatrixInvert( tmp, worldToReference ); ConcatTransforms( worldToReference, constraintToWorld, constraint.constraintToReference ); ConcatTransforms( worldToAttached, constraintToWorld, constraint.constraintToAttached ); // for now, just slam this to be the passed in value MatrixSetColumn( attachmentPointRagdollSpace, 3, constraint.constraintToReference ); DisableCollisions( pAttached ); m_pAttachConstraint = physenv->CreateRagdollConstraint( pRefObject, pAttached, m_ragdoll.pGroup, constraint ); FollowEntity( pFollow ); SetOwnerEntity( pFollow ); RagdollActivate( m_ragdoll ); Relink(); m_boneIndexAttached = boneIndexRoot; m_ragdollAttachedObjectIndex = ragdollAttachedIndex; m_attachmentPointBoneSpace = boneLocalOrigin; Vector vTemp; MatrixGetColumn( constraint.constraintToReference, 3, vTemp ); m_attachmentPointRagdollSpace = vTemp; }
void CPhysMotor::Activate( void ) { BaseClass::Activate(); // This gets called after all objects spawn and after all objects restore if ( m_attachedObject == NULL ) { CBaseEntity *pAttach = gEntList.FindEntityByName( NULL, m_nameAttach, NULL ); if ( pAttach && pAttach->GetMoveType() == MOVETYPE_VPHYSICS ) { m_attachedObject = pAttach; IPhysicsObject *pPhys = m_attachedObject->VPhysicsGetObject(); CalculateAcceleration(); matrix3x4_t matrix; pPhys->GetPositionMatrix( matrix ); Vector motorAxis_ls; VectorIRotate( m_motor.m_axis, matrix, motorAxis_ls ); float inertia = DotProductAbs( pPhys->GetInertia(), motorAxis_ls ); m_motor.m_maxTorque = inertia * m_motor.m_inertiaFactor * (m_angularAcceleration + m_additionalAcceleration); m_motor.m_restistanceDamping = 1.0f; } } if ( m_attachedObject ) { IPhysicsObject *pPhys = m_attachedObject->VPhysicsGetObject(); // create a hinge constraint for this object? if ( m_spawnflags & SF_MOTOR_HINGE ) { // UNDONE: Don't do this on restore? if ( !m_pHinge ) { constraint_hingeparams_t hingeParams; hingeParams.Defaults(); hingeParams.worldAxisDirection = m_motor.m_axis; hingeParams.worldPosition = GetLocalOrigin(); m_pHinge = physenv->CreateHingeConstraint( g_PhysWorldObject, pPhys, NULL, hingeParams ); m_pHinge->SetGameData( (void *)this ); } if ( m_spawnflags & SF_MOTOR_NOCOLLIDE ) { physenv->DisableCollisions( pPhys, g_PhysWorldObject ); } } else { m_pHinge = NULL; } // NOTE: On restore, this path isn't run because m_pController will not be NULL if ( !m_pController ) { m_pController = physenv->CreateMotionController( &m_motor ); m_pController->AttachObject( m_attachedObject->VPhysicsGetObject() ); if ( m_spawnflags & SF_MOTOR_START_ON ) { TurnOn(); } } } // Need to do this on restore since there's no good way to save this if ( m_pController ) { m_pController->SetEventHandler( &m_motor ); } }
void CRagdollPropAttached::InitRagdollAttached( IPhysicsObject *pAttached, const Vector &forceVector, int forceBone, matrix3x4_t *pPrevBones, matrix3x4_t *pBoneToWorld, float dt, int collisionGroup, CBaseAnimating *pFollow, int boneIndexRoot, const Vector &boneLocalOrigin, int parentBoneAttach, const Vector &worldAttachOrigin ) { int ragdollAttachedIndex = 0; if ( parentBoneAttach > 0 ) { CStudioHdr *pStudioHdr = GetModelPtr(); mstudiobone_t *pBone = pStudioHdr->pBone( parentBoneAttach ); ragdollAttachedIndex = pBone->physicsbone; } InitRagdoll( forceVector, forceBone, vec3_origin, pPrevBones, pBoneToWorld, dt, collisionGroup, false ); IPhysicsObject *pRefObject = m_ragdoll.list[ragdollAttachedIndex].pObject; Vector attachmentPointRagdollSpace; pRefObject->WorldToLocal( &attachmentPointRagdollSpace, worldAttachOrigin ); constraint_ragdollparams_t constraint; constraint.Defaults(); matrix3x4_t tmp, worldToAttached, worldToReference, constraintToWorld; Vector offsetWS; pAttached->LocalToWorld( &offsetWS, boneLocalOrigin ); AngleMatrix( QAngle(0, pFollow->GetAbsAngles().y, 0 ), offsetWS, constraintToWorld ); constraint.axes[0].SetAxisFriction( -2, 2, 20 ); constraint.axes[1].SetAxisFriction( 0, 0, 0 ); constraint.axes[2].SetAxisFriction( -15, 15, 20 ); // Exaggerate the bone's ability to pull the mass of the ragdoll around constraint.constraint.bodyMassScale[1] = 50.0f; pAttached->GetPositionMatrix( &tmp ); MatrixInvert( tmp, worldToAttached ); pRefObject->GetPositionMatrix( &tmp ); MatrixInvert( tmp, worldToReference ); ConcatTransforms( worldToReference, constraintToWorld, constraint.constraintToReference ); ConcatTransforms( worldToAttached, constraintToWorld, constraint.constraintToAttached ); // for now, just slam this to be the passed in value MatrixSetColumn( attachmentPointRagdollSpace, 3, constraint.constraintToReference ); PhysDisableEntityCollisions( pAttached, m_ragdoll.list[0].pObject ); m_pAttachConstraint = physenv->CreateRagdollConstraint( pRefObject, pAttached, m_ragdoll.pGroup, constraint ); SetParent( pFollow ); SetOwnerEntity( pFollow ); RagdollActivate( m_ragdoll, modelinfo->GetVCollide( GetModelIndex() ), GetModelIndex() ); // add a bunch of dampening to the ragdoll for ( int i = 0; i < m_ragdoll.listCount; i++ ) { float damping, rotdamping; m_ragdoll.list[i].pObject->GetDamping( &damping, &rotdamping ); damping *= ATTACHED_DAMPING_SCALE; rotdamping *= ATTACHED_DAMPING_SCALE; m_ragdoll.list[i].pObject->SetDamping( &damping, &rotdamping ); } m_boneIndexAttached = boneIndexRoot; m_ragdollAttachedObjectIndex = ragdollAttachedIndex; m_attachmentPointBoneSpace = boneLocalOrigin; Vector vTemp; MatrixGetColumn( constraint.constraintToReference, 3, vTemp ); m_attachmentPointRagdollSpace = vTemp; }