void ChMatterSPH::ResizeNnodes(int newsize) { bool oldcoll = GetCollide(); SetCollide(false); // this will remove old particle coll.models from coll.engine, if previously added /* for (unsigned int j = 0; j < nodes.size(); j++) { //delete (nodes[j]); ***not needed since using shared ptrs nodes[j] = 0; } */ nodes.resize(newsize); for (unsigned int j = 0; j < nodes.size(); j++) { nodes[j] = std::make_shared<ChNodeSPH>(); nodes[j]->SetContainer(this); nodes[j]->variables.SetUserData((void*)this); // UserData unuseful in future cuda solver? //((ChModelBullet*)nodes[j]->collision_model)->SetContactable(nodes[j]); nodes[j]->collision_model->AddPoint(0.001); //***TEST*** nodes[j]->collision_model->BuildModel(); } SetCollide(oldcoll); // this will also add particle coll.models to coll.engine, if already in a ChSystem }
// 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::WriteToTemplate( vphysics_save_cphysicsobject_t &objectTemplate ) { if ( m_collideType == COLLIDE_BALL ) { objectTemplate.pCollide = NULL; objectTemplate.sphereRadius = GetSphereRadius(); } else { objectTemplate.pCollide = GetCollide(); objectTemplate.sphereRadius = 0; } objectTemplate.isStatic = IsStatic(); objectTemplate.collisionEnabled = IsCollisionEnabled(); objectTemplate.gravityEnabled = IsGravityEnabled(); objectTemplate.dragEnabled = IsDragEnabled(); objectTemplate.motionEnabled = IsMotionEnabled(); objectTemplate.isAsleep = IsAsleep(); objectTemplate.isTrigger = IsTrigger(); objectTemplate.materialIndex = m_materialIndex; objectTemplate.mass = GetMass(); objectTemplate.rotInertia = GetInertia(); GetDamping( &objectTemplate.speedDamping, &objectTemplate.rotSpeedDamping ); objectTemplate.massCenterOverride = m_massCenterOverride; objectTemplate.callbacks = m_callbacks; objectTemplate.gameFlags = m_gameFlags; objectTemplate.volume = GetVolume(); objectTemplate.dragCoefficient = m_dragCoefficient; objectTemplate.angDragCoefficient = m_angDragCoefficient; objectTemplate.pShadow = m_pShadow; objectTemplate.hasShadowController = (m_pShadow != NULL) ? true : false; //bool m_shadowTempGravityDisable; objectTemplate.collideType = m_collideType; objectTemplate.contentsMask = m_contentsMask; GetPosition( &objectTemplate.origin, &objectTemplate.angles ); GetVelocity( &objectTemplate.velocity, &objectTemplate.angVelocity ); }
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 ); }
// UNEXPOSED void CPhysicsObject::Init(CPhysicsEnvironment *pEnv, btRigidBody *pObject, int materialIndex, objectparams_t *pParams, bool isStatic, bool isSphere) { m_pEnv = pEnv; m_pObject = pObject; m_bIsSphere = isSphere; m_gameFlags = 0; m_fMass = (pParams && !isStatic) ? pParams->mass : 0; m_pGameData = NULL; m_pName = NULL; m_fVolume = 0; m_callbacks = CALLBACK_GLOBAL_COLLISION | CALLBACK_GLOBAL_FRICTION | CALLBACK_FLUID_TOUCH | CALLBACK_GLOBAL_TOUCH | CALLBACK_GLOBAL_COLLIDE_STATIC | CALLBACK_DO_FLUID_SIMULATION; m_iLastActivationState = -1; m_pObject->setUserPointer(this); m_pObject->setSleepingThresholds(SLEEP_LINEAR_THRESHOLD, SLEEP_ANGULAR_THRESHOLD); m_pObject->setActivationState(ISLAND_SLEEPING); // All objects start asleep. if (pParams) { m_pGameData = pParams->pGameData; m_pName = pParams->pName; m_fVolume = pParams->volume * CUBIC_METERS_PER_CUBIC_INCH; EnableCollisions(pParams->enableCollisions); m_pObject->setDebugName(m_pName); } SetMaterialIndex(materialIndex); SetContents(MASK_SOLID); // Compute our air drag values. float drag = 0; float angDrag = 0; if (pParams) { drag = pParams->dragCoefficient; angDrag = pParams->dragCoefficient; } if (isStatic || !GetCollide()) { drag = 0; angDrag = 0; } ComputeDragBasis(isStatic); if (!isStatic && drag != 0.0f) { EnableDrag(true); } m_dragCoefficient = drag; m_angDragCoefficient = angDrag; // Compute our continuous collision detection stuff (for fast moving objects, prevents tunneling) // This doesn't work on compound objects! see: btDiscreteDynamicsWorld::integrateTransforms if (!isStatic) { btVector3 mins, maxs; m_pObject->getCollisionShape()->getAabb(btTransform::getIdentity(), mins, maxs); mins = mins.absolute(); maxs = maxs.absolute(); float maxradius = min(min(maxs.getX(), maxs.getY()), maxs.getZ()); float minradius = min(min(mins.getX(), mins.getY()), mins.getZ()); float radius = min(maxradius, minradius); m_pObject->setCcdMotionThreshold((radius / 2) * (radius / 2)); m_pObject->setCcdSweptSphereRadius(0.7f * radius); } if (isStatic) { m_pObject->setCollisionFlags(m_pObject->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT); m_pEnv->GetBulletEnvironment()->addRigidBody(m_pObject, COLGROUP_WORLD, ~COLGROUP_WORLD); } else { m_pEnv->GetBulletEnvironment()->addRigidBody(m_pObject); } }