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
Exemplo n.º 4
0
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);
}
Exemplo n.º 5
0
  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);
 }