// convert square velocity magnitude from IVP to HL float CPhysicsObject::GetEnergy() { IVP_Core *pCore = m_pObject->get_core(); IVP_FLOAT energy = 0.0f; IVP_U_Float_Point tmp; energy = 0.5f * pCore->get_mass() * pCore->speed.dot_product(&pCore->speed); // 1/2mvv tmp.set_pairwise_mult(&pCore->rot_speed, pCore->get_rot_inertia()); // wI energy += 0.5f * tmp.dot_product(&pCore->rot_speed); // 1/2mvv + 1/2wIw return ConvertEnergyToHL( energy ); }
float CPhysicsObject::GetEnergy() const { float e = 0.5 * GetMass() * m_pObject->getLinearVelocity().dot(m_pObject->getLinearVelocity()); e =+ 0.5 * GetMass() * m_pObject->getAngularVelocity().dot(m_pObject->getAngularVelocity()); return ConvertEnergyToHL(e); }
float CPhysicsObject::GetEnergy() const { // (1/2) * mass * velocity^2 float e = 0.5f * GetMass() * m_pObject->getLinearVelocity().dot(m_pObject->getLinearVelocity()); e += 0.5f * GetMass() * m_pObject->getAngularVelocity().dot(m_pObject->getAngularVelocity()); return ConvertEnergyToHL(e); }
//----------------------------------------------------------------------------- // Purpose: This walks the objects in the environment and generates friction events // for any scraping that is occurring. //----------------------------------------------------------------------------- void ProcessActiveObjects( IVP_Environment *pEnvironment, IPhysicsCollisionEvent *pEvent ) { // FIXME: Is this correct? Shouldn't it do next PSI - lastScrape? float nextTime = pEnvironment->get_old_time_of_last_PSI().get_time(); float delta = nextTime - m_lastScrapeTime; // only process if we have done a PSI if ( delta < pEnvironment->get_delta_PSI_time() ) return; float t = 1.0f; t /= delta; if ( t > 10.0f ) t = 10.0f; m_lastScrapeTime = nextTime; // UNDONE: This only calls friciton for one object in each pair. // UNDONE: Split energy in half and call for both objects? // UNDONE: Don't split/call if one object is static (like the world)? for ( int i = 0; i < m_activeObjects.Count(); i++ ) { CPhysicsObject *pObject = m_activeObjects[i]; IVP_Real_Object *ivpObject = pObject->GetObject(); // no friction callbacks for this object if ( ! (pObject->GetCallbackFlags() & CALLBACK_GLOBAL_FRICTION) ) continue; // UNDONE: IVP_Synapse_Friction is supposed to be opaque. Is there a better way // to implement this? Using the friction listener is much more work for the CPU // and considers sleeping objects. IVP_Synapse_Friction *pfriction = ivpObject->get_first_friction_synapse(); while ( pfriction ) { IVP_Contact_Point *contact = pfriction->get_contact_point(); IVP_Synapse_Friction *pOpposite = GetOppositeSynapse( pfriction ); IVP_Real_Object *pobj = pOpposite->get_object(); CPhysicsObject *pScrape = (CPhysicsObject *)pobj->client_data; // friction callbacks for this object? if ( pScrape->GetCallbackFlags() & CALLBACK_GLOBAL_FRICTION ) { float energy = IVP_Contact_Point_API::get_eliminated_energy( contact ); if ( energy ) { IVP_Contact_Point_API::reset_eliminated_energy( contact ); // scrape with an estimate for the energy per unit mass // This assumes that the game is interested in some measure of vibration // for sound effects. This also assumes that more massive objects require // more energy to vibrate. energy = energy * t * ivpObject->get_core()->get_inv_mass(); if ( energy > 0.05f ) { int hitSurface = physprops->RemapIVPMaterialIndex( pOpposite->get_material_index() ); CPhysicsFrictionData data(pfriction); pEvent->Friction( pObject, ConvertEnergyToHL(energy), pObject->GetMaterialIndexInternal(), hitSurface, &data ); } } } pfriction = pfriction->get_next(); } } }