bool PhysicsSystem::AddRigidBody(CollisionBody* collision_body) { eid entity_id = collision_body->entity_id; RemoveRigidBody(entity_id); if (!collision_body->shape) { return false; } btVector3 fallInertia(0, 0, 0); if (collision_body->mass > 0.0) { if (collision_body->shape) { collision_body->shape->calculateLocalInertia(collision_body->mass, fallInertia); } } btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(collision_body->mass, &collision_body->motion_state, collision_body->shape.get(), fallInertia); auto body = new btRigidBody(fallRigidBodyCI); if (!body) { return false; } this->bodies[entity_id] = body; body->setUserPointer(collision_body); return true; }
PhysicsInterface::BodyObject Bullet::createCapsuleBody(float height, float radius, float mass, bool fixed, const Entity* entity, const SimpleTransform& initialTransform) { auto collisionShape = new btCapsuleShape(radius, height); // Calculate inertia auto localInertia = btVector3(0.0f, 0.0f, 0.0f); if (!fixed) collisionShape->calculateLocalInertia(mass, localInertia); // Motion state for this body auto motionState = new btDefaultMotionState(toBullet(initialTransform)); // Create Bullet rigid body auto bulletBody = new btRigidBody( btRigidBody::btRigidBodyConstructionInfo(fixed ? 0.0f : mass, motionState, collisionShape, localInertia)); bulletBody->setDamping(DefaultLinearDamping, DefaultAngularDamping); bulletBody->setSleepingThresholds(DefaultLinearSleepingThreshold, DefaultAngularSleepingThreshold); bulletBody->setRestitution(0.0f); // Add body to the simulation dynamicsWorld_->addRigidBody(bulletBody); // Create local body auto body = new Body(bulletBody, entity, fixed); bodies_.append(body); body->ownedCollisionShape = collisionShape; bulletBody->setUserPointer(body); return body; }
PhysicsRigidBody* PhysicsMgr::createRigidBodyMesh(Mesh* mesh, Matrix44* transform) { auto rig = new PhysicsRigidBody(); btScalar mass(0.0f); btTransform startTransform; btTriangleMesh * meshInterface = new btTriangleMesh(); auto idxSize = mesh->getIndicesSize(); for(auto i =0; i < idxSize; i+=3) { auto v1 = mesh->getVertex(i); auto v2 = mesh->getVertex(i + 1); auto v3 = mesh->getVertex(i + 2); meshInterface->addTriangle(btVector3(v1.m_pos.x, v1.m_pos.y, v1.m_pos.z), btVector3(v2.m_pos.x, v2.m_pos.y, v2.m_pos.z), btVector3(v3.m_pos.x, v3.m_pos.y, v3.m_pos.z)); } auto tetraShape = new btBvhTriangleMeshShape(meshInterface, true, true); startTransform.setIdentity(); if (transform) { startTransform.setFromOpenGLMatrix(transform->data()); } auto btRig = shared()->createRigidBodyInternal(mass, startTransform, tetraShape, btVector4(1, 0, 0, 1)); btRig->setContactProcessingThreshold(BT_LARGE_FLOAT); btRig->setFriction (btScalar(0.9)); btRig->setCcdMotionThreshold(.1); btRig->setCcdSweptSphereRadius(0); rig->setRigidBody(btRig); rig->genUserIndex(); btRig->setUserIndex(rig->userIndex()); btRig->setUserPointer(rig); return rig; }
PhysicsRigidBody* PhysicsMgr::createRigidBodyFromCompund(float mass, Matrix44* transform, PhysicsCompoundShape * tzwShape) { auto rig = new PhysicsRigidBody(); bool isDynamic = (mass != 0.f); btVector3 localInertia(0, 0, 0); auto shape = tzwShape->getShape(); if (isDynamic) shape->calculateLocalInertia(mass, localInertia); btTransform startTransform; startTransform.setFromOpenGLMatrix(transform->data()); auto btRig = shared()->createRigidBodyInternal(mass, startTransform, shape, btVector4(1, 0, 0, 1)); rig->setRigidBody(btRig); rig->genUserIndex(); btRig->setUserIndex(rig->userIndex()); btRig->setUserPointer(rig); return rig; }
PhysicsInterface::BodyObject Bullet::createGeometryBodyFromTemplate(BodyTemplateObject bodyTemplateObject, float mass, bool fixed, const Entity* entity, const SimpleTransform& initialTransform) { auto bodyTemplate = reinterpret_cast<BodyTemplate*>(bodyTemplateObject); if (!bodyTemplateObject || !bodyTemplate->collisionShape) { LOG_ERROR << "Invalid body template"; return nullptr; } // Calculate inertia auto localInertia = btVector3(0.0f, 0.0f, 0.0f); if (!fixed) bodyTemplate->collisionShape->calculateLocalInertia(mass, localInertia); // Motion state for this body auto motionState = new btDefaultMotionState(toBullet(initialTransform), btTransform(btQuaternion::getIdentity(), toBullet(Vec3::Zero))); // Create Bullet rigid body auto bulletBody = new btRigidBody( btRigidBody::btRigidBodyConstructionInfo((fixed ? 0.0f : mass), motionState, bodyTemplate->collisionShape, (fixed ? btVector3(0.0f, 0.0f, 0.0f) : localInertia))); bulletBody->setDamping(DefaultLinearDamping, DefaultAngularDamping); bulletBody->setSleepingThresholds(DefaultLinearSleepingThreshold, DefaultAngularSleepingThreshold); bulletBody->setRestitution(0.0f); // Add body to the simulation dynamicsWorld_->addRigidBody(bulletBody); // Create local body auto body = new Body(bulletBody, entity, fixed); bodies_.append(body); bulletBody->setUserPointer(body); return body; }
PhysicsRigidBody * PhysicsMgr::createRigidBodyCylinder(float massValue, float topRadius, float bottomRadius, float height, Matrix44 transform) { auto rig = new PhysicsRigidBody(); btScalar mass(massValue); btTransform startTransform; startTransform.setIdentity(); bool isDynamic = (mass != 0.f); btCylinderShape* colShape = new btCylinderShapeZ(btVector3(topRadius, bottomRadius, height * 0.5)); btVector3 localInertia(0, 0, 0); if (isDynamic) { colShape->calculateLocalInertia(mass, localInertia); } startTransform.setFromOpenGLMatrix(transform.data()); auto btRig = shared()->createRigidBodyInternal(mass, startTransform, colShape, btVector4(1, 0, 0, 1)); rig->setRigidBody(btRig); rig->genUserIndex(); btRig->setUserIndex(rig->userIndex()); btRig->setUserPointer(rig); return rig; }
PhysicsRigidBody* PhysicsMgr::createRigidBody(float massValue, Matrix44& transform, AABB& aabb) { auto rig = new PhysicsRigidBody(); btScalar mass(massValue); btTransform startTransform; startTransform.setIdentity(); bool isDynamic = (mass != 0.f); vec3 half = aabb.half(); btBoxShape* colShape = shared()->createBoxShape(btVector3(half.x, half.y, half.z)); btVector3 localInertia(0, 0, 0); if (isDynamic) { colShape->calculateLocalInertia(mass, localInertia); } startTransform.setFromOpenGLMatrix(transform.data()); auto btRig = shared()->createRigidBodyInternal(mass, startTransform, colShape, btVector4(1, 0, 0, 1)); rig->setRigidBody(btRig); rig->genUserIndex(); btRig->setUserIndex(rig->userIndex()); btRig->setUserPointer(rig); return rig; }
PhysicsInterface::BodyObject Bullet::createBoundingBoxBody(const AABB& aabb, float mass, bool fixed, const Entity* entity, const SimpleTransform& initialTransform) { auto collisionShape = new btBoxShape(toBullet((aabb.getMaximum() - aabb.getMinimum()) * 0.5f)); // Calculate inertia auto localInertia = btVector3(0.0f, 0.0f, 0.0f); if (!fixed) collisionShape->calculateLocalInertia(mass, localInertia); // Motion state for this body auto motionState = new btDefaultMotionState(toBullet(initialTransform), btTransform(btQuaternion::getIdentity(), toBullet(aabb.getCenter()))); // Create Bullet rigid body auto bulletBody = new btRigidBody( btRigidBody::btRigidBodyConstructionInfo(fixed ? 0.0f : mass, motionState, collisionShape, localInertia)); bulletBody->setDamping(DefaultLinearDamping, DefaultAngularDamping); bulletBody->setSleepingThresholds(DefaultLinearSleepingThreshold, DefaultAngularSleepingThreshold); bulletBody->setRestitution(0.0f); // Add body to the simulation dynamicsWorld_->addRigidBody(bulletBody); // Create local body auto body = new Body(bulletBody, entity, fixed); bodies_.append(body); body->ownedCollisionShape = collisionShape; bulletBody->setUserPointer(body); return body; }