// 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 );
}
Example #2
0
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);
}
Example #3
0
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();
			}
		}
	}