void Physics3DComponent::syncNodeToPhysics() { if (_physics3DObj->getObjType() == Physics3DObject::PhysicsObjType::RIGID_BODY || _physics3DObj->getObjType() == Physics3DObject::PhysicsObjType::COLLIDER) { auto mat = _owner->getNodeToWorldTransform(); //remove scale, no scale support for physics float oneOverLen = 1.f / sqrtf(mat.m[0] * mat.m[0] + mat.m[1] * mat.m[1] + mat.m[2] * mat.m[2]); mat.m[0] *= oneOverLen; mat.m[1] *= oneOverLen; mat.m[2] *= oneOverLen; oneOverLen = 1.f / sqrtf(mat.m[4] * mat.m[4] + mat.m[5] * mat.m[5] + mat.m[6] * mat.m[6]); mat.m[4] *= oneOverLen; mat.m[5] *= oneOverLen; mat.m[6] *= oneOverLen; oneOverLen = 1.f / sqrtf(mat.m[8] * mat.m[8] + mat.m[9] * mat.m[9] + mat.m[10] * mat.m[10]); mat.m[8] *= oneOverLen; mat.m[9] *= oneOverLen; mat.m[10] *= oneOverLen; mat *= _invTransformInPhysics; if (_physics3DObj->getObjType() == Physics3DObject::PhysicsObjType::RIGID_BODY) { auto body = static_cast<Physics3DRigidBody*>(_physics3DObj)->getRigidBody(); auto motionState = body->getMotionState(); motionState->setWorldTransform(convertMat4TobtTransform(mat)); body->setMotionState(motionState); } else if (_physics3DObj->getObjType() == Physics3DObject::PhysicsObjType::COLLIDER) { auto object = static_cast<Physics3DCollider*>(_physics3DObj)->getGhostObject(); object->setWorldTransform(convertMat4TobtTransform(mat)); } } }
FractureBody::FractureBody(const FractureBodyInfo & info) : btRigidBody(btRigidBodyConstructionInfo(1, 0, info.m_shape, btVector3(1, 1, 1))), m_connections(info.m_connections), m_motionState(*this) { m_internalType = CO_FRACTURE_TYPE | CO_RIGID_BODY; // calculate center of mass and inertia m_centerOfMassOffset = -info.m_massCenter / info.m_mass; btVector3 inertia = info.m_inertia - getPrincipalInertia(m_centerOfMassOffset, info.m_mass); setMassProps(info.m_mass, inertia); // shift children shapes due to new center of mass for (int i = 0; i < info.m_shape->getNumChildShapes(); ++i) { info.m_shape->getChildTransform(i).getOrigin() += m_centerOfMassOffset; } info.m_shape->recalculateLocalAabb(); // set motion states if (info.m_states.size() == m_connections.size() + 1) { info.m_states[0]->massCenterOffset = m_centerOfMassOffset; new (&m_motionState) FrMotionState(*this, info.m_states[0]); setMotionState(&m_motionState); for (int i = 0; i < m_connections.size(); ++i) { m_connections[i].m_body->setMotionState(info.m_states[i + 1]); } } }
// protected void AvatarManager::removeAvatarMotionState(AvatarSharedPointer avatar) { auto rawPointer = std::static_pointer_cast<Avatar>(avatar); AvatarMotionState* motionState = rawPointer->getMotionState(); if (motionState) { // clean up physics stuff motionState->clearObjectBackPointer(); rawPointer->setMotionState(nullptr); _avatarMotionStates.remove(motionState); _motionStatesToAdd.remove(motionState); _motionStatesToDelete.push_back(motionState); } }
TTrigger::TTrigger( TPhyBodyInfo& info ) : TPhyEntity( PHY_SENSOR_BODY, info ) { m_entityType |= ET_TRIGGER; int flag = getPhyBody()->getCollisionFlags(); getPhyBody()->setCollisionFlags( flag | btCollisionObject::CF_NO_CONTACT_RESPONSE ); m_dbgObj.Object( g_Game->getCurLevel()->getFlyScene().CreateObject() ); TObjMotionState* motion = new TObjMotionState( getTransform() , m_dbgObj.Object() ); setMotionState( motion ); }
TChestTrigger::TChestTrigger() :TBoxTrigger( Vec3D( 100 , 100 , 100 ) ) ,m_items( new TItemStorage(MaxItemNum) ) { m_DTime = 0.0f; OBJECTid objID = TResManager::instance().cloneModel( "bag" , true ); modelObj.Object( objID ); float scale = 20; modelObj.Scale( scale , scale , scale , LOCAL ); modelObj.Rotate( X_AXIS , 90 , LOCAL ); modelObj.XForm(); XForm trans; trans.setIdentity(); TObjMotionState* motionState = new TObjMotionState( trans , objID ); setMotionState( motionState ); }
bool PhysicsObject::init(unsigned int attributeIndex, short collisionFilterGroup) { if(attributeIndex < 0) { return false; } attributeIndex_ = attributeIndex; collisionFilterGroup_ = collisionFilterGroup; //Get the init data from a physics attribute AttributePtr<Attribute_Physics> ptr_physics = itrPhysics_.at(attributeIndex); btScalar mass = static_cast<btScalar>(ptr_physics->mass); //Resolve mass, local inertia of the collision shape, and also the collision shape itself. btCollisionShape* collisionShape = subClassSpecificCollisionShape(); if(collisionShape != nullptr) { setCollisionShape(collisionShape); } else { ERROR_MESSAGEBOX("Error in PhysicsObject::init. Expected collision shape pointer unexpectedly set to nullptr. Using default shape instead."); setCollisionShape(CollisionShapes::Instance()->getDefaultShape()); } btVector3 localInertia = subClassCalculateLocalInertiaHook(mass); setMassProps(mass, localInertia); //Set inverse mass and inverse local inertia updateInertiaTensor(); if((getCollisionFlags() & btCollisionObject::CF_STATIC_OBJECT)) { btTransform world; AttributePtr<Attribute_Spatial> ptr_spatial = itrPhysics_.at(attributeIndex_)->ptr_spatial; AttributePtr<Attribute_Position> ptr_position = ptr_spatial->ptr_position; world.setOrigin(convert(ptr_position->position)); world.setRotation(convert(ptr_spatial->rotation)); setWorldTransform(world); //Static physics objects: transform once } else { //Non-static physics objects: let a derived btMotionState handle transforms. MotionState* customMotionState = new MotionState(attributeIndex); setMotionState(customMotionState); setAngularVelocity(btVector3(ptr_physics->angularVelocity.x, ptr_physics->angularVelocity.y, ptr_physics->angularVelocity.z)); setLinearVelocity(btVector3(ptr_physics->linearVelocity.x, ptr_physics->linearVelocity.y, ptr_physics->linearVelocity.z)); //Gravity is set after "addRigidBody" for non-static physics objects } if(ptr_physics->collisionResponse) { setCollisionFlags(getCollisionFlags() & ~CF_NO_CONTACT_RESPONSE); //Activate collision response } else { setCollisionFlags(getCollisionFlags() | CF_NO_CONTACT_RESPONSE); //Deactivate collision response } return subClassSpecificInitHook(); }