ptr<Character> BtWorld::CreateCharacter(ptr<Shape> abstractShape, const mat4x4& startTransform) { try { ptr<BtShape> shape = abstractShape.FastCast<BtShape>(); if(!shape) THROW("Non-bullet shape"); btConvexShape* collisionShape = fast_cast<btConvexShape*>(shape->GetInternalObject()); btPairCachingGhostObject* ghost = new btPairCachingGhostObject(); ghost->setWorldTransform(toBt(startTransform)); ghost->setCollisionShape(collisionShape); ghost->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT); // 2 - номер оси "вверх" - Z btKinematicCharacterController* controller = new btKinematicCharacterController(ghost, collisionShape, 0.5f, 2); dynamicsWorld->addCollisionObject(ghost); //dynamicsWorld->addCollisionObject(ghost, btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter); dynamicsWorld->addAction(controller); return NEW(BtCharacter(this, shape, ghost, controller)); } catch(Exception* exception) { THROW_SECONDARY("Can't create bullet character", exception); } }
ptr<RigidBody> BtWorld::CreateRigidBody(ptr<Shape> abstractShape, float mass, const mat4x4& startTransform) { try { ptr<BtShape> shape = abstractShape.FastCast<BtShape>(); if(!shape) THROW("Non-bullet shape"); btCollisionShape* collisionShape = shape->GetInternalObject(); btVector3 localInertia(0, 0, 0); if(mass != 0) collisionShape->calculateLocalInertia(mass, localInertia); ptr<BtRigidBody> rigidBody = NEW(BtRigidBody(this, shape, toBt(startTransform))); btRigidBody::btRigidBodyConstructionInfo info(mass, &*rigidBody, shape->GetInternalObject(), localInertia); btRigidBody* internalRigidBody = new btRigidBody(info); rigidBody->SetInternalObject(internalRigidBody); dynamicsWorld->addRigidBody(internalRigidBody); return rigidBody; } catch(Exception* exception) { THROW_SECONDARY("Can't create bullet rigid body", exception); } }
PhysicsBox::PhysicsBox(PhysicsWorld* world, const Vec3& extend) : PhysicsCollisionShape(world, ShapeType::BOX) { m_box.init(toBt(extend)); m_box->setMargin(getWorld().getCollisionMargin()); m_box->setUserPointer(static_cast<PhysicsObject*>(this)); }
void PhysicsActor::set6DofConstraint(Ogre::Vector3 linear_lower_limit, Ogre::Vector3 linear_upper_limit, Ogre::Vector3 angular_lower_limit, Ogre::Vector3 angular_upper_limit) { removeConstraints(); btTransform identity = btTransform::getIdentity(); btTransform transform; transform.setIdentity(); transform.setOrigin(rigid_body_->getWorldTransform().getOrigin()); constraint_ = new btGeneric6DofConstraint(*rigid_body_, dummy_constraint_body_, identity, transform, false); constraint_->setAngularLowerLimit(toBt(angular_lower_limit)); constraint_->setAngularUpperLimit(toBt(angular_upper_limit)); constraint_->setLinearLowerLimit(toBt(linear_lower_limit)); constraint_->setLinearUpperLimit(toBt(linear_upper_limit)); if (physics_enabled_) { physics_->dynamics_world()->addConstraint(constraint_); constraint_is_added_ = true; } }
void PhysicsActor::set_scale(Ogre::Vector3 scale) { rigid_body_->getCollisionShape()->setLocalScaling(toBt(scale)); btVector3 local_inertia(0, 0, 0); rigid_body_->getCollisionShape()->calculateLocalInertia(mass_, local_inertia); rigid_body_->setMassProps(mass_, local_inertia); rigid_body_->updateInertiaTensor(); // This is required to make the new size update immediately, not sure why if (physics_enabled_) { removeActorFromDynamicsWorld(); addActorToDynamicsWorld(); } }
ptr<Shape> BtWorld::CreateBoxShape(const vec3& halfSize) { try { btCollisionShape* collisionShape = new btBoxShape(toBt(halfSize)); return NEW(BtShape(this, collisionShape)); } catch(Exception* exception) { THROW_SECONDARY("Can't create bullet box shape", exception); } }
void BeliefCollisionChecker::compute_multi_tf(Configuration& rad, const vector<KinBody::LinkPtr>& links, const vector<DblVec>& multi_joints, vector<vector<btTransform> >* output_multi_tf) { assert (output_multi_tf != nullptr); output_multi_tf->clear(); int nlinks = links.size(); for (int i = 0; i < nlinks; ++i) { output_multi_tf->push_back(vector<btTransform>(multi_joints.size())); } for (int i_multi=0; i_multi<multi_joints.size(); i_multi++) { rad.SetDOFValues(multi_joints[i_multi]); for (int i_link=0; i_link < nlinks; ++i_link) { (*output_multi_tf)[i_link][i_multi] = toBt(links[i_link]->GetTransform()); } } }
PhysicsTriangleSoup::PhysicsTriangleSoup( PhysicsWorld* world, ConstWeakArray<Vec3> positions, ConstWeakArray<U32> indices, Bool convex) : PhysicsCollisionShape(world, ShapeType::TRI_MESH) { if(!convex) { ANKI_ASSERT((indices.getSize() % 3) == 0); m_mesh.init(); for(U i = 0; i < indices.getSize(); i += 3) { m_mesh->addTriangle( toBt(positions[indices[i]]), toBt(positions[indices[i + 1]]), toBt(positions[indices[i + 2]])); } // Create the dynamic shape m_triMesh.m_dynamic.init(m_mesh.get()); m_triMesh.m_dynamic->setMargin(getWorld().getCollisionMargin()); m_triMesh.m_dynamic->updateBound(); m_triMesh.m_dynamic->setUserPointer(static_cast<PhysicsObject*>(this)); // And the static one m_triMesh.m_static.init(m_mesh.get(), true); m_triMesh.m_static->setMargin(getWorld().getCollisionMargin()); m_triMesh.m_static->setUserPointer(static_cast<PhysicsObject*>(this)); } else { m_type = ShapeType::CONVEX; // Fake the type m_convex.init(&positions[0][0], positions.getSize(), sizeof(Vec3)); m_convex->setMargin(getWorld().getCollisionMargin()); m_convex->setUserPointer(static_cast<PhysicsObject*>(this)); } }
ptr<Shape> BtWorld::CreateCompoundShape(const std::vector<std::pair<mat4x4, ptr<Shape> > >& shapes) { BEGIN_TRY(); btCompoundShape* compoundShape = new btCompoundShape(false); for(size_t i = 0; i < shapes.size(); ++i) { const auto& p = shapes[i]; compoundShape->addChildShape(toBt(p.first), p.second.FastCast<BtShape>()->GetInternalObject()); } return NEW(BtShape(this, compoundShape)); END_TRY("Can't create bullet compound shape"); }
PlayerPhysicsComponent::PlayerPhysicsComponent(GameObject &gameObject, float mass) : PhysicsComponent(gameObject, CollisionGroup::Characters, CollisionGroup::Everything) { collisionShape = UPtr<btCollisionShape>(new btCapsuleShape(PLAYER_RADIUS, PLAYER_MIDDLE_HEIGHT)); collisionShape->setLocalScaling(toBt(gameObject.getScale())); motionState = UPtr<btMotionState>(new PlayerMotionState(gameObject)); btVector3 inertia(0.0f, 0.0f, 0.0f); collisionShape->calculateLocalInertia(mass, inertia); btRigidBody::btRigidBodyConstructionInfo constructionInfo(mass, motionState.get(), collisionShape.get(), inertia); UPtr<btRigidBody> rigidBody(new btRigidBody(constructionInfo)); rigidBody->setAngularFactor(0.0f); // Prevent the capsule from falling over rigidBody->setSleepingThresholds(0.0f, 0.0f); // Prevent the capsule from sleeping collisionObject = std::move(rigidBody); }
void PhysicsActor::applyForce(const Ogre::Vector3 &force, const Ogre::Vector3 &rel_pos) { rigid_body_->applyForce(toBt(force), toBt(rel_pos)); }
void PhysicsActor::applyCentralForce(const Ogre::Vector3 &force) { rigid_body_->applyCentralForce(toBt(force)); }
void PhysicsActor::applyImpulse(const Ogre::Vector3 &impulse, const Ogre::Vector3 &rel_pos) { rigid_body_->applyImpulse(toBt(impulse), toBt(rel_pos)); }
void PhysicsActor::applyCentralImpulse(const Ogre::Vector3 &impulse) { rigid_body_->applyCentralImpulse(toBt(impulse)); }
void PhysicsActor::setPose(Ogre::Vector3 position, Ogre::Quaternion orientation) { position_ = toBt(position); orientation_ = toBt(orientation); updateTransform(); }
void PhysicsActor::set_linear_velocity(Ogre::Vector3 linear_velocity) { rigid_body_->setLinearVelocity(toBt(linear_velocity)); }
void PhysicsActor::set_angular_velocity(Ogre::Vector3 angular_velocity) { rigid_body_->setAngularVelocity(toBt(angular_velocity)); }
void PlayerMotionState::getWorldTransform(btTransform &worldTrans) const { worldTrans.setOrigin(toBt(gameObject.getPosition())); worldTrans.setRotation(toBt(glm::quat())); }
void BtRigidBody::ApplyImpulse(const vec3& impulse, const vec3& point) { rigidBody->applyImpulse(toBt(impulse), toBt(point) - transform.getOrigin()); }
void BtCharacter::Walk(const vec3& speed) { controller->setVelocityForTimeInterval(toBt(speed), 1); }
bool ThrowAbility::use() { if (isOnCooldown()) { return false; } SPtr<Scene> scene = gameObject.getScene().lock(); if (!scene) { return false; } const glm::vec3 &position = gameObject.getCameraComponent().getCameraPosition(); const glm::vec3 &front = gameObject.getCameraComponent().getFrontVector(); const glm::vec3 &right = gameObject.getCameraComponent().getRightVector(); SPtr<GameObject> projectile(std::make_shared<GameObject>()); projectile->setPosition(position + front + right * 0.25f); projectile->setScale(glm::vec3(PROJECTILE_SCALE)); // Graphics SPtr<Model> playerModel = gameObject.getGraphicsComponent().getModel(); SPtr<Mesh> mesh = Context::getInstance().getAssetManager().loadMesh("meshes/rock_attack.obj"); glm::vec3 color(1.0f, 0.75f, 0.15f); PlayerLogicComponent *playerLogic = dynamic_cast<PlayerLogicComponent*>(&gameObject.getLogicComponent()); if (playerLogic) { color = playerLogic->getColor(); } SPtr<Material> material(std::make_shared<PhongMaterial>(color * 0.2f, color * 0.6f, glm::vec3(0.2f), color * 0.2f, 50.0f)); SPtr<Model> model(std::make_shared<Model>(playerModel->getShaderProgram(), mesh)); model->attachMaterial(material); projectile->setGraphicsComponent(std::make_shared<GeometricGraphicsComponent>(*projectile)); projectile->getGraphicsComponent().setModel(model); // Physics projectile->setPhysicsComponent(std::make_shared<MeshPhysicsComponent>(*projectile, 0.05f, CollisionGroup::Projectiles, CollisionGroup::Everything)); btRigidBody *projectileRigidBody = dynamic_cast<btRigidBody*>(projectile->getPhysicsComponent().getCollisionObject()); projectileRigidBody->setFriction(1.0f); projectileRigidBody->setRollingFriction(0.25f); projectileRigidBody->setRestitution(0.5f); projectileRigidBody->applyCentralForce(toBt(front * 100.0f)); // Logic SPtr<ProjectileLogicComponent> logic(std::make_shared<ProjectileLogicComponent>(*projectile)); WPtr<GameObject> wProjectile(projectile); GameObject &creator = gameObject; logic->setCollisionCallback([wProjectile, color, &creator](GameObject &gameObject, const btCollisionObject *objectCollidedWidth, const float dt) { if (objectCollidedWidth == creator.getPhysicsComponent().getCollisionObject()) { return; } SPtr<Scene> scene = gameObject.getScene().lock(); if (!scene) { return; } SPtr<GameObject> projectile = wProjectile.lock(); if (!projectile) { return; } scene->removeObject(projectile); SPtr<GameObject> explosion(createExplosion(projectile->getPosition(), 1.0f, color)); scene->addLight(explosion); scene->addObject(explosion); }); projectile->setLogicComponent(logic); // Audio SPtr<AudioComponent> audioComponent(std::make_shared<AudioComponent>(*projectile)); audioComponent->registerSoundEvent(Event::SET_SCENE, SoundGroup::THROW); projectile->setAudioComponent(audioComponent); scene->addObject(projectile); resetTimeSinceLastUse(); return true; }
void BtRigidBody::ApplyForce(const vec3& force, const vec3& point) { rigidBody->applyForce(toBt(force), toBt(point) - transform.getOrigin()); }
void PhysicsActor::set_position(Ogre::Vector3 position) { position_ = toBt(position); updateTransform(); }
void PhysicsActor::set_orientation(Ogre::Quaternion orientation) { orientation_ = toBt(orientation); updateTransform(); }
inline btTransform toBt(const mat4x4& a) { return btTransform(toBt(submat<float, 3, 3>(a)), btVector3(a(0, 3), a(1, 3), a(2, 3))); }