예제 #1
0
void RigidBody::CreateBody()
{
    if (!impl->world || impl->body || !ParentEntity())
        return;
    
    CheckForPlaceableAndTerrain();
    
    CreateCollisionShape();
    
    btVector3 localInertia;
    float m;
    int collisionFlags;
    
    impl->GetProperties(localInertia, m, collisionFlags);
    
    impl->body = new btRigidBody(m, impl, impl->shape, localInertia);
    // TEST: Adjust the threshold of when to sleep the object - for reducing network bandwidth.
//    impl->body->setSleepingThresholds(0.2f, 0.5f); // Bullet defaults are 0.8 and 1.0.
    impl->body->setUserPointer(this);
    impl->body->setCollisionFlags(collisionFlags);
    impl->world->BulletWorld()->addRigidBody(impl->body, (short)collisionLayer.Get(), (short)collisionMask.Get());
    impl->body->activate();
    
    UpdateGravity();
}
예제 #2
0
/**
  * Scene_Container owns this method because I, Dylan, have made an executive decision to make lights bound to
  * the laws of physics impossible; I see no point for it (except for flashlights maybe). Our lights will be static, 
  * so the initialization of rigid bodies can be the sole responsibility of the Scene_Container, because it knows
  * about all of its own vertices.
  *
  * TODO:	Support more than just Convex Hull Shape for collision detection; Triangle Mesh Shape might be more
  *			appropriate for static game objects.
 **/
void Scene_Container::InitRigidBody(btScalar mass)
{
	// Create the collision shape
	CreateCollisionShape();
	btVector3 localInertia(0, 0, 0);
	isDynamic = (mass != 0.f);
	if (isDynamic)
		collisionShape->calculateLocalInertia(mass, localInertia);
	btTransform* transform = new btTransform(
		btQuaternion(this->transform.rotation.x, 
			this->transform.rotation.y, 
			this->transform.rotation.z, 
			this->transform.rotation.w),
		btVector3(this->transform.position.x, 
			this->transform.position.y, 
			this->transform.position.z));
	btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(
		mass,
		new btDefaultMotionState(*transform),
		collisionShape,
		localInertia);
	rigidBody = new btRigidBody(rigidBodyCI);
	rigidBody->setUserPointer(this);
	Physics_Manager::GetInstance()->AddRigidBody(rigidBody);
}
예제 #3
0
int CcdChapter::Init()
{
	CreateScene();

	//	load resource
	LoadResource();

	CreateBullet();

	Plane plane(Vector3::UNIT_Y, 0);
	MeshManager::getSingleton().createPlane("ground", ResourceGroup, plane, 500, 500, 1, 1, true, 1, 5, 5, Vector3::UNIT_Z);

	Entity *groundEntity = m_pkSceneManager->createEntity("GroundEntity", "ground");
	groundEntity->setMaterialName("BulletPlane", ResourceGroup);
	groundEntity->setCastShadows(true);
	SceneNode *pkNode = m_pkRootNode->createChildSceneNode();
	pkNode->attachObject(groundEntity);

	btCollisionShape *shape = CreateCollisionShape(SHAPE_TYPE::SHAPE_PLANE, Vector3::ZERO);
	m_CollisionShapes.push_back(shape);
	btRigidBody *body = CreateRigidBody(shape, false, pkNode, 100);
	m_RigidBodies.push_back(body);
	m_pkDynamicsWorld->addRigidBody(body);
	body->setUserPointer(pkNode);
	//body->setFriction(100);



	return 0;
}
예제 #4
0
void RigidBody::TerrainUpdated(IAttribute* attribute, AttributeChange::Type /*change*/)
{
    Terrain* terrain = impl->terrain;
    if (!terrain)
        return;
    /// \todo It is suboptimal to regenerate the whole heightfield when just the terrain's transform changes
    if (attribute == &terrain->nodeTransformation && shapeType.Get() == HeightField)
        CreateCollisionShape();
}
예제 #5
0
void RigidBody::OnCollisionMeshAssetLoaded(AssetPtr asset)
{
    IMeshAsset* meshAsset = dynamic_cast<IMeshAsset*>(asset.Get());
    if (!meshAsset)
        LogError("RigidBody::OnCollisionMeshAssetLoaded: Mesh asset load finished for asset \"" +
            asset->Name() + "\", but asset pointer was null!");

    if (shapeType.Get() == TriMesh)
    {
        impl->triangleMesh = impl->owner->GetTriangleMeshFromMeshAsset(meshAsset);
        CreateCollisionShape();
    }
    else if (shapeType.Get() == ConvexHull)
    {
        impl->convexHullSet = impl->owner->GetConvexHullSetFromMeshAsset(meshAsset);
        CreateCollisionShape();
    }

    impl->cachedShapeType = shapeType.Get();
    impl->cachedSize = size.Get();
}
예제 #6
0
void RigidBody::AttributesChanged()
{
    if (impl->disconnected)
        return;
    
    bool isShapeTriMeshOrConvexHull = (shapeType.Get() == TriMesh || shapeType.Get() == ConvexHull);
    bool bodyRead = false;
    bool meshRequested = false;

    // Create body now if does not exist yet
    if (!impl->body)
        CreateBody();
    // If body was not created (we do not actually have a physics world), exit
    if (!impl->body)
        return;
    
    if (mass.ValueChanged() || collisionLayer.ValueChanged() || collisionMask.ValueChanged())
    {
        // Read body to the world in case static/dynamic classification changed, or if collision mask changed
        ReaddBody();
        bodyRead = true;
    }
    
    if (friction.ValueChanged())
        impl->body->setFriction(friction.Get());
    
    if (rollingFriction.ValueChanged())
        impl->body->setRollingFriction(rollingFriction.Get());
    
    if (restitution.ValueChanged())
        impl->body->setRestitution(friction.Get());
    
    if (linearDamping.ValueChanged() || angularDamping.ValueChanged())
         impl->body->setDamping(linearDamping.Get(), angularDamping.Get());
    
    if (linearFactor.ValueChanged())
        impl->body->setLinearFactor(linearFactor.Get());
    
    if (angularFactor.ValueChanged())
        impl->body->setAngularFactor(angularFactor.Get());
    
    if (shapeType.ValueChanged() || size.ValueChanged())
    {
        if (shapeType.Get() != impl->cachedShapeType || !size.Get().Equals(impl->cachedSize))
        {
            // If shape does not involve mesh, can create it directly. Otherwise request the mesh
            if (!isShapeTriMeshOrConvexHull)
            {
                CreateCollisionShape();
                impl->cachedShapeType = shapeType.Get();
                impl->cachedSize = size.Get();
            }
            // If shape type has changed from TrimMesh <--> ConvexHull refresh the mesh shape.
            else if (shapeType.Get() != impl->cachedShapeType)
            {
                RequestMesh();
                meshRequested = true;
            }
            // If size changed but no reload of mesh shape was done, update its scale.
            else if (!size.Get().Equals(impl->cachedSize))
                UpdateScale();
        }
    }
    
    // Request mesh if its id changes
    if (collisionMeshRef.ValueChanged() && isShapeTriMeshOrConvexHull && !meshRequested)
        RequestMesh();
    
    // Readd body to the world in case phantom or kinematic classification changed
    if (!bodyRead && (phantom.ValueChanged() || kinematic.ValueChanged()))
        ReaddBody();
    
    if (drawDebug.ValueChanged())
    {
        bool enable = drawDebug.Get();
        if (impl->body)
        {
            int collisionFlags = impl->body->getCollisionFlags();
            if (enable)
                collisionFlags &= ~btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT;
            else
                collisionFlags |= btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT;
            impl->body->setCollisionFlags(collisionFlags);
        }
        
        // Refresh PhysicsWorld's knowledge of debug-enabled rigidbodies
        if (impl->world)
        {
            if (enable)
                impl->world->debugRigidBodies_.Insert(this);
            else
                impl->world->debugRigidBodies_.Erase(this);
        }
    }
    
    if (linearVelocity.ValueChanged() && !impl->disconnected)
    {
        impl->body->setLinearVelocity(linearVelocity.Get());
        impl->body->activate();
    }
    
    if (angularVelocity.ValueChanged() && !impl->disconnected)
    {
        impl->body->setAngularVelocity(DegToRad(angularVelocity.Get()));
        impl->body->activate();
    }
    
    if (useGravity.ValueChanged())
        UpdateGravity();
}
예제 #7
0
void RigidBody::OnTerrainRegenerated()
{
    if (shapeType.Get() == HeightField)
        CreateCollisionShape();
}