Beispiel #1
0
PhysicsInterface::JointObject Bullet::createHingeJoint(BodyObject firstBodyObject, BodyObject secondBodyObject,
                                                       const Vec3& globalAnchor, const Vec3& globalAxis)
{
    if (!firstBodyObject || !secondBodyObject || firstBodyObject == secondBodyObject)
    {
        LOG_ERROR << "Invalid bodies";
        return nullptr;
    }

    auto firstBody = reinterpret_cast<Body*>(firstBodyObject);
    auto secondBody = reinterpret_cast<Body*>(secondBodyObject);

    auto firstBodyTransform = btTransform();
    auto secondBodyTransform = btTransform();
    firstBody->bulletBody->getMotionState()->getWorldTransform(firstBodyTransform);
    secondBody->bulletBody->getMotionState()->getWorldTransform(secondBodyTransform);

    auto btConstraint = new btHingeConstraint(*firstBody->bulletBody, *secondBody->bulletBody,
                                              firstBodyTransform.inverse() * toBullet(globalAnchor),
                                              secondBodyTransform.inverse() * toBullet(globalAnchor),
                                              firstBodyTransform.getBasis().inverse() * toBullet(globalAxis),
                                              secondBodyTransform.getBasis().inverse() * toBullet(globalAxis));

    joints_.append(new Joint(firstBody, secondBody, btConstraint));

    dynamicsWorld_->addConstraint(joints_.back()->bulletConstraint, true);

    return joints_.back();
}
void Context::init( const Format &format )
{
	
	mCollisionConfiguration = format.mConfiguration ? format.mConfiguration :
		!format.mCreateSoftRigidWorld ? new btDefaultCollisionConfiguration() : new btSoftBodyRigidBodyCollisionConfiguration();
	
	mCollisionDispatcher = format.mCollisionDispatcher ? format.mCollisionDispatcher : new btCollisionDispatcher(mCollisionConfiguration);
	mBroadPhase = format.mBroadphase ? format.mBroadphase : new btDbvtBroadphase();
	mSolver = format.mSolver ? format.mSolver : new btSequentialImpulseConstraintSolver();
	
	mWorld = format.mWorld ? format.mWorld :
		!format.mCreateSoftRigidWorld ? new btDiscreteDynamicsWorld( mCollisionDispatcher, mBroadPhase, mSolver, mCollisionConfiguration ) :
										new btSoftRigidDynamicsWorld( mCollisionDispatcher, mBroadPhase, mSolver, mCollisionConfiguration, format.mSoftBodySolver );
	
	// If we want to setup the debug renderer
	if( format.mCreateDebugRenderer ) {
		setupDebugRenderer( format.mDebugMode );
	}
	
	// This initializes the static pointer to the bullet context
	sBulletContext = this;
	sBulletContextInitialized = true;
	
	mWorld->setWorldUserInfo( this );
	mWorld->setGravity( toBullet( format.mGravity ) );
	if( format.mCreateSoftRigidWorld ) {
		auto worldInfo = getSoftBodyWorldInfo();
		worldInfo.m_gravity = toBullet( format.mGravity );
		// Add other world_info settings here from format.
	}
}
bool Context::closestRayCast( const ci::vec3 &startPosition, const ci::vec3 &direction, RayResult &result )
{
	if( ! world() )
		return false;
	
	btVector3 rayTo = toBullet( direction * 1000.0f );
	btVector3 rayFrom = toBullet( startPosition );
	
	btCollisionWorld::ClosestRayResultCallback rayCallback( rayFrom, rayTo );
	
	world()->rayTest( rayFrom, rayTo, rayCallback );
	
	if( rayCallback.hasHit() ) {
		
		btRigidBody* pBody = (btRigidBody*) btRigidBody::upcast( rayCallback.m_collisionObject );
		
		if(!pBody)
			return false;
		
		result.pBody = pBody;
		result.hitPoint = fromBullet( rayCallback.m_hitPointWorld );
		result.hitNormal = fromBullet( rayCallback.m_hitNormalWorld );
		
		return true;
	}
	
	return false;
}
Beispiel #4
0
Actor::Actor(const MWWorld::Ptr& ptr, osg::ref_ptr<const Resource::BulletShape> shape, btCollisionWorld* world)
  : mCanWaterWalk(false), mWalkingOnWater(false)
  , mCollisionObject(0), mForce(0.f, 0.f, 0.f), mOnGround(false)
  , mInternalCollisionMode(true)
  , mExternalCollisionMode(true)
  , mCollisionWorld(world)
{
    mPtr = ptr;

    mHalfExtents = shape->mCollisionBoxHalfExtents;
    mMeshTranslation = shape->mCollisionBoxTranslate;

    // Use capsule shape only if base is square (nonuniform scaling apparently doesn't work on it)
    if (std::abs(mHalfExtents.x()-mHalfExtents.y())<mHalfExtents.x()*0.05 && mHalfExtents.z() >= mHalfExtents.x())
    {
        // Could also be btCapsuleShapeZ, but the movement solver seems to have issues with it (jumping on slopes doesn't work)
        mShape.reset(new btCylinderShapeZ(toBullet(mHalfExtents)));
    }
    else
        mShape.reset(new btBoxShape(toBullet(mHalfExtents)));

    mCollisionObject.reset(new btCollisionObject);
    mCollisionObject->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT);
    mCollisionObject->setActivationState(DISABLE_DEACTIVATION);
    mCollisionObject->setCollisionShape(mShape.get());
    mCollisionObject->setUserPointer(static_cast<PtrHolder*>(this));

    updateRotation();
    updateScale();
    updatePosition();

    updateCollisionMask();
}
Beispiel #5
0
void Bullet::applyForceToBody(BodyObject bodyObject, const Vec3& force, ForceMode mode)
{
    if (!bodyObject)
        return;

    auto body = reinterpret_cast<Body*>(bodyObject);

    body->bulletBody->activate(true);

    if (mode == ForceStandard)
        body->bulletBody->applyCentralForce(toBullet(force * 100.0f));
    else if (mode == ForceImpulse)
        body->bulletBody->applyCentralImpulse(toBullet(force));
}
Beispiel #6
0
void Bullet::applyTorqueToBody(BodyObject bodyObject, const Vec3& torque, ForceMode mode)
{
    if (!bodyObject)
        return;

    auto body = reinterpret_cast<Body*>(bodyObject);

    body->bulletBody->activate(true);

    if (mode == ForceStandard)
        body->bulletBody->applyTorque(toBullet(torque));
    else if (mode == ForceImpulse)
        body->bulletBody->applyTorqueImpulse(toBullet(torque));
}
Beispiel #7
0
bool Bullet::raycast(const Ray& ray, PhysicsIntersectResult& result) const
{
    auto endPoint = ray.getPoint(MaxRayDistance);

    auto intersections = Vector<PhysicsIntersectResult>();
    auto callback = RayResultCollector(ray, intersections);
    dynamicsWorld_->rayTest(toBullet(ray.getOrigin()), toBullet(endPoint), callback);

    if (intersections.empty())
        return false;

    intersections.sort();
    result = intersections[0];

    return true;
}
Beispiel #8
0
PhysicsInterface::BodyObject Bullet::createCapsuleBody(float height, float radius, float mass, bool fixed,
                                                       const Entity* entity, const SimpleTransform& initialTransform)
{
    auto collisionShape = new btCapsuleShape(radius, height);

    // Calculate inertia
    auto localInertia = btVector3(0.0f, 0.0f, 0.0f);
    if (!fixed)
        collisionShape->calculateLocalInertia(mass, localInertia);

    // Motion state for this body
    auto motionState = new btDefaultMotionState(toBullet(initialTransform));

    // Create Bullet rigid body
    auto bulletBody = new btRigidBody(
        btRigidBody::btRigidBodyConstructionInfo(fixed ? 0.0f : mass, motionState, collisionShape, localInertia));

    bulletBody->setDamping(DefaultLinearDamping, DefaultAngularDamping);
    bulletBody->setSleepingThresholds(DefaultLinearSleepingThreshold, DefaultAngularSleepingThreshold);
    bulletBody->setRestitution(0.0f);

    // Add body to the simulation
    dynamicsWorld_->addRigidBody(bulletBody);

    // Create local body
    auto body = new Body(bulletBody, entity, fixed);
    bodies_.append(body);

    body->ownedCollisionShape = collisionShape;

    bulletBody->setUserPointer(body);

    return body;
}
Beispiel #9
0
void reEnemy::messageProcess( reMessageDispatcher* sender, reMessage* message )
{	
	switch (message->id)
	{
	case reM_MOUSE_PRESS:
		{
			reMouseMessage* mouseMessage = (reMouseMessage*)message;
			reVec3 dir = glm::normalize(mouseMessage->dir);
			reVec3 p(0,1,0);
			target = mouseMessage->p + mouseMessage->dir*(glm::dot(p, mouseMessage->p)/glm::dot(p, -mouseMessage->dir));
			reVec3 d = (mouseMessage->p.y / -dir.y) * dir + mouseMessage->p;
			assert(glm::length(d-target) < 0.1f);
		}
		break;
	case reM_TIMER:
		{
			reVec4 pos = worldTransform().matrix * reVec4(0,0,0,1);
			reVec3 dir = target - reVec3(pos);
			if (glm::length(dir)>.5f)
			{
				dir = glm::normalize(dir);
				body->btBody->applyCentralForce(toBullet(dir)*1000);
			}
			else
			{
				dir = -fromBullet(body->btBody->getLinearVelocity());
				body->btBody->applyCentralForce(toBullet(dir)*100);				
			}
			reVec3 v = fromBullet(body->btBody->getLinearVelocity());
			reNode* node = (reNode*)children->objectByName("model");
			reAnimator* animator = node->children->findObject<reAnimator>();
			if (glm::length(v) > 0.001f)
			{
				float angle = atan2(v.x, v.z);				
				node->transform(reTransform(glm::rotate(reMat4(), glm::degrees(angle), reVec3(0,1,0))));				
				animator->play((reSequence*)node->objectByName("walk"), .3);
				animator->stopAnimation("idle", .3);
			}
			else
			{
				animator->play((reSequence*)node->objectByName("idle"), .3);
				animator->stopAnimation("walk", .3);
			}
		}
		break;
	}
}
Beispiel #10
0
void Actor::updateCollisionObjectPosition()
{
    btTransform tr = mCollisionObject->getWorldTransform();
    osg::Vec3f scaledTranslation = mRotation * osg::componentMultiply(mMeshTranslation, mScale);
    osg::Vec3f newPosition = scaledTranslation + mPosition;
    tr.setOrigin(toBullet(newPosition));
    mCollisionObject->setWorldTransform(tr);
}
Beispiel #11
0
void RigidBody::init( const Format &format )
{
	mType = getPhyObjType( format.mCollShape->getName() );
	
	mCollGroup = format.mCollisionGroup;
	mCollMask = format.mCollisionMask;
	
	mCollisionShape = format.mCollShape;
	mCollisionShape->setLocalScaling( toBullet(format.mInitialScale) );

	recalculateBoundingSphere();
	
	btVector3 localInertia(0,0,0);
	
	if( format.mMass != 0.0f && ! format.mSetKinematic ) {
		mCollisionShape->calculateLocalInertia( format.mMass, localInertia );
	}
	
	mMotionState = format.mMotionState;
	
	btRigidBody::btRigidBodyConstructionInfo cInfo( format.mMass, mMotionState.get(), mCollisionShape.get(), localInertia );
	
	cInfo.m_friction = format.mFriction;
	cInfo.m_restitution = format.mRestitution;
	
	mRigidBody.reset( new btRigidBody(cInfo) );
	
	if( format.mSetKinematic ) {
		mRigidBody->setCollisionFlags( mRigidBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT );
		setActivationState( DISABLE_DEACTIVATION );
	}
	
	if( format.mAddToWorld ) {
		Context()->addRigidBody( mRigidBody.get(), mCollGroup, mCollMask );
		mAddedToWorld = true;
	}
	
	if( ! mMotionState ) {
		btTransform trans;
		trans.setOrigin( toBullet( format.mInitialPosition ) );
		trans.setRotation( toBullet( format.mInitialRotation ) );
		mRigidBody->setWorldTransform( trans );
	}
	
	mRigidBody->setUserPointer( format.mRigidBodyUserPtr ? format.mRigidBodyUserPtr : this );
}
Beispiel #12
0
void Bullet::moveCharacterController(CharacterControllerObject characterControllerObject, const Vec3& move, float time)
{
    if (!characterControllerObject)
        return;

    auto characterController = reinterpret_cast<CharacterController*>(characterControllerObject);

    characterController->bulletController->setVelocityForTimeInterval(toBullet(move / time), time);
}
Beispiel #13
0
void Actor::updateRotation ()
{
    btTransform tr = mCollisionObject->getWorldTransform();
    mRotation = mPtr.getRefData().getBaseNode()->getAttitude();
    tr.setRotation(toBullet(mRotation));
    mCollisionObject->setWorldTransform(tr);

    updateCollisionObjectPosition();
}
bool Context::allHitsRayResult( const ci::vec3 &startPosition, const ci::vec3 &direction, RayResult &result )
{
	btVector3 rayTo = toBullet( direction * 1000.0f );
	btVector3 rayFrom = toBullet( startPosition );
	
	btCollisionWorld::AllHitsRayResultCallback allHitsCallback( rayFrom, rayTo );
	
	world()->rayTest( rayFrom, rayTo, allHitsCallback );
	
	if( allHitsCallback.hasHit() ) {
		auto bodies = std::move( allHitsCallback.m_collisionObjects );
		
		if( bodies.size() <= 0 )
			return false;
		
		 
	}
	
	return false;
}
Beispiel #15
0
bool Bullet::setCharacterControllerPosition(CharacterControllerObject characterControllerObject, const Vec3& position)
{
    if (!characterControllerObject)
        return false;

    auto characterController = reinterpret_cast<CharacterController*>(characterControllerObject);

    characterController->bulletController->setWorldPosition(toBullet(position));

    return true;
}
Beispiel #16
0
bool Bullet::setBodyAngularVelocity(BodyObject bodyObject, const Vec3& velocity) const
{
    if (!bodyObject)
        return false;

    auto body = reinterpret_cast<Body*>(bodyObject);

    body->bulletBody->setAngularVelocity(toBullet(velocity));
    body->bulletBody->activate(true);

    return true;
}
Beispiel #17
0
void ActorTracer::doTrace(const btCollisionObject *actor, const osg::Vec3f& start, const osg::Vec3f& end, const btCollisionWorld* world)
{
    const btVector3 btstart = toBullet(start);
    const btVector3 btend = toBullet(end);

    const btTransform &trans = actor->getWorldTransform();
    btTransform from(trans);
    btTransform to(trans);
    from.setOrigin(btstart);
    to.setOrigin(btend);

    ClosestNotMeConvexResultCallback newTraceCallback(actor, btstart-btend, btScalar(0.0));
    // Inherit the actor's collision group and mask
    newTraceCallback.m_collisionFilterGroup = actor->getBroadphaseHandle()->m_collisionFilterGroup;
    newTraceCallback.m_collisionFilterMask = actor->getBroadphaseHandle()->m_collisionFilterMask;

    const btCollisionShape *shape = actor->getCollisionShape();
    assert(shape->isConvex());
    world->convexSweepTest(static_cast<const btConvexShape*>(shape),
                                               from, to, newTraceCallback);

    // Copy the hit data over to our trace results struct:
    if(newTraceCallback.hasHit())
    {
        const btVector3& tracehitnormal = newTraceCallback.m_hitNormalWorld;
        mFraction = newTraceCallback.m_closestHitFraction;
        mPlaneNormal = osg::Vec3f(tracehitnormal.x(), tracehitnormal.y(), tracehitnormal.z());
        mEndPos = (end-start)*mFraction + start;
        mHitPoint = toOsg(newTraceCallback.m_hitPointWorld);
        mHitObject = newTraceCallback.m_hitCollisionObject;
    }
    else
    {
        mEndPos = end;
        mPlaneNormal = osg::Vec3f(0.0f, 0.0f, 1.0f);
        mFraction = 1.0f;
        mHitPoint = end;
        mHitObject = nullptr;
    }
}
Beispiel #18
0
PhysicsInterface::BodyTemplateObject Bullet::createBodyTemplateFromGeometry(const Vector<Vec3>& vertices,
                                                                            const Vector<RawIndexedTriangle>& triangles,
                                                                            bool deleteOnceUnused,
                                                                            float customCollisionMargin)
{
    if (vertices.empty() || triangles.empty())
        return nullptr;

    auto bodyTemplate = new BodyTemplate(deleteOnceUnused);
    bodyTemplates_.append(bodyTemplate);

    // Copy the geometry data
    bodyTemplate->vertices = vertices;
    bodyTemplate->triangles = triangles;

    // Create interface to the geometry data for Bullet to use
    auto mesh = btIndexedMesh();
    mesh.m_numTriangles = bodyTemplate->triangles.size();
    mesh.m_triangleIndexBase = reinterpret_cast<byte_t*>(bodyTemplate->triangles.getData());
    mesh.m_triangleIndexStride = 3 * sizeof(unsigned int);
    mesh.m_numVertices = bodyTemplate->vertices.size();
    mesh.m_vertexBase = bodyTemplate->vertices.as<byte_t>();
    mesh.m_vertexStride = 3 * sizeof(float);

    auto meshInterface = new btTriangleIndexVertexArray();
    meshInterface->addIndexedMesh(mesh);

    // Calculate an AABB around the geometry
    auto aabb = AABB(bodyTemplate->vertices);

    // Create the collision shape
    bodyTemplate->collisionShape =
        new btBvhTriangleMeshShape(meshInterface, true, toBullet(aabb.getMinimum()), toBullet(aabb.getMaximum()));

    if (customCollisionMargin > 0.0f)
        bodyTemplate->collisionShape->setMargin(customCollisionMargin);

    return bodyTemplate;
}
Beispiel #19
0
PhysicsInterface::JointObject Bullet::createBallAndSocketJoint(BodyObject firstBodyObject, BodyObject secondBodyObject,
                                                               const Vec3& globalAnchor, const Vec3& angularLimits)
{
    if (!firstBodyObject || !secondBodyObject || firstBodyObject == secondBodyObject)
    {
        LOG_ERROR << "Invalid bodies";
        return nullptr;
    }

    auto firstBody = reinterpret_cast<Body*>(firstBodyObject);
    auto secondBody = reinterpret_cast<Body*>(secondBodyObject);

    auto firstBodyTransform = btTransform();
    auto secondBodyTransform = btTransform();
    firstBody->bulletBody->getMotionState()->getWorldTransform(firstBodyTransform);
    secondBody->bulletBody->getMotionState()->getWorldTransform(secondBodyTransform);

    auto firstLocalAnchor =
        btTransform(btQuaternion::getIdentity(), firstBodyTransform.inverse() * toBullet(globalAnchor));
    auto secondLocalAnchor =
        btTransform(btQuaternion::getIdentity(), secondBodyTransform.inverse() * toBullet(globalAnchor));

    auto btConstraint = new btGeneric6DofConstraint(*firstBody->bulletBody, *secondBody->bulletBody, firstLocalAnchor,
                                                    secondLocalAnchor, true);

    if (angularLimits != Vec3::Zero)
    {
        btConstraint->setAngularLowerLimit(toBullet(-angularLimits));
        btConstraint->setAngularUpperLimit(toBullet(angularLimits));
    }

    joints_.append(new Joint(firstBody, secondBody, btConstraint));

    dynamicsWorld_->addConstraint(joints_.back()->bulletConstraint, true);

    return joints_.back();
}
void PhyObjTriggerVol::initObject( btCollisionShape *collShape, const ci::vec3 &position )
{
	mTrigger = new btCollisionObject();
	
	mTrigger->setCollisionShape( collShape );
	
	btTransform triggerTrans;
	triggerTrans.setIdentity();
	triggerTrans.setOrigin( toBullet( position ) );
	mTrigger->setWorldTransform( triggerTrans );
	
	mTrigger->setCollisionFlags( btCollisionObject::CF_NO_CONTACT_RESPONSE );
	
	Context()->world()->addCollisionObject( mTrigger );
}
Beispiel #21
0
void Actor::updateScale()
{
    float scale = mPtr.getCellRef().getScale();
    osg::Vec3f scaleVec(scale,scale,scale);

    mPtr.getClass().adjustScale(mPtr, scaleVec, false);
    mScale = scaleVec;
    mShape->setLocalScaling(toBullet(mScale));

    scaleVec = osg::Vec3f(scale,scale,scale);
    mPtr.getClass().adjustScale(mPtr, scaleVec, true);
    mRenderingScale = scaleVec;

    updateCollisionObjectPosition();
}
Beispiel #22
0
PhysicsInterface::BodyObject Bullet::createBoundingBoxBody(const AABB& aabb, float mass, bool fixed,
                                                           const Entity* entity,
                                                           const SimpleTransform& initialTransform)
{
    auto collisionShape = new btBoxShape(toBullet((aabb.getMaximum() - aabb.getMinimum()) * 0.5f));

    // Calculate inertia
    auto localInertia = btVector3(0.0f, 0.0f, 0.0f);
    if (!fixed)
        collisionShape->calculateLocalInertia(mass, localInertia);

    // Motion state for this body
    auto motionState = new btDefaultMotionState(toBullet(initialTransform),
                                                btTransform(btQuaternion::getIdentity(), toBullet(aabb.getCenter())));

    // Create Bullet rigid body
    auto bulletBody = new btRigidBody(
        btRigidBody::btRigidBodyConstructionInfo(fixed ? 0.0f : mass, motionState, collisionShape, localInertia));

    bulletBody->setDamping(DefaultLinearDamping, DefaultAngularDamping);
    bulletBody->setSleepingThresholds(DefaultLinearSleepingThreshold, DefaultAngularSleepingThreshold);
    bulletBody->setRestitution(0.0f);

    // Add body to the simulation
    dynamicsWorld_->addRigidBody(bulletBody);

    // Create local body
    auto body = new Body(bulletBody, entity, fixed);
    bodies_.append(body);

    body->ownedCollisionShape = collisionShape;

    bulletBody->setUserPointer(body);

    return body;
}
Beispiel #23
0
bool Bullet::setup()
{
    broadphase_ = new btDbvtBroadphase;

    ghostPairCallback_ = new btGhostPairCallback;
    broadphase_->getOverlappingPairCache()->setInternalGhostPairCallback(ghostPairCallback_);

    collisionConfiguration_ = new btDefaultCollisionConfiguration;
    dispatcher_ = new btCollisionDispatcher(collisionConfiguration_);

    solver_ = new btSequentialImpulseConstraintSolver;

    dynamicsWorld_ = new btDiscreteDynamicsWorld(dispatcher_, broadphase_, solver_, collisionConfiguration_);
    dynamicsWorld_->setGravity(toBullet(getGravityVector()));

    LOG_INFO << "Initialized Bullet " << (btGetVersion() / 100) << "." << (btGetVersion() % 100);

    return true;
}
Beispiel #24
0
PhysicsInterface::BodyObject Bullet::createGeometryBodyFromTemplate(BodyTemplateObject bodyTemplateObject, float mass,
                                                                    bool fixed, const Entity* entity,
                                                                    const SimpleTransform& initialTransform)
{
    auto bodyTemplate = reinterpret_cast<BodyTemplate*>(bodyTemplateObject);

    if (!bodyTemplateObject || !bodyTemplate->collisionShape)
    {
        LOG_ERROR << "Invalid body template";
        return nullptr;
    }

    // Calculate inertia
    auto localInertia = btVector3(0.0f, 0.0f, 0.0f);
    if (!fixed)
        bodyTemplate->collisionShape->calculateLocalInertia(mass, localInertia);

    // Motion state for this body
    auto motionState = new btDefaultMotionState(toBullet(initialTransform),
                                                btTransform(btQuaternion::getIdentity(), toBullet(Vec3::Zero)));

    // Create Bullet rigid body
    auto bulletBody = new btRigidBody(
        btRigidBody::btRigidBodyConstructionInfo((fixed ? 0.0f : mass), motionState, bodyTemplate->collisionShape,
                                                 (fixed ? btVector3(0.0f, 0.0f, 0.0f) : localInertia)));

    bulletBody->setDamping(DefaultLinearDamping, DefaultAngularDamping);
    bulletBody->setSleepingThresholds(DefaultLinearSleepingThreshold, DefaultAngularSleepingThreshold);
    bulletBody->setRestitution(0.0f);

    // Add body to the simulation
    dynamicsWorld_->addRigidBody(bulletBody);

    // Create local body
    auto body = new Body(bulletBody, entity, fixed);
    bodies_.append(body);

    bulletBody->setUserPointer(body);

    return body;
}
Beispiel #25
0
bool Bullet::setBodyTransform(BodyObject bodyObject, const SimpleTransform& transform)
{
    if (!bodyObject)
        return false;

    auto body = reinterpret_cast<Body*>(bodyObject);

    if (body->isFixed)
    {
        LOG_ERROR << "Can't alter the physics transform of a fixed body";
        return false;
    }

    // Set new transform on the body
    body->bulletBody->getWorldTransform() = toBullet(transform);

    // Put this body back in the active list since it's been manually reconfigured
    body->bulletBody->activate(true);

    return true;
}
Beispiel #26
0
void ActorTracer::findGround(const Actor* actor, const osg::Vec3f& start, const osg::Vec3f& end, btCollisionWorld* world)
{
    const btVector3 btstart(start.x(), start.y(), start.z()+1.0f);
    const btVector3 btend(end.x(), end.y(), end.z()+1.0f);

    const btTransform &trans = actor->getCollisionObject()->getWorldTransform();
    btTransform from(trans.getBasis(), btstart);
    btTransform to(trans.getBasis(), btend);

    ClosestNotMeConvexResultCallback newTraceCallback(actor->getCollisionObject(), btstart-btend, btScalar(0.0));
    // Inherit the actor's collision group and mask
    newTraceCallback.m_collisionFilterGroup = actor->getCollisionObject()->getBroadphaseHandle()->m_collisionFilterGroup;
    newTraceCallback.m_collisionFilterMask = actor->getCollisionObject()->getBroadphaseHandle()->m_collisionFilterMask;
    newTraceCallback.m_collisionFilterMask &= ~CollisionType_Actor;

    btVector3 halfExtents = toBullet(actor->getHalfExtents());

    halfExtents[2] = 1.0f;
    btCylinderShapeZ base(halfExtents);

    world->convexSweepTest(&base, from, to, newTraceCallback);
    if(newTraceCallback.hasHit())
    {
        const btVector3& tracehitnormal = newTraceCallback.m_hitNormalWorld;
        mFraction = newTraceCallback.m_closestHitFraction;
        mPlaneNormal = osg::Vec3f(tracehitnormal.x(), tracehitnormal.y(), tracehitnormal.z());
        mEndPos = (end-start)*mFraction + start;
        mEndPos[2] += 1.0f;
    }
    else
    {
        mEndPos = end;
        mPlaneNormal = osg::Vec3f(0.0f, 0.0f, 1.0f);
        mFraction = 1.0f;
    }
}
Beispiel #27
0
void PhysicsEngine::RegisterObject(ModelNode *pItem){

  /*********************************************************************
   *ADDING SHAPES
   **********************************************************************/
  if (dynamic_cast<Shape*>(pItem) != NULL) {
    Shape* pNodeShape = (Shape*) pItem;

    /************************************
     *ADDING A RAYCAST VEHICLE
     ************************************/

    if(dynamic_cast<SimRaycastVehicle*>(pNodeShape)!=NULL){
      bullet_vehicle btRayVehicle( pItem, dynamics_world_.get(),
                                   vehicle_raycaster_);
      CollisionShapePtr pShape( btRayVehicle.getBulletShapePtr() );
      MotionStatePtr pMotionState( btRayVehicle.getBulletMotionStatePtr() );
      RigidBodyPtr body( btRayVehicle.getBulletBodyPtr() );
      VehiclePtr vehicle( btRayVehicle.getBulletRaycastVehicle() );
      std::shared_ptr<Vehicle_Entity> pEntity( new Vehicle_Entity );
      pEntity->m_pRigidBody = body;
      pEntity->m_pShape = pShape;
      pEntity->m_pMotionState = pMotionState;
      pEntity->m_pVehicle = vehicle;
      ray_vehicles_map_[pItem->GetName()] = pEntity;
    }

    //Box
    if (dynamic_cast<BoxShape*>( pNodeShape ) != NULL) {
      bullet_cube btBox(pItem);
      CollisionShapePtr pShape( btBox.getBulletShapePtr() );
      MotionStatePtr pMotionState( btBox.getBulletMotionStatePtr() );
      RigidBodyPtr body( btBox.getBulletBodyPtr() );
      dynamics_world_->addRigidBody( body.get() );

      //Save the object; easier deconstruction this way.
      std::shared_ptr<Entity> pEntity( new Entity );
      pEntity->m_pRigidBody = body;
      pEntity->m_pShape = pShape;
      pEntity->m_pMotionState = pMotionState;
      shapes_map_[pItem->GetName()] = pEntity;
    }

    //Cylinder
    else if (dynamic_cast<CylinderShape*>( pNodeShape ) != NULL) {
      bullet_cylinder btCylinder(pItem);
      CollisionShapePtr pShape( btCylinder.getBulletShapePtr() );
      MotionStatePtr pMotionState( btCylinder.getBulletMotionStatePtr() );
      RigidBodyPtr body( btCylinder.getBulletBodyPtr() );
      dynamics_world_->addRigidBody( body.get() );

      //Save the object; easier deconstruction this way.
      std::shared_ptr<Entity> pEntity( new Entity );
      pEntity->m_pRigidBody = body;
      pEntity->m_pShape = pShape;
      pEntity->m_pMotionState = pMotionState;
      shapes_map_[pItem->GetName()] = pEntity;
    }

    //Plane
    else if (dynamic_cast<PlaneShape*>( pNodeShape ) != NULL) {
      bullet_plane btPlane(pItem);
      CollisionShapePtr pShape( btPlane.getBulletShapePtr() );
      MotionStatePtr pMotionState( btPlane.getBulletMotionStatePtr() );
      RigidBodyPtr body( btPlane.getBulletBodyPtr() );
      dynamics_world_->addRigidBody( body.get() );

      //Save the object; easier deconstruction this way.
      std::shared_ptr<Entity> pEntity( new Entity );
      pEntity->m_pRigidBody = body;
      pEntity->m_pShape = pShape;
      pEntity->m_pMotionState = pMotionState;
      shapes_map_[pItem->GetName()] = pEntity;
    }

    //Heightmap
    else if (dynamic_cast<HeightmapShape*>( pNodeShape ) != NULL) {
      bullet_heightmap btMap(pItem);
      CollisionShapePtr pShape( btMap.getBulletShapePtr() );
      MotionStatePtr pMotionState( btMap.getBulletMotionStatePtr() );
      RigidBodyPtr body( btMap.getBulletBodyPtr() );
      dynamics_world_->addRigidBody( body.get() );

      //Save the object; easier deconstruction this way.
      std::shared_ptr<Entity> pEntity( new Entity );
      pEntity->m_pRigidBody = body;
      pEntity->m_pShape = pShape;
      pEntity->m_pMotionState = pMotionState;
      shapes_map_[pItem->GetName()] = pEntity;
    }

    //Mesh
    else if (dynamic_cast<MeshShape*>( pNodeShape ) != NULL){
      bullet_mesh btMesh(pItem);
      CollisionShapePtr pShape( btMesh.getBulletShapePtr() );
      MotionStatePtr pMotionState( btMesh.getBulletMotionStatePtr() );
      RigidBodyPtr body( btMesh.getBulletBodyPtr() );
      dynamics_world_->addRigidBody( body.get() );

      //Save the object; easier deconstruction this way.
      std::shared_ptr<Entity> pEntity( new Entity );
      pEntity->m_pRigidBody = body;
      pEntity->m_pShape = pShape;
      pEntity->m_pMotionState = pMotionState;
      shapes_map_[pItem->GetName()] = pEntity;
    }
  }



  /*********************************************************************
   *ADDING CONSTRAINTS
   **********************************************************************/

  else if (dynamic_cast<Constraint*>(pItem) != NULL) {
    Constraint* pNodeCon = (Constraint*) pItem;
    // Point to Point
    if (dynamic_cast<PToPOne*>( pNodeCon ) != NULL) {
      PToPOne* pCon = (PToPOne*) pNodeCon;
      btRigidBody* RigidShape_A;
      if(isVehicle(pCon->m_Shape_A)){
        std::shared_ptr<Vehicle_Entity> Shape_A = ray_vehicles_map_.at(pCon->m_Shape_A);
        RigidShape_A = Shape_A->m_pRigidBody.get();
      }
      else{
        std::shared_ptr<Entity> Shape_A = shapes_map_.at(pCon->m_Shape_A);
        RigidShape_A = Shape_A->m_pRigidBody.get();
      }
      btVector3 pivot_A(pCon->m_pivot_in_A[0], pCon->m_pivot_in_A[1],
                        pCon->m_pivot_in_A[2]);
      btPoint2PointConstraint* PToP =
          new btPoint2PointConstraint(*RigidShape_A, pivot_A);
      dynamics_world_->addConstraint(PToP);
      ptop_map_[pCon->GetName()] = PToP;
    }

    else if(dynamic_cast<PToPTwo*>( pNodeCon ) != NULL) {
      PToPTwo* pCon = (PToPTwo*) pNodeCon;
      btRigidBody* RigidShape_A;
      btRigidBody* RigidShape_B;
      if(isVehicle(pCon->m_Shape_A)){
        std::shared_ptr<Vehicle_Entity> Shape_A = ray_vehicles_map_.at(pCon->m_Shape_A);
        RigidShape_A = Shape_A->m_pRigidBody.get();
      }
      else{
        std::shared_ptr<Entity> Shape_A = shapes_map_.at(pCon->m_Shape_A);
        RigidShape_A = Shape_A->m_pRigidBody.get();
      }
      if(isVehicle(pCon->m_Shape_B)){
        std::shared_ptr<Vehicle_Entity> Shape_B = ray_vehicles_map_.at(pCon->m_Shape_B);
        RigidShape_B = Shape_B->m_pRigidBody.get();
      }
      else{
        std::shared_ptr<Entity> Shape_B = shapes_map_.at(pCon->m_Shape_B);
        RigidShape_B = Shape_B->m_pRigidBody.get();
      }
      btVector3 pivot_A(pCon->m_pivot_in_A[0], pCon->m_pivot_in_A[1],
                        pCon->m_pivot_in_A[2]);
      btVector3 pivot_B(pCon->m_pivot_in_B[0], pCon->m_pivot_in_B[1],
                        pCon->m_pivot_in_B[2]);
      btPoint2PointConstraint* PToP =
          new btPoint2PointConstraint(*RigidShape_A, *RigidShape_B,
                                      pivot_A, pivot_B);
      dynamics_world_->addConstraint(PToP);
      ptop_map_[pCon->GetName()] = PToP;
    }

    //Hinge
    else if(dynamic_cast<HingeOnePivot*>( pNodeCon ) != NULL) {
      HingeOnePivot* pCon = (HingeOnePivot*) pNodeCon;
      btRigidBody* RigidShape_A;
      if(isVehicle(pCon->m_Shape_A)){
        std::shared_ptr<Vehicle_Entity> Shape_A = ray_vehicles_map_.at(pCon->m_Shape_A);
        RigidShape_A = Shape_A->m_pRigidBody.get();
      }
      else{
        std::shared_ptr<Entity> Shape_A = shapes_map_.at(pCon->m_Shape_A);
        RigidShape_A = Shape_A->m_pRigidBody.get();
      }
      btVector3 pivot_A(pCon->m_pivot_in_A[0], pCon->m_pivot_in_A[1],
                        pCon->m_pivot_in_A[2]);
      btVector3 axis_A(pCon->m_axis_in_A[0], pCon->m_axis_in_A[1],
                       pCon->m_axis_in_A[2]);
      btHingeConstraint* Hinge =
          new btHingeConstraint(*RigidShape_A, pivot_A,
                                axis_A, true);
      Hinge->setLimit(pCon->m_low_limit, pCon->m_high_limit, pCon->m_softness,
                      pCon->m_bias, pCon->m_relaxation);
      dynamics_world_->addConstraint(Hinge);
      hinge_map_[pCon->GetName()] = Hinge;
    }

    else if(dynamic_cast<HingeTwoPivot*>( pNodeCon ) != NULL) {
      HingeTwoPivot* pCon = (HingeTwoPivot*) pNodeCon;
      btRigidBody* RigidShape_A;
      btRigidBody* RigidShape_B;
      if(isVehicle(pCon->m_Shape_A)){
        std::shared_ptr<Vehicle_Entity> Shape_A = ray_vehicles_map_.at(pCon->m_Shape_A);
        RigidShape_A = Shape_A->m_pRigidBody.get();
      }
      else{
        std::shared_ptr<Entity> Shape_A = shapes_map_.at(pCon->m_Shape_A);
        RigidShape_A = Shape_A->m_pRigidBody.get();
      }
      if(isVehicle(pCon->m_Shape_B)){
        std::shared_ptr<Vehicle_Entity> Shape_B = ray_vehicles_map_.at(pCon->m_Shape_B);
        RigidShape_B = Shape_B->m_pRigidBody.get();
      }
      else{
        std::shared_ptr<Entity> Shape_B = shapes_map_.at(pCon->m_Shape_B);
        RigidShape_B = Shape_B->m_pRigidBody.get();
      }
      btVector3 pivot_A(pCon->m_pivot_in_A[0], pCon->m_pivot_in_A[1],
                        pCon->m_pivot_in_A[2]);
      btVector3 axis_A(pCon->m_axis_in_A[0], pCon->m_axis_in_A[1],
                       pCon->m_axis_in_A[2]);
      btVector3 pivot_B(pCon->m_pivot_in_B[0], pCon->m_pivot_in_B[1],
                        pCon->m_pivot_in_B[2]);
      btVector3 axis_B(pCon->m_axis_in_B[0], pCon->m_axis_in_B[1],
                       pCon->m_axis_in_B[2]);
      btHingeConstraint* Hinge =
          new btHingeConstraint(*RigidShape_A,
                                *RigidShape_B,
                                pivot_A, pivot_B,
                                axis_A, axis_B,
                                true);
      Hinge->setLimit(pCon->m_low_limit, pCon->m_high_limit, pCon->m_softness,
                      pCon->m_bias, pCon->m_relaxation);
      dynamics_world_->addConstraint(Hinge);
      hinge_map_[pCon->GetName()] = Hinge;
    }

    //Hinge2
    else if(dynamic_cast<Hinge2*>( pNodeCon ) != NULL) {
      Hinge2* pCon = (Hinge2*) pNodeCon;
      btRigidBody* RigidShape_A;
      btRigidBody* RigidShape_B;
      if(isVehicle(pCon->m_Shape_A)){
        std::shared_ptr<Vehicle_Entity> Shape_A = ray_vehicles_map_.at(pCon->m_Shape_A);
        RigidShape_A = Shape_A->m_pRigidBody.get();
      }
      else{
        std::shared_ptr<Entity> Shape_A = shapes_map_.at(pCon->m_Shape_A);
        RigidShape_A = Shape_A->m_pRigidBody.get();
      }
      if(isVehicle(pCon->m_Shape_B)){
        std::shared_ptr<Vehicle_Entity> Shape_B = ray_vehicles_map_.at(pCon->m_Shape_B);
        RigidShape_B = Shape_B->m_pRigidBody.get();
      }
      else{
        std::shared_ptr<Entity> Shape_B = shapes_map_.at(pCon->m_Shape_B);
        RigidShape_B = Shape_B->m_pRigidBody.get();
      }
      btVector3 btAnchor(pCon->m_Anchor[0], pCon->m_Anchor[1],
                         pCon->m_Anchor[2]);
      btVector3 btAxis_1(pCon->m_Axis_1[0], pCon->m_Axis_1[1],
                         pCon->m_Axis_1[2]);
      btVector3 btAxis_2(pCon->m_Axis_2[0], pCon->m_Axis_2[1],
                         pCon->m_Axis_2[2]);
      btHinge2Constraint* Hinge =
          new btHinge2Constraint(*RigidShape_A, *RigidShape_B,
                                 btAnchor, btAxis_1, btAxis_2);
      Hinge->setAngularLowerLimit(toBulletVec3(pCon->m_LowerAngLimit));
      Hinge->setAngularUpperLimit(toBulletVec3(pCon->m_UpperAngLimit));
      Hinge->setLinearLowerLimit(toBulletVec3(pCon->m_LowerLinLimit));
      Hinge->setLinearUpperLimit(toBulletVec3(pCon->m_UpperLinLimit));
      Hinge->enableSpring(3, true);
      Hinge->setStiffness(3, pCon->m_stiffness);
      Hinge->setDamping(3, pCon->m_damping);
      dynamics_world_->addConstraint(Hinge);
      hinge2_map_[pCon->GetName()] = Hinge;
    }

    //SixDOF
    else if(dynamic_cast<SixDOFOne*>( pNodeCon ) != NULL) {
      SixDOFOne* pCon = (SixDOFOne*) pNodeCon;
      std::shared_ptr<Entity> Shape_A = shapes_map_.at(pCon->m_Shape_A);
      btTransform trans_A = toBullet(_Cart2T(pCon->m_Transform_A));
      btGeneric6DofConstraint* SixDOF =
          new btGeneric6DofConstraint(*Shape_A->m_pRigidBody.get(),
                                      trans_A,
                                      true);
      SixDOF->setLinearLowerLimit(toBulletVec3(pCon->m_LowerLinLimit));
      SixDOF->setLinearUpperLimit(toBulletVec3(pCon->m_UpperLinLimit));
      SixDOF->setAngularLowerLimit(toBulletVec3(pCon->m_LowerAngLimit));
      SixDOF->setAngularUpperLimit(toBulletVec3(pCon->m_UpperAngLimit));
      dynamics_world_->addConstraint(SixDOF);
      sixdof_map_[pCon->GetName()] = SixDOF;
    }

    else if(dynamic_cast<SixDOFTwo*>( pNodeCon ) != NULL) {
      SixDOFTwo* pCon = (SixDOFTwo*) pNodeCon;
      btRigidBody* RigidShape_A;
      btRigidBody* RigidShape_B;
      if(isVehicle(pCon->m_Shape_A)){
        std::shared_ptr<Vehicle_Entity> Shape_A = ray_vehicles_map_.at(pCon->m_Shape_A);
        RigidShape_A = Shape_A->m_pRigidBody.get();
      }
      else{
        std::shared_ptr<Entity> Shape_A = shapes_map_.at(pCon->m_Shape_A);
        RigidShape_A = Shape_A->m_pRigidBody.get();
      }
      if(isVehicle(pCon->m_Shape_B)){
        std::shared_ptr<Vehicle_Entity> Shape_B = ray_vehicles_map_.at(pCon->m_Shape_B);
        RigidShape_B = Shape_B->m_pRigidBody.get();
      }
      else{
        std::shared_ptr<Entity> Shape_B = shapes_map_.at(pCon->m_Shape_B);
        RigidShape_B = Shape_B->m_pRigidBody.get();
      }
      btTransform trans_A = toBullet(_Cart2T(pCon->m_Transform_A));
      btTransform trans_B = toBullet(_Cart2T(pCon->m_Transform_B));
      btGeneric6DofConstraint* SixDOF =
          new btGeneric6DofConstraint(*RigidShape_A, *RigidShape_B,
                                      trans_A, trans_B,
                                      true);
      SixDOF->setLinearLowerLimit(toBulletVec3(pCon->m_LowerLinLimit));
      SixDOF->setLinearUpperLimit(toBulletVec3(pCon->m_UpperLinLimit));
      SixDOF->setAngularLowerLimit(toBulletVec3(pCon->m_LowerAngLimit));
      SixDOF->setAngularUpperLimit(toBulletVec3(pCon->m_UpperAngLimit));
      dynamics_world_->addConstraint(SixDOF);
      sixdof_map_[pCon->GetName()] = SixDOF;
    }
  }

  return;

}
Beispiel #28
0
void rePlayer::messageProcess( reMessageDispatcher* sender, reMessage* message )
{
	reVec3 deltaAngle(0,0,0);
	float rs = .5f;
	switch (message->id)
	{
	case reM_TIMER:
		if (model())
		{
			reVec3 dirZ = reVec3(model()->worldTransform().matrix * reVec4(0,0,-1, 0));
			reVec3 dirX = reVec3(model()->worldTransform().matrix * reVec4(1,0,0, 0));

			if (reRadial::shared()->input()->keyStates['W'])
			{			
				body->btBody->applyCentralForce(toBullet(dirZ * 50.0f));
			}
			if (reRadial::shared()->input()->keyStates['S'])
			{
				body->btBody->applyCentralForce(toBullet(dirZ * -50.0f));
			}
			if (reRadial::shared()->input()->keyStates[' '])
			{			
				body->btBody->applyCentralForce(toBullet(dirX * 1.0f));
				//reVec4 f = worldTransform().matrix * reVec4(0,-200,0,0);
				//btVector3 bf(f.x, f.y, f.z);
				//body->btBody->applyCentralForce(bf);
			}
			if (reRadial::shared()->input()->keyStates['A'])
			{
				reVec3 v = reVec3(glm::rotate(reMat4(), rs, reVec3(0,1,0)) * reVec4(fromBullet(body->btBody->getLinearVelocity()), 0));
				body->btBody->setLinearVelocity(toBullet(v));								
				model()->transform(glm::rotate(reMat4(), rs, reVec3(0,1,0)) * model()->transform().matrix);
				//body->btBody->applyCentralForce(toBullet(f));
			}
			if (reRadial::shared()->input()->keyStates['D'])
			{
				reVec3 v = reVec3(glm::rotate(reMat4(), -rs, reVec3(0,1,0)) * reVec4(fromBullet(body->btBody->getLinearVelocity()), 0));
				body->btBody->setLinearVelocity(toBullet(v));
				model()->transform(glm::rotate(reMat4(), -rs, reVec3(0,1,0)) * model()->transform().matrix);
				//deltaAngle += reVec3(0,-1,0);
				//model()->transform(glm::rotate(reMat4(), -1.0f, reVec3(0,1,0)) * model()->transform().matrix);
			}
			reVec3 pos = worldTransform().position();
			camera->lookAt(pos);
			light->lookAt(pos);
			if (pos.y < calculateVertex(reVec4(pos,1)).y)
			{
				//__debugbreak();
			}
			break;
		}
	}
	
	if (glm::length(fromBullet(body->btBody->getLinearVelocity())))
	{				
		reVec3 dir = glm::normalize(fromBullet(body->btBody->getLinearVelocity()));
		if (!dir.z)
		{
			return;
		}
		float yaw = dir.z < 0 ? glm::atan(dir.x / dir.z) : M_PI - glm::atan(dir.x / -dir.z);
		float pitch = glm::atan(dir.y / abs(dir.z));
		reMat4 y(glm::rotate(reMat4(), glm::degrees(yaw), reVec3(0,1,0)));
		reMat4 p(glm::rotate(reMat4(), glm::degrees(pitch), reVec3(1,0,0)));		
		model()->children->at(0)->transform(p);
		reVec3 da = reVec3(0, glm::degrees(yaw), 0) - camera->lookAngles();
		camera->lookAngles(camera->lookAngles() + da / 5.0f );
	}
}
Beispiel #29
0
void Bullet::setGravityVector(const Vec3& gravity)
{
    gravityVector_ = gravity;

    dynamicsWorld_->setGravity(toBullet(gravityVector_));
}
Beispiel #30
0
void compileProject(Path rootPath, irr::scene::ISceneManager* smgr) {

    pRoot = rootPath;

    FMain fMain;
    std::vector<FObject> fObjects;
    std::vector<FResource> fResources;

    // Main file
    {
        std::cout << "Loading main file..." << std::endl;
        Json::Value jrMain;
        // Read
        {
            std::ifstream rMain(pRoot + "/" + pMain);
            if(!rMain.is_open()) {
                std::cout << "Aborted! Could not read main file!" << std::endl;
                return;
            }
            rMain >> jrMain;
        }

        fMain.name = toString(jrMain["name"], "Unnamed Content Pack");
        fMain.namesp = toString(jrMain["namespace"], "anon");
        fMain.desc = toString(jrMain["description"], "No description available.");

        // Load authors
        {
            const Json::Value& jrMainObjects = jrMain["authors"];
            if(jrMainObjects.isArray()) {
                for(Json::Value::iterator it = jrMainObjects.begin(); it != jrMainObjects.end(); ++ it) {
                    fMain.authors.push_back(toString(*it));
                }
            }
            else {
                fMain.authors.push_back(toString(jrMainObjects, "Anonymous"));
            }
        }

        // Load object reference list
        {
            const Json::Value& jrMainObjects = jrMain["objects"];
            if(jrMainObjects.isArray()) {
                for(Json::Value::iterator it = jrMainObjects.begin(); it != jrMainObjects.end(); ++ it) {
                    Path objPath = toString(*it);
                    fMain.refObjects.push_back(Referen(objPath));
                }
            }
            else if(jrMainObjects.isString()) {
                Path objPath = jrMainObjects.asString();
                fMain.refObjects.push_back(Referen(objPath));
            }
            else {
                std::cout << "Aborted! Cannot parse objects list!" << std::endl;
                return;
            }
        }
    }

    // Object files
    {
        std::cout << "Loading object files...";
        for(std::vector<Referen>::iterator it = fMain.refObjects.begin(); it != fMain.refObjects.end(); ++ it) {

            const Referen& refObject = *it;
            Path refContext = getDirectory(refObject.absPath);

            FObject fObject;

            Json::Value jrObject;
            {
                std::ifstream rObject(pRoot + "/" + refObject.absPath);
                if(!rObject.is_open()) {
                    std::cout << "Aborted! Could not read " + refObject.absPath + "!" << std::endl;
                    return;
                }
                rObject >> jrObject;
            }

            fObject.id = toString(jrObject["id"]);

            Path pModel = toString(jrObject["model"]);
            fObject.refModel = Referen(pModel, refContext);
            FResource fModel;
            fModel.refSelf = fObject.refModel;
            fModel.type = MODEL;
            fResources.push_back(fModel);


            Path pPhysics = toString(jrObject["physics"]);
            fObject.refPhysics = Referen(pPhysics, refContext);
            FResource fPhys;
            fPhys.refSelf = fObject.refPhysics;
            fPhys.type = PHYSICS;
            fResources.push_back(fPhys);

            fObject.physOffset = toBullet(jrObject["physics-offset"]);

            fObject.refSelf = refObject;
            fObjects.push_back(fObject);
        }
    }

    std::cout << "Compiling entire project..." << std::endl;

    // Main file
    {
        std::cout << "Compiling main file..." << std::endl;

        // Construct new json file
        Json::Value jwMain;

        // Simple strings
        jwMain["name"] = fMain.name;
        jwMain["namespace"] = fMain.namesp;
        jwMain["description"] = fMain.desc;

        // Authors
        {
            Json::Value& jwMainAuthors = jwMain["authors"];
            for(std::vector<std::string>::iterator it = fMain.authors.begin(); it != fMain.authors.end(); ++ it) {
                jwMainAuthors.append(*it);
            }
        }

        // Objects
        {
            Json::Value& jwMainAuthors = jwMain["objects"];
            for(std::vector<Referen>::iterator it = fMain.refObjects.begin(); it != fMain.refObjects.end(); ++ it) {
                const Referen& referen = *it;
                jwMainAuthors.append(referen.qualifiedName);
            }
        }

        // Also clean the folder
        {
            std::string winCmd;
            winCmd = "del /q \"" + pOutputRoot + "\\" + fMain.name + "\\*.*\"";
            std::system(winCmd.c_str());
            winCmd = "mkdir \"" + pOutputRoot + "/" + fMain.name + "\"";
            std::system(winCmd.c_str());
        }

        std::ofstream wMain(pOutputRoot + "/" + fMain.name + "/content-pack.json");
        if(!wMain.is_open()) {
            std::cout << "Aborted! Could not write to main file!" << std::endl;
            return;
        }
        wMain << jwMain;
    }

    // Object files
    {
        std::cout << "Compiling object definition files..." << std::endl;
        for(std::vector<FObject>::iterator it = fObjects.begin(); it != fObjects.end(); ++ it) {
            const FObject& fObject = *it;

            // Construct new json file
            Json::Value jwObject;

            // Simple strings
            jwObject["id"] = fObject.id;
            jwObject["model"] = fObject.refModel.qualifiedName;
            jwObject["physics"] = fObject.refPhysics.qualifiedName;
            jwObject["physics-offset"] = toJson(fObject.physOffset);

            std::ofstream wObject(pOutputRoot + "/" + fMain.name + "/" + fObject.refSelf.qualifiedName);
            if(!wObject.is_open()) {
                std::cout << "Aborted! Could not write to object file " << fObject.refSelf.qualifiedName << std::endl;
                return;
            }
            wObject << jwObject;
        }
    }

    // Resource files
    {
        std::cout << "Compiling resources" << std::endl;
        for(std::vector<FResource>::iterator it = fResources.begin(); it != fResources.end(); ++ it) {
            const FResource& fResource = *it;



            Path output = pOutputRoot + "/" + fMain.name + "/" + fResource.refSelf.qualifiedName;

            switch(fResource.type) {
                /*
                case MODEL: {
                }
                */
                case PHYSICS: {
                    std::ifstream rResource(pRoot + "/" + fResource.refSelf.absPath);
                    if(!rResource.is_open()) {
                        std::cout << "Aborted! Could not read " << fResource.refSelf.absPath << "!" << std::endl;
                        return;
                    }
                    std::string extension = getExtension(fResource.refSelf.absPath);

                    FPhysics physShape;
                    if(extension == "json") {
                        Json::Value jwPhysics;
                        rResource >> jwPhysics;

                        std::string strType = jwPhysics["type"].asString();

                        if(strType == "sphere") {
                            physShape.type = SPHERE;
                            physShape.radius = jwPhysics["radius"].asDouble();
                        }
                        else if(strType == "box") {
                            physShape.type = BOX;
                            physShape.dimensions = toBullet(jwPhysics["size"]);
                        }
                        else if(strType == "cylinder") {
                            physShape.type = CYLINDER;
                            physShape.dimensions = toBullet(jwPhysics["size"]);
                        }
                        else if(strType == "capsule") {
                            physShape.type = CAPSULE;
                            physShape.radius = jwPhysics["radius"].asDouble();
                            physShape.height = jwPhysics["height"].asDouble();
                        }
                        else if(strType == "cone") {
                            physShape.type = CONE;
                            physShape.radius = jwPhysics["radius"].asDouble();
                            physShape.height = jwPhysics["height"].asDouble();
                        }
                    }
                    else {

                    }

                    output = shaveExtension(output);
                    ReiIO::savePhysics(output + ".physics", physShape);

                    break;
                }
                case MODEL: {

                    reia::ComplexMeshData* meshData = reia::loadUsingAssimp(smgr, pRoot + "/" + fResource.refSelf.absPath);

                    reia::ComplexMeshSceneNode* meshNode = reia::addNodeFromMesh(smgr, meshData);
                    delete meshNode;

                    output = shaveExtension(output);
                    ReiIO::saveComplexMesh(output + ".model", *meshData);
                    delete meshData;
                    break;
                }

                default: {

                }
            }
        }