Пример #1
0
// Creates a Box object, including the associated Bullet rigid
// body, and sets its collision shape to a bullet box shape.
// If the object is specified to be kinematic, then the appropriate setup
// is done to the rigid body to make it kinematic within Bullet.
// position: where to create the box.
// dimensions: the dimensions of the box
// density: the density of the box (which, with the dimensions, determines its mass)
// isKinematic: flag to determine if this object will be kinematic or not
Box::Box(double position[3], double dimensions[3], double density, bool isKinematic)
{
	x = dimensions[0];
	y = dimensions[1];
	z = dimensions[2];
	double mass = x * y * z * density;
	
	btCollisionShape* boxCollision = new btBoxShape(btVector3(x * 0.5, y * 0.5, z * 0.5));
	btDefaultMotionState* boxState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(position[0], position[1], position[2])));
	btVector3 boxInertia(0, 0, 0);
	boxCollision->calculateLocalInertia(mass, boxInertia);
	btRigidBody::btRigidBodyConstructionInfo boxInfo(mass, boxState, boxCollision, boxInertia);
	btRigidBody* rb = new btRigidBody(boxInfo);
	
	// set the kinematic flag and set up the rigid body as kinematic if necessary
	setKinematic(isKinematic);
	if (isKinematic)
	{
		rb->setCollisionFlags(rb->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
		rb->setActivationState(DISABLE_DEACTIVATION);
	}

	// set the rigid body associated with this SceneObject.
	setRigidBody(rb);
}
Пример #2
0
PhysicsRigidBody::PhysicsRigidBody(Node* node, const PhysicsCollisionShape::Definition& shape, const Parameters& parameters, int group, int mask)
        : PhysicsCollisionObject(node, group, mask), _body(NULL), _mass(parameters.mass), _constraints(NULL), _inDestructor(false)
{
    GP_ASSERT(Game::getInstance()->getPhysicsController());
    GP_ASSERT(_node);

    // Create our collision shape.
    kmVec3 centerOfMassOffset = vec3Zero;
    _collisionShape = Game::getInstance()->getPhysicsController()->createShape(node, shape, &centerOfMassOffset, parameters.mass != 0.0f);
    GP_ASSERT(_collisionShape && _collisionShape->getShape());

    // Create motion state object.
	_motionState = new PhysicsMotionState(node, this, (kmVec3LengthSq(&centerOfMassOffset) > MATH_EPSILON) ? &centerOfMassOffset : NULL);

    // If the mass is non-zero, then the object is dynamic so we calculate the local 
    // inertia. However, if the collision shape is a triangle mesh, we don't calculate 
    // inertia since Bullet doesn't currently support this.
    btVector3 localInertia(0.0, 0.0, 0.0);
    if (parameters.mass != 0.0)
        _collisionShape->getShape()->calculateLocalInertia(parameters.mass, localInertia);

    // Create the Bullet physics rigid body object.
    btRigidBody::btRigidBodyConstructionInfo rbInfo(parameters.mass, NULL, _collisionShape->getShape(), localInertia);
    rbInfo.m_friction = parameters.friction;
    rbInfo.m_restitution = parameters.restitution;
    rbInfo.m_linearDamping = parameters.linearDamping;
    rbInfo.m_angularDamping = parameters.angularDamping;

    // Create + assign the new bullet rigid body object.
    _body = bullet_new<btRigidBody>(rbInfo);

    // Set motion state after rigid body assignment, since bullet will callback on the motion state interface to query
    // the initial transform and it will need to access to rigid body (_body).
    _body->setMotionState(_motionState);

    // Set other initially defined properties.
    setKinematic(parameters.kinematic);
    setAnisotropicFriction(parameters.anisotropicFriction);
    setAngularFactor(parameters.angularFactor);
    setLinearFactor(parameters.linearFactor);

    // Add ourself to the physics world.
    Game::getInstance()->getPhysicsController()->addCollisionObject(this);

    if (_collisionShape->getType() == PhysicsCollisionShape::SHAPE_HEIGHTFIELD)
    {
        // Add a listener on the node's transform so we can track dirty changes to calculate
        // an inverse kmMat4 for transforming heightfield points between world and local space.
        _node->addListener(this);
    }
}
Пример #3
0
PhysicsRigidBody::PhysicsRigidBody(Node* node, const PhysicsCollisionShape::Definition& shape, const Parameters& parameters)
        : PhysicsCollisionObject(node), _body(NULL), _mass(parameters.mass), _constraints(NULL), _inDestructor(false)
{
    GP_ASSERT(Game::getInstance()->getPhysicsController());
    GP_ASSERT(_node);

    // Create our collision shape.
    Vector3 centerOfMassOffset;
    _collisionShape = Game::getInstance()->getPhysicsController()->createShape(node, shape, &centerOfMassOffset);
    GP_ASSERT(_collisionShape && _collisionShape->getShape());

    // Create motion state object.
    _motionState = new PhysicsMotionState(node, (centerOfMassOffset.lengthSquared() > MATH_EPSILON) ? &centerOfMassOffset : NULL);

    // If the mass is non-zero, then the object is dynamic so we calculate the local 
    // inertia. However, if the collision shape is a triangle mesh, we don't calculate 
    // inertia since Bullet doesn't currently support this.
    btVector3 localInertia(0.0, 0.0, 0.0);
    if (parameters.mass != 0.0 && _collisionShape->getType() != PhysicsCollisionShape::SHAPE_MESH)
        _collisionShape->getShape()->calculateLocalInertia(parameters.mass, localInertia);

    // Create the Bullet physics rigid body object.
    btRigidBody::btRigidBodyConstructionInfo rbInfo(parameters.mass, _motionState, _collisionShape->getShape(), localInertia);
    rbInfo.m_friction = parameters.friction;
    rbInfo.m_restitution = parameters.restitution;
    rbInfo.m_linearDamping = parameters.linearDamping;
    rbInfo.m_angularDamping = parameters.angularDamping;

    // Create + assign the new bullet rigid body object.
    _body = bullet_new<btRigidBody>(rbInfo);

    // Set other initially defined properties.
    setKinematic(parameters.kinematic);
    setAnisotropicFriction(parameters.anisotropicFriction);
    setGravity(parameters.gravity);

    // Add ourself to the physics world.
    Game::getInstance()->getPhysicsController()->addCollisionObject(this);

    if (_collisionShape->getType() == PhysicsCollisionShape::SHAPE_HEIGHTFIELD)
    {
        // Add a listener on the node's transform so we can track dirty changes to calculate
        // an inverse matrix for transforming heightfield points between world and local space.
        _node->addListener(this);
    }
}
Пример #4
0
void EntityMotionState::updateKinematicState(uint32_t substep) {
    setKinematic(_entity->isMoving(), substep);
}
Пример #5
0
bool Physics3DKinematicDemo::init()
{
    if (!Physics3DTestDemo::init())
        return false;

    //create floor
    Physics3DRigidBodyDes rbDes;
    rbDes.mass = 0.0f;
    rbDes.shape = Physics3DShape::createBox(Vec3(60.0f, 1.0f, 60.0f));
    auto floor = PhysicsSprite3D::create("Sprite3DTest/box.c3t", &rbDes);
    floor->setTexture("Sprite3DTest/plane.png");
    floor->setScaleX(60);
    floor->setScaleZ(60);
    floor->setPosition3D(Vec3(0.f, -1.f, 0.f));
    this->addChild(floor);
    floor->setCameraMask((unsigned short)CameraFlag::USER1);
    floor->syncNodeToPhysics();
    //static object sync is not needed
    floor->setSyncFlag(Physics3DComponent::PhysicsSyncFlag::NONE);

    //create Kinematics
    for (unsigned int i = 0; i < 3; ++i)
    {
        rbDes.mass = 0.f; //kinematic objects. zero mass so that it can not be affected by other dynamic objects
        rbDes.shape = Physics3DShape::createBox(Vec3(2.0f, 2.0f, 2.0f));
        
        auto sprite = PhysicsSprite3D::create("Sprite3DTest/box.c3t", &rbDes);
        sprite->setTexture("Images/CyanSquare.png");
        sprite->setCameraMask((unsigned short)CameraFlag::USER1);
        auto rigidBody = static_cast<Physics3DRigidBody*>(sprite->getPhysicsObj());
        rigidBody->setKinematic(true);
        
        this->addChild(sprite);

        sprite->setScale(2.0f);
        sprite->setPosition3D(Vec3(-15.0f, 0.0f, 15.0f - 15.0f * i));
        auto moveby = MoveBy::create(2.0f + i, Vec3(30.0f, 0.0f, 0.0f));
        sprite->runAction(RepeatForever::create(Sequence::create(moveby, moveby->reverse(), nullptr)));
    }

    //create Dynamic
    {
        //create several spheres
        rbDes.mass = 1.f;
        rbDes.shape = Physics3DShape::createSphere(0.5f);
        float start_x = START_POS_X - ARRAY_SIZE_X/2;
        float start_y = START_POS_Y + 5.0f;
        float start_z = START_POS_Z - ARRAY_SIZE_Z/2;

        for (int k=0;k<ARRAY_SIZE_Y;k++)
        {
            for (int i=0;i<ARRAY_SIZE_X;i++)
            {
                for(int j = 0;j<ARRAY_SIZE_Z;j++)
                {
                    float x = 1.0*i + start_x;
                    float y = 5.0+1.0*k + start_y;
                    float z = 1.0*j + start_z;
                    rbDes.originalTransform.setIdentity();
                    rbDes.originalTransform.translate(x, y, z);

                    auto sprite = PhysicsSprite3D::create("Sprite3DTest/sphere.c3b", &rbDes);
                    sprite->setTexture("Sprite3DTest/plane.png");
                    sprite->setCameraMask((unsigned short)CameraFlag::USER1);
                    sprite->setScale(1.0f / sprite->getContentSize().width);
                    this->addChild(sprite);
                    sprite->setPosition3D(Vec3(x, y, z));
                    sprite->syncNodeToPhysics();
                    
                    sprite->setSyncFlag(Physics3DComponent::PhysicsSyncFlag::PHYSICS_TO_NODE);
                }
            }
        }
    }


    physicsScene->setPhysics3DDebugCamera(_camera);
    return true;
}
Пример #6
0
bool Physics3DColliderDemo::init()
{
    if (!Physics3DTestDemo::init())
        return false;

    Physics3DRigidBodyDes rbDes;
    rbDes.mass = 1.0f;
    rbDes.shape = Physics3DShape::createBox(Vec3(3.0f, 3.0f, 3.f));
    auto playerBody = Physics3DRigidBody::create(&rbDes);
    auto component = Physics3DComponent::create(playerBody);
    playerBody->setKinematic(true);
    auto sprite = Sprite3D::create("Sprite3DTest/box.c3t");
    sprite->setTexture("Sprite3DTest/plane.png");
    sprite->setScale(3.f);
    sprite->setPosition3D(Vec3(0.0f, 0.f, 30.f));
    sprite->addComponent(component);
    sprite->setCameraMask((unsigned short)CameraFlag::USER1);
    auto moveby = MoveBy::create(5.0f, Vec3(0.0f, 0.0f, -60.0f));
    sprite->runAction(RepeatForever::create(Sequence::create(moveby, moveby->reverse(), nullptr)));
    this->addChild(sprite);

    {
        Physics3DColliderDes colliderDes;
        colliderDes.shape = Physics3DShape::createSphere(10.0f);
        colliderDes.isTrigger = true;
        auto collider = Physics3DCollider::create(&colliderDes);
        auto component = Physics3DComponent::create(collider);
        auto node = Node::create();
        node->addComponent(component);
        node->setCameraMask((unsigned short)CameraFlag::USER1);
        this->addChild(node);

        Physics3DRigidBodyDes rbDes;
        rbDes.mass = 1.0f;
        rbDes.shape = Physics3DShape::createBox(Vec3(10.0f, 10.0f, 1.f));
        auto rigidBody = Physics3DRigidBody::create(&rbDes);
        component = Physics3DComponent::create(rigidBody);
        rigidBody->setKinematic(true);
        auto doorLeft = Sprite3D::create("Sprite3DTest/box.c3t");
        doorLeft->setTexture("Sprite3DTest/plane.png");
        doorLeft->setScaleX(10.0f);
        doorLeft->setScaleY(10.0f);
        doorLeft->setScaleZ(1.0f);
        doorLeft->setPosition3D(Vec3(-5.0f, 0.0f, 0.0f));
        doorLeft->addComponent(component);
        doorLeft->setCameraMask((unsigned short)CameraFlag::USER1);
        node->addChild(doorLeft);

        rbDes.mass = 1.0f;
        rbDes.shape = Physics3DShape::createBox(Vec3(10.0f, 10.0f, 1.f));
        rigidBody = Physics3DRigidBody::create(&rbDes);
        component = Physics3DComponent::create(rigidBody);
        rigidBody->setKinematic(true);
        auto doorRight = Sprite3D::create("Sprite3DTest/box.c3t");
        doorRight->setTexture("Sprite3DTest/plane.png");
        doorRight->setScaleX(10.0f);
        doorRight->setScaleY(10.0f);
        doorRight->setScaleZ(1.0f);
        doorRight->setPosition3D(Vec3(5.0f, 0.0f, 0.0f));
        doorRight->addComponent(component);
        doorRight->setCameraMask((unsigned short)CameraFlag::USER1);
        node->addChild(doorRight);


        collider->onTriggerEnter = [=](Physics3DObject *otherObject){
            if (otherObject == playerBody){
                auto moveby = MoveBy::create(1.0f, Vec3(-5.0f, 0.0f, 0.0f));
                doorLeft->runAction(moveby);
                doorRight->runAction(moveby->reverse());
            }
        };

        collider->onTriggerExit = [=](Physics3DObject *otherObject){
            if (otherObject == playerBody){
                auto moveby = MoveBy::create(1.0f, Vec3(5.0f, 0.0f, 0.0f));
                doorLeft->runAction(moveby);
                doorRight->runAction(moveby->reverse());
            }
        };
    }

    physicsScene->setPhysics3DDebugCamera(_camera);
    return true;
}