//----------------------------------------------------------------------------- // Purpose: Create a constraint between this object and another // Input : *pObject - Object to constrain ourselves to // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CWeaponStriderBuster::CreateConstraintToObject( CBaseEntity *pObject ) { if ( m_pConstraint != NULL ) { // Should we destroy the constraint and make a new one at this point? Assert( 0 ); return false; } if ( pObject == NULL ) return false; IPhysicsObject *pPhysObject = pObject->VPhysicsGetObject(); if ( pPhysObject == NULL ) return false; IPhysicsObject *pMyPhysObject = VPhysicsGetObject(); if ( pPhysObject == NULL ) return false; // Create the fixed constraint constraint_fixedparams_t fixedConstraint; fixedConstraint.Defaults(); fixedConstraint.InitWithCurrentObjectState( pPhysObject, pMyPhysObject ); IPhysicsConstraint *pConstraint = physenv->CreateFixedConstraint( pPhysObject, pMyPhysObject, NULL, fixedConstraint ); if ( pConstraint == NULL ) return false; // Hold on to us m_pConstraint = pConstraint; pConstraint->SetGameData( (void *)this ); m_hConstrainedEntity = pObject->GetOwnerEntity();; // Disable collisions between the two ents PhysDisableObjectCollisions( pPhysObject, pMyPhysObject ); return true; }
//----------------------------------------------------------------------------- // Purpose: Update the impale entity's position to the hydra's desired //----------------------------------------------------------------------------- void CHydraImpale::ImpaleThink( void ) { if ( !m_hHydra ) { // Remove ourselves. m_pConstraint->Deactivate(); UTIL_Remove( this ); return; } // Ask the Hydra where he'd like the ragdoll, and move ourselves there Vector vecOrigin; QAngle vecAngles; m_hHydra->GetDesiredImpaledPosition( &vecOrigin, &vecAngles ); SetAbsOrigin( vecOrigin ); SetAbsAngles( vecAngles ); //NDebugOverlay::Cross3D( vecOrigin, Vector( -5, -5, -5 ), Vector( 5, 5, 5 ), 255, 0, 0, 20, .1); SetNextThink( gpGlobals->curtime + 0.1f ); }
//----------------------------------------------------------------------------- // Purpose: Activate/create the constraint //----------------------------------------------------------------------------- IPhysicsConstraint *CHydraImpale::CreateConstraint( CNPC_Hydra *pHydra, IPhysicsObject *pTargetPhys, IPhysicsConstraintGroup *pGroup ) { m_hHydra = pHydra; IPhysicsObject *pImpalePhysObject = VPhysicsGetObject(); Assert( pImpalePhysObject ); constraint_fixedparams_t fixed; fixed.Defaults(); fixed.InitWithCurrentObjectState( pImpalePhysObject, pTargetPhys ); fixed.constraint.Defaults(); m_pConstraint = physenv->CreateFixedConstraint( pImpalePhysObject, pTargetPhys, pGroup, fixed ); if ( m_pConstraint ) { m_pConstraint->SetGameData( (void *)this ); } SetThink( ImpaleThink ); SetNextThink( gpGlobals->curtime ); return m_pConstraint; }
void CWeaponHL2MPBase::FallInit( void ) { #ifndef CLIENT_DLL SetModel( GetWorldModel() ); VPhysicsDestroyObject(); if ( HasSpawnFlags( SF_NORESPAWN ) == false ) { SetMoveType( MOVETYPE_NONE ); SetSolid( SOLID_BBOX ); AddSolidFlags( FSOLID_TRIGGER ); UTIL_DropToFloor( this, MASK_SOLID ); } else { if ( !VPhysicsInitNormal( SOLID_BBOX, GetSolidFlags() | FSOLID_TRIGGER, false ) ) { SetMoveType( MOVETYPE_NONE ); SetSolid( SOLID_BBOX ); AddSolidFlags( FSOLID_TRIGGER ); } else { #if !defined( CLIENT_DLL ) // Constrained start? if ( HasSpawnFlags( SF_WEAPON_START_CONSTRAINED ) ) { //Constrain the weapon in place IPhysicsObject *pReferenceObject, *pAttachedObject; pReferenceObject = g_PhysWorldObject; pAttachedObject = VPhysicsGetObject(); if ( pReferenceObject && pAttachedObject ) { constraint_fixedparams_t fixed; fixed.Defaults(); fixed.InitWithCurrentObjectState( pReferenceObject, pAttachedObject ); fixed.constraint.forceLimit = lbs2kg( 10000 ); fixed.constraint.torqueLimit = lbs2kg( 10000 ); IPhysicsConstraint *pConstraint = GetConstraint(); pConstraint = physenv->CreateFixedConstraint( pReferenceObject, pAttachedObject, NULL, fixed ); pConstraint->SetGameData( (void *) this ); } } #endif //CLIENT_DLL } } SetPickupTouch(); SetThink( &CBaseCombatWeapon::FallThink ); SetNextThink( gpGlobals->curtime + 0.1f ); #endif }
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 ); } }