void RigidBody::CreateBody() { if (!impl->world || impl->body || !ParentEntity()) return; CheckForPlaceableAndTerrain(); CreateCollisionShape(); btVector3 localInertia; float m; int collisionFlags; impl->GetProperties(localInertia, m, collisionFlags); impl->body = new btRigidBody(m, impl, impl->shape, localInertia); // TEST: Adjust the threshold of when to sleep the object - for reducing network bandwidth. // impl->body->setSleepingThresholds(0.2f, 0.5f); // Bullet defaults are 0.8 and 1.0. impl->body->setUserPointer(this); impl->body->setCollisionFlags(collisionFlags); impl->world->BulletWorld()->addRigidBody(impl->body, (short)collisionLayer.Get(), (short)collisionMask.Get()); impl->body->activate(); UpdateGravity(); }
/** * Scene_Container owns this method because I, Dylan, have made an executive decision to make lights bound to * the laws of physics impossible; I see no point for it (except for flashlights maybe). Our lights will be static, * so the initialization of rigid bodies can be the sole responsibility of the Scene_Container, because it knows * about all of its own vertices. * * TODO: Support more than just Convex Hull Shape for collision detection; Triangle Mesh Shape might be more * appropriate for static game objects. **/ void Scene_Container::InitRigidBody(btScalar mass) { // Create the collision shape CreateCollisionShape(); btVector3 localInertia(0, 0, 0); isDynamic = (mass != 0.f); if (isDynamic) collisionShape->calculateLocalInertia(mass, localInertia); btTransform* transform = new btTransform( btQuaternion(this->transform.rotation.x, this->transform.rotation.y, this->transform.rotation.z, this->transform.rotation.w), btVector3(this->transform.position.x, this->transform.position.y, this->transform.position.z)); btRigidBody::btRigidBodyConstructionInfo rigidBodyCI( mass, new btDefaultMotionState(*transform), collisionShape, localInertia); rigidBody = new btRigidBody(rigidBodyCI); rigidBody->setUserPointer(this); Physics_Manager::GetInstance()->AddRigidBody(rigidBody); }
int CcdChapter::Init() { CreateScene(); // load resource LoadResource(); CreateBullet(); Plane plane(Vector3::UNIT_Y, 0); MeshManager::getSingleton().createPlane("ground", ResourceGroup, plane, 500, 500, 1, 1, true, 1, 5, 5, Vector3::UNIT_Z); Entity *groundEntity = m_pkSceneManager->createEntity("GroundEntity", "ground"); groundEntity->setMaterialName("BulletPlane", ResourceGroup); groundEntity->setCastShadows(true); SceneNode *pkNode = m_pkRootNode->createChildSceneNode(); pkNode->attachObject(groundEntity); btCollisionShape *shape = CreateCollisionShape(SHAPE_TYPE::SHAPE_PLANE, Vector3::ZERO); m_CollisionShapes.push_back(shape); btRigidBody *body = CreateRigidBody(shape, false, pkNode, 100); m_RigidBodies.push_back(body); m_pkDynamicsWorld->addRigidBody(body); body->setUserPointer(pkNode); //body->setFriction(100); return 0; }
void RigidBody::TerrainUpdated(IAttribute* attribute, AttributeChange::Type /*change*/) { Terrain* terrain = impl->terrain; if (!terrain) return; /// \todo It is suboptimal to regenerate the whole heightfield when just the terrain's transform changes if (attribute == &terrain->nodeTransformation && shapeType.Get() == HeightField) CreateCollisionShape(); }
void RigidBody::OnCollisionMeshAssetLoaded(AssetPtr asset) { IMeshAsset* meshAsset = dynamic_cast<IMeshAsset*>(asset.Get()); if (!meshAsset) LogError("RigidBody::OnCollisionMeshAssetLoaded: Mesh asset load finished for asset \"" + asset->Name() + "\", but asset pointer was null!"); if (shapeType.Get() == TriMesh) { impl->triangleMesh = impl->owner->GetTriangleMeshFromMeshAsset(meshAsset); CreateCollisionShape(); } else if (shapeType.Get() == ConvexHull) { impl->convexHullSet = impl->owner->GetConvexHullSetFromMeshAsset(meshAsset); CreateCollisionShape(); } impl->cachedShapeType = shapeType.Get(); impl->cachedSize = size.Get(); }
void RigidBody::AttributesChanged() { if (impl->disconnected) return; bool isShapeTriMeshOrConvexHull = (shapeType.Get() == TriMesh || shapeType.Get() == ConvexHull); bool bodyRead = false; bool meshRequested = false; // Create body now if does not exist yet if (!impl->body) CreateBody(); // If body was not created (we do not actually have a physics world), exit if (!impl->body) return; if (mass.ValueChanged() || collisionLayer.ValueChanged() || collisionMask.ValueChanged()) { // Read body to the world in case static/dynamic classification changed, or if collision mask changed ReaddBody(); bodyRead = true; } if (friction.ValueChanged()) impl->body->setFriction(friction.Get()); if (rollingFriction.ValueChanged()) impl->body->setRollingFriction(rollingFriction.Get()); if (restitution.ValueChanged()) impl->body->setRestitution(friction.Get()); if (linearDamping.ValueChanged() || angularDamping.ValueChanged()) impl->body->setDamping(linearDamping.Get(), angularDamping.Get()); if (linearFactor.ValueChanged()) impl->body->setLinearFactor(linearFactor.Get()); if (angularFactor.ValueChanged()) impl->body->setAngularFactor(angularFactor.Get()); if (shapeType.ValueChanged() || size.ValueChanged()) { if (shapeType.Get() != impl->cachedShapeType || !size.Get().Equals(impl->cachedSize)) { // If shape does not involve mesh, can create it directly. Otherwise request the mesh if (!isShapeTriMeshOrConvexHull) { CreateCollisionShape(); impl->cachedShapeType = shapeType.Get(); impl->cachedSize = size.Get(); } // If shape type has changed from TrimMesh <--> ConvexHull refresh the mesh shape. else if (shapeType.Get() != impl->cachedShapeType) { RequestMesh(); meshRequested = true; } // If size changed but no reload of mesh shape was done, update its scale. else if (!size.Get().Equals(impl->cachedSize)) UpdateScale(); } } // Request mesh if its id changes if (collisionMeshRef.ValueChanged() && isShapeTriMeshOrConvexHull && !meshRequested) RequestMesh(); // Readd body to the world in case phantom or kinematic classification changed if (!bodyRead && (phantom.ValueChanged() || kinematic.ValueChanged())) ReaddBody(); if (drawDebug.ValueChanged()) { bool enable = drawDebug.Get(); if (impl->body) { int collisionFlags = impl->body->getCollisionFlags(); if (enable) collisionFlags &= ~btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT; else collisionFlags |= btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT; impl->body->setCollisionFlags(collisionFlags); } // Refresh PhysicsWorld's knowledge of debug-enabled rigidbodies if (impl->world) { if (enable) impl->world->debugRigidBodies_.Insert(this); else impl->world->debugRigidBodies_.Erase(this); } } if (linearVelocity.ValueChanged() && !impl->disconnected) { impl->body->setLinearVelocity(linearVelocity.Get()); impl->body->activate(); } if (angularVelocity.ValueChanged() && !impl->disconnected) { impl->body->setAngularVelocity(DegToRad(angularVelocity.Get())); impl->body->activate(); } if (useGravity.ValueChanged()) UpdateGravity(); }
void RigidBody::OnTerrainRegenerated() { if (shapeType.Get() == HeightField) CreateCollisionShape(); }