Esempio n. 1
0
// UNEXPOSED
void CPhysicsObject::ComputeDragBasis(bool isStatic) {
	m_dragBasis.setZero();
	m_angDragBasis.setZero();

	if (!isStatic && GetCollide()) {
		btCollisionShape *shape = m_pObject->getCollisionShape();

		btVector3 min, max, delta;
		btTransform ident = btTransform::getIdentity();

		shape->getAabb(ident, min, max);

		delta = max - min;
		delta = delta.absolute();

		m_dragBasis.setX(delta.y() * delta.z());
		m_dragBasis.setY(delta.x() * delta.z());
		m_dragBasis.setZ(delta.x() * delta.y());
		m_dragBasis *= GetInvMass();

		btVector3 ang = m_pObject->getInvInertiaDiagLocal();
		delta *= 0.5;

		m_angDragBasis.setX(AngDragIntegral(ang[0], delta.x(), delta.y(), delta.z()) + AngDragIntegral(ang[0], delta.x(), delta.z(), delta.y()));
		m_angDragBasis.setY(AngDragIntegral(ang[1], delta.y(), delta.x(), delta.z()) + AngDragIntegral(ang[1], delta.y(), delta.z(), delta.x()));
		m_angDragBasis.setZ(AngDragIntegral(ang[2], delta.z(), delta.x(), delta.y()) + AngDragIntegral(ang[2], delta.z(), delta.y(), delta.x()));
	}
}
Esempio n. 2
0
void CPhysicsObject::Init(CPhysicsEnvironment* pEnv, btRigidBody* pObject, int materialIndex, float volume, float drag, float angDrag, const Vector *massCenterOverride) {
	m_pEnv = pEnv;
	m_materialIndex = materialIndex;
	m_pObject = pObject;
	pObject->setUserPointer(this);
	m_pGameData = NULL;
	m_gameFlags = 0;
	m_iLastActivationState = pObject->getActivationState();
	m_callbacks = CALLBACK_GLOBAL_COLLISION|CALLBACK_GLOBAL_FRICTION|CALLBACK_FLUID_TOUCH|CALLBACK_GLOBAL_TOUCH|CALLBACK_GLOBAL_COLLIDE_STATIC|CALLBACK_DO_FLUID_SIMULATION;
	m_fVolume = volume;
	float matdensity;
	g_SurfaceDatabase.GetPhysicsProperties(materialIndex, &matdensity, NULL, NULL, NULL);
	m_fBuoyancyRatio = (GetMass()/(GetVolume()*METERS_PER_INCH*METERS_PER_INCH*METERS_PER_INCH))/matdensity;

	surfacedata_t *surface = g_SurfaceDatabase.GetSurfaceData(materialIndex);
	if (surface)
	{
		m_pObject->setFriction(surface->physics.friction);
		// Note to self: using these dampening values = breakdancing fridges http://dl.dropbox.com/u/4838268/gm_construct%202012-4-24%2004-50-26.webm
		//m_pObject->setDamping(surface->physics.dampening, surface->physics.dampening);
	}

	// Drag calculations converted from  2003 source code
	if (!IsStatic() && GetCollide() )
	{
		btCollisionShape * shape = m_pObject->getCollisionShape();

		btVector3 min, max, delta;
		btTransform t;
		delta = min, max;
		delta = delta.absolute();

		shape->getAabb( t, min, max);

		m_dragBasis.setX(delta.y() * delta.z());
		m_dragBasis.setY(delta.x() * delta.z());
		m_dragBasis.setZ(delta.x() * delta.y());

		btVector3 ang = m_pObject->getInvInertiaDiagLocal();
		delta *= 0.5;

		m_angDragBasis.setX(AngDragIntegral( ang[0], delta.x(), delta.y(), delta.z() ) + AngDragIntegral( ang[0], delta.x(), delta.z(), delta.y() ));
		m_angDragBasis.setY(AngDragIntegral( ang[1], delta.y(), delta.x(), delta.z() ) + AngDragIntegral( ang[1], delta.y(), delta.z(), delta.x() ));
		m_angDragBasis.setZ(AngDragIntegral( ang[2], delta.z(), delta.x(), delta.y() ) + AngDragIntegral( ang[2], delta.z(), delta.y(), delta.x() ));

				
	} else {
		drag = 0;
		angDrag = 0;
	}
	m_dragCoefficient = drag;
	m_angDragCoefficient = angDrag;
}
void CPhysicsObject::Init( IVP_Real_Object *pObject, int materialIndex, float volume, float drag, float angDrag, const Vector *massCenterOverride )
{
	m_materialIndex = materialIndex;
	m_pObject = pObject;
	pObject->client_data = (void *)this;
	m_pGameData = NULL;
	m_gameFlags = 0;
	m_sleepState = OBJ_SLEEP;		// objects start asleep
	m_callbacks = CALLBACK_GLOBAL_COLLISION|CALLBACK_GLOBAL_FRICTION|CALLBACK_FLUID_TOUCH|CALLBACK_GLOBAL_TOUCH|CALLBACK_GLOBAL_COLLIDE_STATIC|CALLBACK_DO_FLUID_SIMULATION;
	m_activeIndex = 0xFFFF;
	m_pShadow = NULL;
	m_shadowTempGravityDisable = false;

	m_dragBasis = vec3_origin;
	m_angDragBasis = vec3_origin;
	if ( massCenterOverride )
	{
		m_massCenterOverride = *massCenterOverride;
	}

	if ( !IsStatic() && GetCollide() )
	{
		// Basically we are computing drag as an OBB.  Get OBB extents for projection
		// scale those extents by appropriate mass/inertia to compute velocity directly (not force)
		// in the controller
		// NOTE: Compute these even if drag coefficients are zero, because the drag coefficient could change later

		// Get an AABB for this object and use the area of each side as a basis for approximating cross-section area for drag
		Vector dragMins, dragMaxs;
		// NOTE: coordinates in/out of physcollision are in HL units, not IVP
		physcollision->CollideGetAABB( dragMins, dragMaxs, GetCollide(), vec3_origin, vec3_angle );

		Vector delta = dragMaxs - dragMins;
		ConvertPositionToIVP( delta.x, delta.y, delta.z );
		delta.x = fabsf(delta.x);
		delta.y = fabsf(delta.y);
		delta.z = fabsf(delta.z);
		// dragBasis is now the area of each side
		m_dragBasis.x = delta.y * delta.z;
		m_dragBasis.y = delta.x * delta.z;
		m_dragBasis.z = delta.x * delta.y;
		m_dragBasis *= GetInvMass();

		const IVP_U_Float_Point *pInvRI = m_pObject->get_core()->get_inv_rot_inertia();

		// This angular basis is the integral of each differential drag area's torque over the whole OBB
		// need half lengths for this integral
		delta *= 0.5;
		// rotation about the x axis
		m_angDragBasis.x = AngDragIntegral( pInvRI->k[0], delta.x, delta.y, delta.z ) + AngDragIntegral( pInvRI->k[0], delta.x, delta.z, delta.y );
		// rotation about the y axis
		m_angDragBasis.y = AngDragIntegral( pInvRI->k[1], delta.y, delta.x, delta.z ) + AngDragIntegral( pInvRI->k[1], delta.y, delta.z, delta.x );
		// rotation about the z axis
		m_angDragBasis.z = AngDragIntegral( pInvRI->k[2], delta.z, delta.x, delta.y ) + AngDragIntegral( pInvRI->k[2], delta.z, delta.y, delta.x );
	}
	else
	{
		drag = 0;
		angDrag = 0;
	}

	m_dragCoefficient = drag;
	m_angDragCoefficient = angDrag;

	SetVolume( volume );
}