bool CPlayerController::IsInContact() { CPhysicsEnvironment *pEnv = m_pObject->GetVPhysicsEnvironment(); int numManifolds = pEnv->GetBulletEnvironment()->getDispatcher()->getNumManifolds(); for (int i = 0; i < numManifolds; i++) { btPersistentManifold *contactManifold = pEnv->GetBulletEnvironment()->getDispatcher()->getManifoldByIndexInternal(i); const btCollisionObject *obA = contactManifold->getBody0(); const btCollisionObject *obB = contactManifold->getBody1(); CPhysicsObject *pPhysUs = NULL; CPhysicsObject *pPhysOther = NULL; if (contactManifold->getNumContacts() > 0 && (obA == m_pObject->GetObject() || obB == m_pObject->GetObject())) { if (obA == m_pObject->GetObject()) { pPhysUs = (CPhysicsObject *)obA->getUserPointer(); pPhysOther = (CPhysicsObject *)obB->getUserPointer(); } else if (obB == m_pObject->GetObject()) { pPhysUs = (CPhysicsObject *)obB->getUserPointer(); pPhysOther = (CPhysicsObject *)obA->getUserPointer(); } if (pPhysOther->IsStatic() || !pPhysOther->IsMotionEnabled() || (pPhysOther->GetCallbackFlags() & CALLBACK_SHADOW_COLLISION)) continue; return true; } } return false; }
void SerializeWorld_f(const CCommand &args) { if (args.ArgC() != 3) { Msg("Usage: vphysics_serialize <index> <name>\n"); return; } CPhysicsEnvironment *pEnv = (CPhysicsEnvironment *)g_Physics.GetActiveEnvironmentByIndex(atoi(args.Arg(2))); if (pEnv) { btDiscreteDynamicsWorld *pWorld = (btDiscreteDynamicsWorld *)pEnv->GetBulletEnvironment(); Assert(pWorld); btSerializer *pSerializer = new btDefaultSerializer; pWorld->serialize(pSerializer); // FIXME: We shouldn't be using this. Find the appropiate method from valve interfaces. const char *pName = args.Arg(3); FILE *pFile = fopen(pName, "wb"); if (pFile) { fwrite(pSerializer->getBufferPointer(), pSerializer->getCurrentBufferSize(), 1, pFile); fclose(pFile); } else { Warning("Couldn't open \"%s\" for writing!\n", pName); } } else { Warning("Invalid environment index supplied!\n"); } }
// UNEXPOSED void CPhysicsEnvironment::TickCallback(btDynamicsWorld *world, btScalar timeStep) { if (!world) return; CPhysicsEnvironment *pEnv = (CPhysicsEnvironment *)world->getWorldUserInfo(); if (pEnv) pEnv->BulletTick(timeStep); }
void CPhysicsObject::SetShadow( const Vector &maxVelocity, const AngularImpulse &maxAngularVelocity, bool allowPhysicsMovement, bool allowPhysicsRotation ) { if ( m_pShadow ) { m_pShadow->MaxSpeed( maxVelocity, maxAngularVelocity ); } else { // m_pObject->get_core()->rot_speed_damp_factor = IVP_U_Float_Point( 1e5f, 1e5f, 1e5f ); m_shadowTempGravityDisable = false; unsigned int flags = GetCallbackFlags() | CALLBACK_SHADOW_COLLISION; flags &= ~CALLBACK_GLOBAL_FRICTION; flags &= ~CALLBACK_GLOBAL_COLLIDE_STATIC; SetCallbackFlags( flags ); IVP_Environment *pEnv = m_pObject->get_environment(); CPhysicsEnvironment *pVEnv = (CPhysicsEnvironment *)pEnv->client_data; m_pShadow = pVEnv->CreateShadowController( this, allowPhysicsMovement, allowPhysicsRotation ); m_pShadow->MaxSpeed( maxVelocity, maxAngularVelocity ); SetRollingDrag( 0 ); EnableDrag( false ); if ( !allowPhysicsMovement ) { EnableGravity( false ); } } }
void CPhysicsObject::RemoveShadowController() { if ( m_pShadow ) { IVP_Environment *pEnv = m_pObject->get_environment(); CPhysicsEnvironment *pVEnv = (CPhysicsEnvironment *)pEnv->client_data; pVEnv->DestroyShadowController( m_pShadow ); m_pShadow = NULL; } }
bool RestorePhysicsSpring( const physrestoreparams_t ¶ms, CPhysicsSpring **ppSpring ) { vphysics_save_cphysicsspring_t springTemplate; memset( &springTemplate, 0, sizeof(springTemplate) ); params.pRestore->ReadAll( &springTemplate ); CPhysicsEnvironment *pEnvironment = (CPhysicsEnvironment *)params.pEnvironment; *ppSpring = (CPhysicsSpring *)pEnvironment->CreateSpring( springTemplate.pObjStart, springTemplate.pObjEnd, &springTemplate ); return true; }
void CPlayerController::do_simulation_controller( IVP_Event_Sim *es,IVP_U_Vector<IVP_Core> *) { if ( !m_enable ) return; IVP_Real_Object *pivp = m_pObject->GetObject(); IVP_Environment *pIVPEnv = pivp->get_environment(); CPhysicsEnvironment *pVEnv = (CPhysicsEnvironment *)pIVPEnv->client_data; float psiScale = pVEnv->GetInvPSIScale(); if ( !psiScale ) return; IVP_Core *pCore = pivp->get_core(); // current situation const IVP_U_Matrix *m_world_f_core = pCore->get_m_world_f_core_PSI(); const IVP_U_Point *cur_pos_ws = m_world_f_core->get_position(); // --------------------------------------------------------- // Translation // --------------------------------------------------------- IVP_U_Float_Point delta_position; delta_position.subtract( &m_targetPosition, cur_pos_ws); if (!pivp->flags.shift_core_f_object_is_zero) { IVP_U_Float_Point shift_cs_os_ws; m_world_f_core->vmult3( pivp->get_shift_core_f_object(), &shift_cs_os_ws); delta_position.subtract( &shift_cs_os_ws ); } IVP_DOUBLE qdist = delta_position.quad_length(); // UNDONE: This is totally bogus! Measure error using last known estimate // not current position! if ( qdist > m_maxDeltaPosition * m_maxDeltaPosition ) { if ( TryTeleportObject() ) return; } // float to allow stepping if ( m_onground ) { const IVP_U_Point *pgrav = es->environment->get_gravity(); IVP_U_Float_Point gravSpeed; gravSpeed.set_multiple( pgrav, es->delta_time ); pCore->speed.subtract( &gravSpeed ); } ComputeController( pCore->speed, delta_position, m_maxSpeed, psiScale / es->delta_time, m_dampFactor ); }
CPhysicsObject::~CPhysicsObject( void ) { RemoveShadowController(); if ( m_pObject ) { // prevents callbacks to the game code / unlink from this object m_callbacks = 0; m_pGameData = 0; m_pObject->client_data = 0; IVP_Core *pCore = m_pObject->get_core(); if ( pCore->physical_unmoveable == IVP_TRUE && pCore->controllers_of_core.n_elems ) { // go ahead and notify them if this happens in the real world for(int i = pCore->controllers_of_core.len()-1; i >=0 ;i-- ) { IVP_Controller *my_controller = pCore->controllers_of_core.element_at(i); my_controller->core_is_going_to_be_deleted_event(pCore); Assert(my_controller==pCore->environment->get_gravity_controller()); } } // UNDONE: Don't free the surface manager here // UNDONE: Remove reference to it by calling something in physics_collide IVP_SurfaceManager *pSurman = GetSurfaceManager(); IVP_Environment *pEnv = m_pObject->get_environment(); CPhysicsEnvironment *pVEnv = (CPhysicsEnvironment *)pEnv->client_data; // BUGBUG: Sometimes IVP will call a "revive" on the object we're deleting! if ( pVEnv && pVEnv->ShouldQuickDelete() ) { m_pObject->delete_silently(); } else { m_pObject->delete_and_check_vicinity(); } delete pSurman; } }
int CPhysicsObject::GetShadowPosition( Vector *position, QAngle *angles ) { IVP_U_Matrix matrix; IVP_Environment *pEnv = m_pObject->get_environment(); CPhysicsEnvironment *pVEnv = (CPhysicsEnvironment *)pEnv->client_data; double psi = pEnv->get_next_PSI_time().get_seconds(); m_pObject->calc_at_matrix( psi, &matrix ); if ( angles ) { ConvertRotationToHL( matrix, *angles ); } if ( position ) { ConvertPositionToHL( matrix.vv, *position ); } return pVEnv->GetSimulatedPSIs(); }
void CPhysicsObject::BecomeTrigger() { if ( IsTrigger() ) return; EnableDrag( false ); EnableGravity( false ); // UNDONE: Use defaults here? Do we want object sets by default? IVP_Template_Phantom trigger; trigger.manage_intruding_cores = IVP_TRUE; // manage a list of intruded objects trigger.dont_check_for_unmoveables = IVP_TRUE; trigger.exit_policy_extra_radius = 0.1f; // relatively strict exit check [m] m_pObject->convert_to_phantom( &trigger ); // hook up events IVP_Environment *pEnv = m_pObject->get_environment(); CPhysicsEnvironment *pVEnv = (CPhysicsEnvironment *)pEnv->client_data; pVEnv->PhantomAdd( this ); }
CPhysicsFrictionSnapshot::CPhysicsFrictionSnapshot(CPhysicsObject *pObject) { m_pObject = pObject; m_iCurContactPoint = 0; m_iCurManifold = 0; CPhysicsEnvironment *pEnv = pObject->GetVPhysicsEnvironment(); btRigidBody *pBody = pObject->GetObject(); int numManifolds = pEnv->GetBulletEnvironment()->getDispatcher()->getNumManifolds(); for (int i = 0; i < numManifolds; i++) { btPersistentManifold *pManifold = pEnv->GetBulletEnvironment()->getDispatcher()->getManifoldByIndexInternal(i); const btCollisionObject *pObjA = pManifold->getBody0(); const btCollisionObject *pObjB = pManifold->getBody1(); if (pManifold->getNumContacts() <= 0) continue; if (pObjA == pBody || pObjB == pBody) { m_manifolds.AddToTail(pManifold); } } }
virtual void event_PSI( IVP_Event_PSI *pEvent ) { CPhysicsEnvironment *pVEnv = (CPhysicsEnvironment *)pEvent->environment->client_data; pVEnv->EventPSI(); }