u32 wsScene::addPrimitive(wsPrimitive* myPrimitive) { wsAssert(numPrimitives < WS_MAX_PRIMITIVES, "Cannot add another primitive to the scene. Maximum already reached."); primitives[numPrimitives] = myPrimitive; #if WS_PHYSICS_BACKEND == WS_BACKEND_BULLET switch (myPrimitive->getType()) { case WS_PRIM_TYPE_PLANE: { wsPlane* plane = (wsPlane*)myPrimitive; vec4 data = plane->getPosData(); btCollisionShape* planeShape = wsNew(btStaticPlaneShape, btStaticPlaneShape(btVector3(data.x, data.y, data.z), data.w)); btDefaultMotionState* planeState = wsNew(btDefaultMotionState, btDefaultMotionState(btTransform(btQuaternion(0.0f, 0.0f, 0.0f, 1.0f), btVector3(0.0f, 0.0f, 0.0f)))); btRigidBody::btRigidBodyConstructionInfo planeRigidBodyCI(0, planeState, planeShape, btVector3(0,0,0)); btRigidBody* groundRigidBody = wsNew(btRigidBody, btRigidBody(planeRigidBodyCI)); physicsWorld->addRigidBody(groundRigidBody, myPrimitive->getCollisionClass(), collisionClasses[(u32)wsLog2(myPrimitive->getCollisionClass())]); } break; case WS_PRIM_TYPE_CUBE: { wsCube* cube = (wsCube*)myPrimitive; vec4 dimensions = cube->getDimensions(); vec4 pos = cube->getPos(); quat rot = cube->getRot(); btCollisionShape* cubeShape = wsNew(btBoxShape, btBoxShape(btVector3(dimensions.x/2.0f, dimensions.y/2.0f, dimensions.z/2.0f))); btDefaultMotionState* cubeState = wsNew(btDefaultMotionState, btDefaultMotionState(btTransform(btQuaternion(rot.x, rot.y, rot.z, rot.w), btVector3(pos.x, pos.y, pos.z)))); btRigidBody::btRigidBodyConstructionInfo cubeRigidBodyCI(0, cubeState, cubeShape, btVector3(0, 0, 0)); btRigidBody* cubeRigidBody = wsNew(btRigidBody, btRigidBody(cubeRigidBodyCI)); physicsWorld->addRigidBody(cubeRigidBody, myPrimitive->getCollisionClass(), collisionClasses[(u32)wsLog2(myPrimitive->getCollisionClass())]); } break; default: break; } #endif return numPrimitives++; }
u32 wsScene::addModel(wsModel* myModel) { u32 modelHash = wsHash(myModel->getName()); if (models->insert(modelHash, myModel) == WS_SUCCESS) { #if WS_PHYSICS_BACKEND == WS_BACKEND_BULLET const vec4 dimensions = myModel->getBounds(); btCollisionShape* boundsShape; if (myModel->getCollisionShape() == WS_NULL) { boundsShape = wsNew(btBoxShape, btBoxShape(btVector3(dimensions.x, dimensions.y, dimensions.z))); } else { wsCollisionShape* shape = myModel->getCollisionShape(); switch (shape->getType()) { default: boundsShape = wsNew(btBoxShape, btBoxShape(btVector3(dimensions.x, dimensions.y, dimensions.z))); break; case WS_SHAPE_CAPSULE: boundsShape = wsNew(btCapsuleShape, btCapsuleShape(shape->getDim0(), shape->getDim1())); break; case WS_SHAPE_CUBE: boundsShape = wsNew(btBoxShape, btBoxShape(btVector3(shape->getDim0(), shape->getDim1(), shape->getDim2()))); break; case WS_SHAPE_CYLINDER: boundsShape = wsNew(btCylinderShape, btCylinderShape(btVector3(shape->getDim0(), shape->getDim1()/2.0f, shape->getDim0()))); break; case WS_SHAPE_SPHERE: boundsShape = wsNew(btSphereShape, btSphereShape(shape->getDim0())); break; } } f32 mass = myModel->getMass(); btVector3 myInertia(0.0f, 0.0f, 0.0f); boundsShape->calculateLocalInertia(mass, myInertia); btRigidBody::btRigidBodyConstructionInfo modelRigidBodyCI(mass, myModel->getTransformp(), boundsShape, myInertia); btRigidBody* modelRigidBody = wsNew(btRigidBody, btRigidBody(modelRigidBodyCI)); if (myModel->getProperties() & WS_MODEL_LOCK_HORIZ_ROTATIONS) { modelRigidBody->setAngularFactor(btVector3(0.0f, 0.0f, 0.0f)); } modelRigidBody->setActivationState(DISABLE_DEACTIVATION); rigidBodies->insert(modelHash, modelRigidBody); physicsWorld->addRigidBody(modelRigidBody, myModel->getCollisionClass(), collisionClasses[(u32)wsLog2(myModel->getCollisionClass())]); #endif return modelHash; } return WS_NULL; }// End addModel(wsModel*) method
void wsScene::addAnimation(wsAnimation* myAnim, const char* modelName) { wsModel* myModel = models->retrieve(wsHash(modelName)); myModel->addAnimation(myAnim); #if WS_PHYSICS_BACKEND == WS_BACKEND_BULLET char animName[512]; strcpy(animName, modelName); strcat(animName, myAnim->getName()); u32 boundsHash = wsHash(animName); const vec4 dimensions = myAnim->getBounds(); btCollisionShape* boundsShape; if (myModel->getCollisionShape() == WS_NULL) { boundsShape = wsNew(btBoxShape, btBoxShape(btVector3(dimensions.x, dimensions.y, dimensions.z))); } else { wsCollisionShape* shape = myModel->getCollisionShape(); switch (shape->getType()) { default: boundsShape = wsNew(btBoxShape, btBoxShape(btVector3(dimensions.x, dimensions.y, dimensions.z))); break; case WS_SHAPE_CAPSULE: boundsShape = wsNew(btCapsuleShape, btCapsuleShape(shape->getDim0(), shape->getDim1())); break; case WS_SHAPE_CUBE: boundsShape = wsNew(btBoxShape, btBoxShape(btVector3(shape->getDim0(), shape->getDim1(), shape->getDim2()))); break; case WS_SHAPE_CYLINDER: boundsShape = wsNew(btCylinderShape, btCylinderShape(btVector3(shape->getDim0(), shape->getDim1()/2.0f, shape->getDim0()))); break; case WS_SHAPE_SPHERE: boundsShape = wsNew(btSphereShape, btSphereShape(shape->getDim0())); break; } } f32 mass = myModel->getMass(); btVector3 myInertia(0.0f, 0.0f, 0.0f); boundsShape->calculateLocalInertia(mass, myInertia); btRigidBody::btRigidBodyConstructionInfo animRigidBodyCI(mass, myModel->getTransformp(), boundsShape, myInertia); btRigidBody* animRigidBody = wsNew(btRigidBody, btRigidBody(animRigidBodyCI)); if (myModel->getProperties() & WS_MODEL_LOCK_HORIZ_ROTATIONS) { animRigidBody->setAngularFactor(btVector3(0.0f, 0.0f, 0.0f)); } rigidBodies->insert(boundsHash, animRigidBody); #endif }// End addAnimation method
RigidBodyBullet::RigidBodyBullet() : RigidCollisionObjectBullet(CollisionObjectBullet::TYPE_RIGID_BODY), kinematic_utilities(NULL), locked_axis(0), gravity_scale(1), mass(1), linearDamp(0), angularDamp(0), can_sleep(true), omit_forces_integration(false), restitution_combine_mode(PhysicsServer::COMBINE_MODE_INHERIT), friction_combine_mode(PhysicsServer::COMBINE_MODE_INHERIT), force_integration_callback(NULL), isTransformChanged(false), previousActiveState(true), maxCollisionsDetection(0), collisionsCount(0), maxAreasWhereIam(10), areaWhereIamCount(0), countGravityPointSpaces(0), isScratchedSpaceOverrideModificator(false) { godotMotionState = bulletnew(GodotMotionState(this)); // Initial properties const btVector3 localInertia(0, 0, 0); btRigidBody::btRigidBodyConstructionInfo cInfo(mass, godotMotionState, compoundShape, localInertia); btBody = bulletnew(btRigidBody(cInfo)); setupBulletCollisionObject(btBody); set_mode(PhysicsServer::BODY_MODE_RIGID); reload_axis_lock(); areasWhereIam.resize(maxAreasWhereIam); for (int i = areasWhereIam.size() - 1; 0 <= i; --i) { areasWhereIam.write[i] = NULL; } btBody->setSleepingThresholds(0.2, 0.2); }
mass_ = mass; if (physics_enabled_) { removeActorFromDynamicsWorld(); addActorToDynamicsWorld(); } } bool PhysicsActor::collides_with_walls_only() { return collides_with_walls_only_; } bool PhysicsActor::collides_with_gridded_piles() { return collides_with_gridded_piles_; } static btRigidBody dummy_constraint_body_ = btRigidBody(0, 0, 0); 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));
RigidBodyComponent::RigidBodyComponent(float mass, btMotionState* motion, btCollisionShape* collision, vec3f inertia) : PhysicsComponent(New btRigidBody(mass, motion, collision, btVector3(inertia.x, inertia.y, inertia.z))), m_Motion(motion), m_Shape(collision) { assert(motion != nullptr); assert(collision != nullptr); }