// 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())); } }
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 ); }