Esempio n. 1
0
void Vehicle::Init()
{
    // This function is called only from the main program when initially creating the vehicle, not on scene load
    ResourceCache* cache = GetSubsystem<ResourceCache>();

    StaticModel* hullObject = node_->CreateComponent<StaticModel>();
    hullBody_ = node_->CreateComponent<RigidBody>();
    CollisionShape* hullShape = node_->CreateComponent<CollisionShape>();

    node_->SetScale(Vector3(1.5f, 1.0f, 3.0f));
    hullObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
    hullObject->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml"));
    hullObject->SetCastShadows(true);
    hullShape->SetBox(Vector3::ONE);
    hullBody_->SetMass(4.0f);
    hullBody_->SetLinearDamping(0.2f); // Some air resistance
    hullBody_->SetAngularDamping(0.5f);
    hullBody_->SetCollisionLayer(1);

    InitWheel("FrontLeft", Vector3(-0.6f, -0.4f, 0.3f), frontLeft_, frontLeftID_);
    InitWheel("FrontRight", Vector3(0.6f, -0.4f, 0.3f), frontRight_, frontRightID_);
    InitWheel("RearLeft", Vector3(-0.6f, -0.4f, -0.3f), rearLeft_, rearLeftID_);
    InitWheel("RearRight", Vector3(0.6f, -0.4f, -0.3f), rearRight_, rearRightID_);

    GetWheelComponents();
}
Esempio n. 2
0
heXoCam::heXoCam(Context *context, MasterControl *masterControl):
    Object(context),
    yaw_{0.0f},
    pitch_{0.0f},
    yawDelta_{0.0f},
    pitchDelta_{0.0f},
    forceMultiplier{1.0f}
{
    masterControl_ = masterControl;
    SubscribeToEvent(E_SCENEUPDATE, URHO3D_HANDLER(heXoCam, HandleSceneUpdate));

    rootNode_ = masterControl_->world.scene->CreateChild("Camera");
    Node* leftEye = rootNode_->CreateChild("Left Eye");
    leftEye->SetPosition(Vector3::LEFT);
    stereoCam_.first_ = leftEye->CreateComponent<Camera>();
    Node* rightEye = rootNode_->CreateChild("Right Eye");
    rightEye->SetPosition(Vector3::RIGHT);
    stereoCam_.second_ = rightEye->CreateComponent<Camera>();

    camera_ = rootNode_->CreateComponent<Camera>();
    camera_->SetFarClip(128.0f);
    rootNode_->SetPosition(Vector3(0.0f, 42.0f, -23.0f));
    rootNode_->SetRotation(Quaternion(65.0f, 0.0f, 0.0f));
    rigidBody_ = rootNode_->CreateComponent<RigidBody>();
    rigidBody_->SetAngularDamping(10.0f);
    CollisionShape* collisionShape = rootNode_->CreateComponent<CollisionShape>();
    collisionShape->SetSphere(0.1f);
    rigidBody_->SetMass(1.0f);

    SetupViewport();
}
Esempio n. 3
0
void Ragdolls::SpawnObject()
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    
    Node* boxNode = scene_->CreateChild("Sphere");
    boxNode->SetPosition(cameraNode_->GetPosition());
    boxNode->SetRotation(cameraNode_->GetRotation());
    boxNode->SetScale(0.25f);
    StaticModel* boxObject = boxNode->CreateComponent<StaticModel>();
    boxObject->SetModel(cache->GetResource<Model>("Models/Sphere.mdl"));
    boxObject->SetMaterial(cache->GetResource<Material>("Materials/StoneSmall.xml"));
    boxObject->SetCastShadows(true);
    
    RigidBody* body = boxNode->CreateComponent<RigidBody>();
    body->SetMass(1.0f);
    body->SetRollingFriction(0.15f);
    CollisionShape* shape = boxNode->CreateComponent<CollisionShape>();
    shape->SetSphere(1.0f);
    
    const float OBJECT_VELOCITY = 10.0f;
    
    // Set initial velocity for the RigidBody based on camera forward vector. Add also a slight up component
    // to overcome gravity better
    body->SetLinearVelocity(cameraNode_->GetRotation() * Vector3(0.0f, 0.25f, 1.0f) * OBJECT_VELOCITY);
}
Esempio n. 4
0
	void update_scene()
	{
		main_context::access(m_server, [&](main_context::Interface *imc)
		{
			Scene *scene = imc->check_scene(m_main_scene);
			Context *context = scene->GetContext();
			ResourceCache *cache = context->GetSubsystem<ResourceCache>();

			{
				Node *n = scene->GetChild("Base");
				n->SetScale(Vector3(1.0f, 1.0f, 1.0f));
				//n->SetPosition(Vector3(0.0f, 0.5f, 0.0f));
				n->SetPosition(Vector3(0.0f, 0.5f, 0.0f));
				//n->SetRotation(Quaternion(0, 90, 0));

				int w = 10, h = 3, d = 10;
				ss_ data =
						"222222222211211111211111111111"
						"222222222211111111111111111111"
						"222222222211111111111111111111"
						"222222222211111111111111111111"
						"222222222211122111111112111111"
						"222233222211123111111112111111"
						"222233222211111111111111111111"
						"222222222211111111111111111111"
						"222222222211111111111111111111"
						"222222222211111111111111111111"
						;

				// Convert data to the actually usable voxel type id namespace
				// starting from VOXELTYPEID_UNDEFINED=0
				for(size_t i = 0; i < data.size(); i++){
					data[i] = data[i] - '0';
				}

				// Crude way of dynamically defining a voxel model
				n->SetVar(StringHash("simple_voxel_data"), Variant(
						PODVector<uint8_t>((const uint8_t*)data.c_str(),
						data.size())));
				n->SetVar(StringHash("simple_voxel_w"), Variant(w));
				n->SetVar(StringHash("simple_voxel_h"), Variant(h));
				n->SetVar(StringHash("simple_voxel_d"), Variant(d));

				// Load the same model in here and give it to the physics
				// subsystem so that it can be collided to
				SharedPtr<Model> model(interface::mesh::
						create_8bit_voxel_physics_model(context, w, h, d, data,
						m_voxel_reg.get()));

				RigidBody *body = n->CreateComponent<RigidBody>(LOCAL);
				body->SetFriction(0.75f);
				CollisionShape *shape = n->CreateComponent<CollisionShape>(
						LOCAL);
				shape->SetTriangleMesh(model, 0, Vector3::ONE);
			}
		});
	}
Esempio n. 5
0
void SceneReplication::CreateScene()
{
    scene_ = new Scene(context_);
    
    // Create scene content on the server only
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    
    // Create octree and physics world with default settings. Create them as local so that they are not needlessly replicated
    // when a client connects
    scene_->CreateComponent<Octree>(LOCAL);
    scene_->CreateComponent<PhysicsWorld>(LOCAL);
    
    // All static scene content and the camera are also created as local, so that they are unaffected by scene replication and are
    // not removed from the client upon connection. Create a Zone component first for ambient lighting & fog control.
    Node* zoneNode = scene_->CreateChild("Zone", LOCAL);
    Zone* zone = zoneNode->CreateComponent<Zone>();
    zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f));
    zone->SetAmbientColor(Color(0.1f, 0.1f, 0.1f));
    zone->SetFogStart(100.0f);
    zone->SetFogEnd(300.0f);
    
    // Create a directional light without shadows
    Node* lightNode = scene_->CreateChild("DirectionalLight", LOCAL);
    lightNode->SetDirection(Vector3(0.5f, -1.0f, 0.5f));
    Light* light = lightNode->CreateComponent<Light>();
    light->SetLightType(LIGHT_DIRECTIONAL);
    light->SetColor(Color(0.2f, 0.2f, 0.2f));
    light->SetSpecularIntensity(1.0f);
    
    // Create a "floor" consisting of several tiles. Make the tiles physical but leave small cracks between them
    for (int y = -20; y <= 20; ++y)
    {
        for (int x = -20; x <= 20; ++x)
        {
            Node* floorNode = scene_->CreateChild("FloorTile", LOCAL);
            floorNode->SetPosition(Vector3(x * 20.2f, -0.5f, y * 20.2f));
            floorNode->SetScale(Vector3(20.0f, 1.0f, 20.0f));
            StaticModel* floorObject = floorNode->CreateComponent<StaticModel>();
            floorObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
            floorObject->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml"));
            
            RigidBody* body = floorNode->CreateComponent<RigidBody>();
            body->SetFriction(1.0f);
            CollisionShape* shape = floorNode->CreateComponent<CollisionShape>();
            shape->SetBox(Vector3::ONE);
        }
    }
    
    // Create the camera. Limit far clip distance to match the fog
    cameraNode_ = scene_->CreateChild("Camera", LOCAL);
    Camera* camera = cameraNode_->CreateComponent<Camera>();
    camera->SetFarClip(300.0f);
    
    // Set an initial position for the camera scene node above the plane
    cameraNode_->SetPosition(Vector3(0.0f, 5.0f, 0.0f));
}
Esempio n. 6
0
Bool testCollisionShapes(const CollisionShape& a, const CollisionShape& b)
{
	U ai = static_cast<U>(a.getType());
	U bi = static_cast<U>(b.getType());

	ANKI_ASSERT(matrix[ai][bi] != nullptr && "Collision algorithm is missing");
	ANKI_ASSERT(ai < COUNT && bi < COUNT && "Out of range");

	return matrix[bi][ai](a, b);
}
Esempio n. 7
0
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
PhysicsZone::pCollisionShape_type
PhysicsZone::createCapsuleShape(float _radius, float _height)
{
    CollisionShape* pRawPointer = new CollisionShape();
    pCollisionShape_type pShape(pRawPointer, boost::bind(&PhysicsZone::destroyCollisionShape, this, _1));

    pRawPointer->setShapePtr(new btCapsuleShape(_radius, _height));
    // TODO - set offsetMatrix (currently passing NULL, which centers the body at its origin)
    return pShape;
}
Esempio n. 8
0
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
PhysicsZone::pCollisionShape_type
PhysicsZone::createBoxShape(float _dx, float _dy, float _dz)
{
    CollisionShape* pRawPointer = new CollisionShape();
    pCollisionShape_type pShape(pRawPointer, boost::bind(&PhysicsZone::destroyCollisionShape, this, _1));

    pRawPointer->setShapePtr(new btBoxShape(btVector3(_dx,_dy,_dz)));
    // TODO - set offsetMatrix (currently passing NULL, which centers the body at its origin)
    return pShape;
}
Esempio n. 9
0
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
PhysicsZone::pCollisionShape_type
PhysicsZone::createOvoidShape(float _radiusX, float _radiusY, float _radiusZ)
{
    CollisionShape* pRawPointer = new CollisionShape();
    pCollisionShape_type pShape(pRawPointer, boost::bind(&PhysicsZone::destroyCollisionShape, this, _1));

    //seem to recall something about a multisphere shape being scalable in multiple directions... research further
    pRawPointer->setShapePtr(new btSphereShape(btScalar(_radiusX)));
    // TODO - set offsetMatrix (currently passing NULL, which centers the body at its origin)
    return pShape;
}
Esempio n. 10
0
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
PhysicsZone::pCollisionShape_type
PhysicsZone::createNullShape()
{
    CollisionShape* pRawPointer = new CollisionShape();
    pCollisionShape_type pShape(pRawPointer, boost::bind(&PhysicsZone::destroyCollisionShape, this, _1));

    //bit of a hacktastic workaround, but see http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=4461&hilit=btRigidBody+vs+btCollisionObject for intent
    pRawPointer->setShapePtr(new btSphereShape(btScalar(1.)));
    pRawPointer->setIsNUllShape(true);
    // TODO - set offsetMatrix (currently passing NULL, which centers the body at its origin)
    return pShape;
}
Esempio n. 11
0
void MeshInstance::create_convex_collision() {

	StaticBody *static_body = Object::cast_to<StaticBody>(create_convex_collision_node());
	ERR_FAIL_COND(!static_body);
	static_body->set_name(String(get_name()) + "_col");

	add_child(static_body);
	if (get_owner()) {
		CollisionShape *cshape = Object::cast_to<CollisionShape>(static_body->get_child(0));
		static_body->set_owner(get_owner());
		cshape->set_owner(get_owner());
	}
}
Esempio n. 12
0
Node *MeshInstance::create_convex_collision_node() {

	if (mesh.is_null())
		return NULL;

	Ref<Shape> shape = mesh->create_convex_shape();
	if (shape.is_null())
		return NULL;

	StaticBody *static_body = memnew(StaticBody);
	CollisionShape *cshape = memnew(CollisionShape);
	cshape->set_shape(shape);
	static_body->add_child(cshape);
	return static_body;
}
Esempio n. 13
0
 void CollisionShapeManager::SaveAllStoredShapesToBinaryFile(const String& FileName)
 {
     btDefaultSerializer* BulletSerializer = new btDefaultSerializer(1024*1024*5);
     BulletSerializer->startSerialization();
     for( ShapeMapIterator it = this->CollisionShapes.begin() ; it != this->CollisionShapes.end() ; it++ )
     {
         CollisionShape* Shape = (*it).second;
         BulletSerializer->registerNameForPointer((void*)Shape->_GetInternalShape(),(*it).first.c_str());
         int len = Shape->_GetInternalShape()->calculateSerializeBufferSize();
         btChunk* chunk = BulletSerializer->allocate(len,1);
         const char* structType = Shape->_GetInternalShape()->serialize(chunk->m_oldPtr, BulletSerializer);
         BulletSerializer->finalizeChunk(chunk,structType,BT_SHAPE_CODE,Shape->_GetInternalShape());
     }
     BulletSerializer->finishSerialization();
     FILE* f2 = fopen(FileName.c_str(),"wb");
     fwrite(BulletSerializer->getBufferPointer(),BulletSerializer->getCurrentBufferSize(),1,f2);
     fclose(f2);
 }
Esempio n. 14
0
Pickup::Pickup(Context *context, MasterControl *masterControl):
    SceneObject(context, masterControl),
    sinceLastPickup_{0.0f},
    chaoInterval_{Random(23.0f, 100.0f)}
{
    rootNode_->SetName("Pickup");
    graphicsNode_ = rootNode_->CreateChild("Graphics");

    model_ = graphicsNode_->CreateComponent<StaticModel>();
    rootNode_->SetScale(0.8f);
    rootNode_->SetEnabledRecursive(false);

    rigidBody_ = rootNode_->CreateComponent<RigidBody>();
    rigidBody_->SetRestitution(0.666f);
    rigidBody_->SetMass(0.666f);
    rigidBody_->SetLinearFactor(Vector3::ONE - Vector3::UP);
    rigidBody_->SetLinearDamping(0.5f);
    rigidBody_->SetFriction(0.0f);
    rigidBody_->SetAngularFactor(Vector3::UP);
    rigidBody_->SetAngularDamping(0.0f);
    rigidBody_->ApplyTorque(Vector3::UP * 32.0f);
    rigidBody_->SetLinearRestThreshold(0.0f);
    rigidBody_->SetAngularRestThreshold(0.0f);

    CollisionShape* collisionShape = rootNode_->CreateComponent<CollisionShape>();
    collisionShape->SetSphere(1.5f);

    masterControl_->tileMaster_->AddToAffectors(WeakPtr<Node>(rootNode_), WeakPtr<RigidBody>(rigidBody_));

    triggerNode_ = masterControl_->world.scene->CreateChild("PickupTrigger");
    triggerBody_ = triggerNode_->CreateComponent<RigidBody>();
    triggerBody_->SetTrigger(true);
    triggerBody_->SetMass(0.0f);
    triggerBody_->SetLinearFactor(Vector3::ZERO);
    CollisionShape* triggerShape = triggerNode_->CreateComponent<CollisionShape>();
    triggerShape->SetSphere(2.5f);

    particleEmitter_ = graphicsNode_->CreateComponent<ParticleEmitter>();

    particleEmitter_->SetEffect(masterControl_->cache_->GetTempResource<ParticleEffect>("Resources/Particles/Shine.xml"));

    SubscribeToEvent(triggerNode_, E_NODECOLLISIONSTART, URHO3D_HANDLER(Pickup, HandleTriggerStart));
    SubscribeToEvent(E_SCENEUPDATE, URHO3D_HANDLER(Pickup, HandleSceneUpdate));
}
Esempio n. 15
0
/**
 * @param scaling The new local scaling vector
 */
inline void ProxyShape::setLocalScaling(const Vector3& scaling) {

    // Set the local scaling of the collision shape
    mCollisionShape->setLocalScaling(scaling);

    mBody->setIsSleeping(false);

    // Notify the body that the proxy shape has to be updated in the broad-phase
    mBody->updateProxyShapeInBroadPhase(this, true);
}
Esempio n. 16
0
void CharacterDemo::CreateCharacter()
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();

    Node* objectNode = scene_->CreateChild("Jack");
    objectNode->SetPosition(Vector3(0.0f, 1.0f, 0.0f));

    // spin node
    Node* adjustNode = objectNode->CreateChild("AdjNode");
    adjustNode->SetRotation( Quaternion(180, Vector3(0,1,0) ) );
    
    // Create the rendering component + animation controller
    AnimatedModel* object = adjustNode->CreateComponent<AnimatedModel>();
    object->SetModel(cache->GetResource<Model>("Models/Mutant/Mutant.mdl"));
    object->SetMaterial(cache->GetResource<Material>("Models/Mutant/Materials/mutant_M.xml"));
    object->SetCastShadows(true);
    adjustNode->CreateComponent<AnimationController>();

    // Set the head bone for manual control
    object->GetSkeleton().GetBone("Mutant:Head")->animated_ = false;

    // Create rigidbody, and set non-zero mass so that the body becomes dynamic
    RigidBody* body = objectNode->CreateComponent<RigidBody>();
    body->SetCollisionLayer(1);
    body->SetMass(1.0f);

    // Set zero angular factor so that physics doesn't turn the character on its own.
    // Instead we will control the character yaw manually
    body->SetAngularFactor(Vector3::ZERO);

    // Set the rigidbody to signal collision also when in rest, so that we get ground collisions properly
    body->SetCollisionEventMode(COLLISION_ALWAYS);

    // Set a capsule shape for collision
    CollisionShape* shape = objectNode->CreateComponent<CollisionShape>();
    shape->SetCapsule(0.7f, 1.8f, Vector3(0.0f, 0.9f, 0.0f));

    // Create the character logic component, which takes care of steering the rigidbody
    // Remember it so that we can set the controls. Use a WeakPtr because the scene hierarchy already owns it
    // and keeps it alive as long as it's not removed from the hierarchy
    character_ = objectNode->CreateComponent<Character>();
}
Esempio n. 17
0
        void CollisionShapeManager::LoadAllShapesFromXMLFile(const String& FileName, const String& Group)
        {
            /// @todo Replace this stack allocated stream for one initialized from the Resource Manager, after the system is ready.
            Resource::FileStream ShapesStream( FileName, Resource::ResourceManager::GetSingletonPtr()->GetAssetPath(FileName,Group) );
            XML::Document ShapesDoc;
            XML::ParseResult DocResult = ShapesDoc.Load(ShapesStream);
            if( DocResult.Status != XML::StatusOk ) {
                MEZZ_EXCEPTION(ExceptionBase::SYNTAX_ERROR_EXCEPTION_XML,"Failed to parse XML file \"" + FileName + "\".");
            }
            XML::Node ShapesRoot = ShapesDoc.GetChild("InitializerRoot");
            if( ShapesRoot.Empty() ) {
                MEZZ_EXCEPTION(ExceptionBase::SYNTAX_ERROR_EXCEPTION_XML,"Failed to find expected Root node in \"" + FileName + "\".");
            }

            for( XML::NodeIterator ShapeIt = ShapesRoot.begin() ; ShapeIt != ShapesRoot.end() ; ++ShapeIt )
            {
                CollisionShape* DeSerializedShape = Physics::CreateShape( (*ShapeIt) );
                this->CollisionShapes.insert( std::pair<String,CollisionShape*>(DeSerializedShape->GetName(),DeSerializedShape) );
            }
        }
Esempio n. 18
0
//==============================================================================
Bool Frustum::insideFrustum(const CollisionShape& b) const
{
	update();

	for(const Plane& plane : m_planesW)
	{
		if(b.testPlane(plane) < 0.0)
		{
			return false;
		}
	}

	return true;
}
Esempio n. 19
0
void Vehicle::InitWheel(const String& name, const Vector3& offset, WeakPtr<Node>& wheelNode, unsigned& wheelNodeID)
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();

    // Note: do not parent the wheel to the hull scene node. Instead create it on the root level and let the physics
    // constraint keep it together
    wheelNode = GetScene()->CreateChild(name);
    wheelNode->SetPosition(node_->LocalToWorld(offset));
    wheelNode->SetRotation(node_->GetRotation() * (offset.x_ >= 0.0 ? Quaternion(0.0f, 0.0f, -90.0f) :
        Quaternion(0.0f, 0.0f, 90.0f)));
    wheelNode->SetScale(Vector3(0.8f, 0.5f, 0.8f));
    // Remember the ID for serialization
    wheelNodeID = wheelNode->GetID();

    StaticModel* wheelObject = wheelNode->CreateComponent<StaticModel>();
    RigidBody* wheelBody = wheelNode->CreateComponent<RigidBody>();
    CollisionShape* wheelShape = wheelNode->CreateComponent<CollisionShape>();
    Constraint* wheelConstraint = wheelNode->CreateComponent<Constraint>();

    wheelObject->SetModel(cache->GetResource<Model>("Models/Cylinder.mdl"));
    wheelObject->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml"));
    wheelObject->SetCastShadows(true);
    wheelShape->SetSphere(1.0f);
    wheelBody->SetFriction(1.0f);
    wheelBody->SetMass(1.0f);
    wheelBody->SetLinearDamping(0.2f); // Some air resistance
    wheelBody->SetAngularDamping(0.75f); // Could also use rolling friction
    wheelBody->SetCollisionLayer(1);
    wheelConstraint->SetConstraintType(CONSTRAINT_HINGE);
    wheelConstraint->SetOtherBody(GetComponent<RigidBody>()); // Connect to the hull body
    wheelConstraint->SetWorldPosition(wheelNode->GetPosition()); // Set constraint's both ends at wheel's location
    wheelConstraint->SetAxis(Vector3::UP); // Wheel rotates around its local Y-axis
    wheelConstraint->SetOtherAxis(offset.x_ >= 0.0 ? Vector3::RIGHT : Vector3::LEFT); // Wheel's hull axis points either left or right
    wheelConstraint->SetLowLimit(Vector2(-180.0f, 0.0f)); // Let the wheel rotate freely around the axis
    wheelConstraint->SetHighLimit(Vector2(180.0f, 0.0f));
    wheelConstraint->SetDisableCollision(true); // Let the wheel intersect the vehicle hull
}
Esempio n. 20
0
	void on_tick(const interface::TickEvent &event)
	{
		log_d(MODULE, "entitytest::on_tick");
		static uint a = 0;
		if(((a++) % 100) == 0){
			main_context::access(m_server, [&](main_context::Interface *imc){
				Scene *scene = imc->check_scene(m_main_scene);
				Node *n = scene->GetChild("Box");
				n->SetPosition(Vector3(0.0f, 6.0f, 0.0f));
				n->SetRotation(Quaternion(30, 60, 90));
				Node *n2 = scene->GetChild("Box2");
				n2->SetPosition(Vector3(-0.4f, 8.0f, 0.0f));
				n2->SetRotation(Quaternion(30, 60, 90));
				m_slow_count++;
				if(m_slow_count == 2){
					Node *n = scene->CreateChild("Box");
					n->SetPosition(Vector3(0.0f, 10.0f, 0.0f));
					n->SetScale(Vector3(1.0f, 1.0f, 1.0f));
					RigidBody *body = n->CreateComponent<RigidBody>();
					CollisionShape *shape = n->CreateComponent<CollisionShape>();
					shape->SetBox(Vector3::ONE);
					body->SetMass(1.0);
					body->SetFriction(0.75f);
					// Model and material is set on client
				}
			});
			return;
		}
		main_context::access(m_server, [&](main_context::Interface *imc){
			Scene *scene = imc->check_scene(m_main_scene);
			Node *n = scene->GetChild("Box");
			//n->Translate(Vector3(0.1f, 0, 0));
			Vector3 p = n->GetPosition();
			log_v(MODULE, "Position: %s", p.ToString().CString());
		});
	}
Esempio n. 21
0
void VehicleDemo::CreateScene()
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    
    scene_ = new Scene(context_);
    
    // Create scene subsystem components
    scene_->CreateComponent<Octree>();
    scene_->CreateComponent<PhysicsWorld>();
    
    // Create camera and define viewport. We will be doing load / save, so it's convenient to create the camera outside the scene,
    // so that it won't be destroyed and recreated, and we don't have to redefine the viewport on load
    cameraNode_ = new Node(context_);
    Camera* camera = cameraNode_->CreateComponent<Camera>();
    camera->SetFarClip(500.0f);
    GetSubsystem<Renderer>()->SetViewport(0, new Viewport(context_, scene_, camera));
    
    // Create static scene content. First create a zone for ambient lighting and fog control
    Node* zoneNode = scene_->CreateChild("Zone");
    Zone* zone = zoneNode->CreateComponent<Zone>();
    zone->SetAmbientColor(Color(0.15f, 0.15f, 0.15f));
    zone->SetFogColor(Color(0.5f, 0.5f, 0.7f));
    zone->SetFogStart(300.0f);
    zone->SetFogEnd(500.0f);
    zone->SetBoundingBox(BoundingBox(-2000.0f, 2000.0f));
    
    // Create a directional light with cascaded shadow mapping
    Node* lightNode = scene_->CreateChild("DirectionalLight");
    lightNode->SetDirection(Vector3(0.3f, -0.5f, 0.425f));
    Light* light = lightNode->CreateComponent<Light>();
    light->SetLightType(LIGHT_DIRECTIONAL);
    light->SetCastShadows(true);
    light->SetShadowBias(BiasParameters(0.00025f, 0.5f));
    light->SetShadowCascade(CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f));
    light->SetSpecularIntensity(0.5f);
    
    // Create heightmap terrain with collision
    Node* terrainNode = scene_->CreateChild("Terrain");
    terrainNode->SetPosition(Vector3::ZERO);
    Terrain* terrain = terrainNode->CreateComponent<Terrain>();
    terrain->SetPatchSize(64);
    terrain->SetSpacing(Vector3(2.0f, 0.1f, 2.0f)); // Spacing between vertices and vertical resolution of the height map
    terrain->SetSmoothing(true);
    terrain->SetHeightMap(cache->GetResource<Image>("Textures/HeightMap.png"));
    terrain->SetMaterial(cache->GetResource<Material>("Materials/Terrain.xml"));
    // The terrain consists of large triangles, which fits well for occlusion rendering, as a hill can occlude all
    // terrain patches and other objects behind it
    terrain->SetOccluder(true);
    
    RigidBody* body = terrainNode->CreateComponent<RigidBody>();
    body->SetCollisionLayer(2); // Use layer bitmask 2 for static geometry
    CollisionShape* shape = terrainNode->CreateComponent<CollisionShape>();
    shape->SetTerrain();
    
    // Create 1000 mushrooms in the terrain. Always face outward along the terrain normal
    const unsigned NUM_MUSHROOMS = 1000;
    for (unsigned i = 0; i < NUM_MUSHROOMS; ++i)
    {
        Node* objectNode = scene_->CreateChild("Mushroom");
        Vector3 position(Random(2000.0f) - 1000.0f, 0.0f, Random(2000.0f) - 1000.0f);
        position.y_ = terrain->GetHeight(position) - 0.1f;
        objectNode->SetPosition(position);
        // Create a rotation quaternion from up vector to terrain normal
        objectNode->SetRotation(Quaternion(Vector3::UP, terrain->GetNormal(position)));
        objectNode->SetScale(3.0f);
        StaticModel* object = objectNode->CreateComponent<StaticModel>();
        object->SetModel(cache->GetResource<Model>("Models/Mushroom.mdl"));
        object->SetMaterial(cache->GetResource<Material>("Materials/Mushroom.xml"));
        object->SetCastShadows(true);
        
        RigidBody* body = objectNode->CreateComponent<RigidBody>();
        body->SetCollisionLayer(2);
        CollisionShape* shape = objectNode->CreateComponent<CollisionShape>();
        shape->SetTriangleMesh(object->GetModel(), 0);
    }
}
Esempio n. 22
0
void Ragdolls::CreateScene()
{
    ResourceCache* cache = GetContext()->m_ResourceCache.get();

    scene_ = new Scene(GetContext());

    // Create octree, use default volume (-1000, -1000, -1000) to (1000, 1000, 1000)
    // Create a physics simulation world with default parameters, which will update at 60fps. Like the Octree must
    // exist before creating drawable components, the PhysicsWorld must exist before creating physics components.
    // Finally, create a DebugRenderer component so that we can draw physics debug geometry
    scene_->CreateComponent<Octree>();
    scene_->CreateComponent<PhysicsWorld>();
    scene_->CreateComponent<DebugRenderer>();

    // Create a Zone component for ambient lighting & fog control
    Node* zoneNode = scene_->CreateChild("Zone");
    Zone* zone = zoneNode->CreateComponent<Zone>();
    zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f));
    zone->SetAmbientColor(Color(0.15f, 0.15f, 0.15f));
    zone->SetFogColor(Color(0.5f, 0.5f, 0.7f));
    zone->SetFogStart(100.0f);
    zone->SetFogEnd(300.0f);

    // Create a directional light to the world. Enable cascaded shadows on it
    Node* lightNode = scene_->CreateChild("DirectionalLight");
    lightNode->SetDirection(Vector3(0.6f, -1.0f, 0.8f));
    Light* light = lightNode->CreateComponent<Light>();
    light->SetLightType(LIGHT_DIRECTIONAL);
    light->SetCastShadows(true);
    light->SetShadowBias(BiasParameters(0.00025f, 0.5f));
    // Set cascade splits at 10, 50 and 200 world units, fade shadows out at 80% of maximum shadow distance
    light->SetShadowCascade(CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f));

    {
        // Create a floor object, 500 x 500 world units. Adjust position so that the ground is at zero Y
        Node* floorNode = scene_->CreateChild("Floor");
        floorNode->SetPosition(Vector3(0.0f, -0.5f, 0.0f));
        floorNode->SetScale(Vector3(500.0f, 1.0f, 500.0f));
        StaticModel* floorObject = floorNode->CreateComponent<StaticModel>();
        floorObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
        floorObject->SetMaterial(cache->GetResource<Material>("Materials/StoneTiled.xml"));

        // Make the floor physical by adding RigidBody and CollisionShape components
        RigidBody* body = floorNode->CreateComponent<RigidBody>();
        // We will be spawning spherical objects in this sample. The ground also needs non-zero rolling friction so that
        // the spheres will eventually come to rest
        body->SetRollingFriction(0.15f);
        CollisionShape* shape = floorNode->CreateComponent<CollisionShape>();
        // Set a box shape of size 1 x 1 x 1 for collision. The shape will be scaled with the scene node scale, so the
        // rendering and physics representation sizes should match (the box model is also 1 x 1 x 1.)
        shape->SetBox(Vector3::ONE);
    }

    // Create animated models
    for (int z = -1; z <= 1; ++z)
    {
        for (int x = -4; x <= 4; ++x)
        {
            Node* modelNode = scene_->CreateChild("Jack");
            modelNode->SetPosition(Vector3(x * 5.0f, 0.0f, z * 5.0f));
            modelNode->SetRotation(Quaternion(0.0f, 180.0f, 0.0f));
            AnimatedModel* modelObject = modelNode->CreateComponent<AnimatedModel>();
            modelObject->SetModel(cache->GetResource<Model>("Models/Jack.mdl"));
            modelObject->SetMaterial(cache->GetResource<Material>("Materials/Jack.xml"));
            modelObject->SetCastShadows(true);
            // Set the model to also update when invisible to avoid staying invisible when the model should come into
            // view, but does not as the bounding box is not updated
            modelObject->SetUpdateInvisible(true);

            // Create a rigid body and a collision shape. These will act as a trigger for transforming the
            // model into a ragdoll when hit by a moving object
            RigidBody* body = modelNode->CreateComponent<RigidBody>();
            // The Trigger mode makes the rigid body only detect collisions, but impart no forces on the
            // colliding objects
            body->SetTrigger(true);
            CollisionShape* shape = modelNode->CreateComponent<CollisionShape>();
            // Create the capsule shape with an offset so that it is correctly aligned with the model, which
            // has its origin at the feet
            shape->SetCapsule(0.7f, 2.0f, Vector3(0.0f, 1.0f, 0.0f));

            // Create a custom component that reacts to collisions and creates the ragdoll
            modelNode->CreateComponent<CreateRagdoll>();
        }
    }

    // Create the camera. Limit far clip distance to match the fog. Note: now we actually create the camera node outside
    // the scene, because we want it to be unaffected by scene load / save
    cameraNode_ = new Node(GetContext());
    Camera* camera = cameraNode_->CreateComponent<Camera>();
    camera->setFarClipDistance(300.0f);

    // Set an initial position for the camera scene node above the floor
    cameraNode_->SetPosition(Vector3(0.0f, 3.0f, -20.0f));
}
void NavigationMesh::GetTileGeometry(NavBuildData* build, Vector<NavigationGeometryInfo>& geometryList, BoundingBox& box)
{
    Matrix3x4 inverse = node_->GetWorldTransform().Inverse();

    for (unsigned i = 0; i < geometryList.Size(); ++i)
    {
        if (box.IsInsideFast(geometryList[i].boundingBox_) != OUTSIDE)
        {
            const Matrix3x4& transform = geometryList[i].transform_;

            if (geometryList[i].component_->GetType() == OffMeshConnection::GetTypeStatic())
            {
                OffMeshConnection* connection = static_cast<OffMeshConnection*>(geometryList[i].component_);
                Vector3 start = inverse * connection->GetNode()->GetWorldPosition();
                Vector3 end = inverse * connection->GetEndPoint()->GetWorldPosition();

                build->offMeshVertices_.Push(start);
                build->offMeshVertices_.Push(end);
                build->offMeshRadii_.Push(connection->GetRadius());
                build->offMeshFlags_.Push((unsigned short)connection->GetMask());
                build->offMeshAreas_.Push((unsigned char)connection->GetAreaID());
                build->offMeshDir_.Push((unsigned char)(connection->IsBidirectional() ? DT_OFFMESH_CON_BIDIR : 0));
                continue;
            }
            else if (geometryList[i].component_->GetType() == NavArea::GetTypeStatic())
            {
                NavArea* area = static_cast<NavArea*>(geometryList[i].component_);
                NavAreaStub stub;
                stub.areaID_ = (unsigned char)area->GetAreaID();
                stub.bounds_ = area->GetWorldBoundingBox();
                build->navAreas_.Push(stub);
                continue;
            }

#ifdef ATOMIC_PHYSICS
            CollisionShape* shape = dynamic_cast<CollisionShape*>(geometryList[i].component_);
            if (shape)
            {
                switch (shape->GetShapeType())
                {
                case SHAPE_TRIANGLEMESH:
                    {
                        Model* model = shape->GetModel();
                        if (!model)
                            continue;

                        unsigned lodLevel = shape->GetLodLevel();
                        for (unsigned j = 0; j < model->GetNumGeometries(); ++j)
                            AddTriMeshGeometry(build, model->GetGeometry(j, lodLevel), transform);
                    }
                    break;

                case SHAPE_CONVEXHULL:
                    {
                        ConvexData* data = static_cast<ConvexData*>(shape->GetGeometryData());
                        if (!data)
                            continue;

                        unsigned numVertices = data->vertexCount_;
                        unsigned numIndices = data->indexCount_;
                        unsigned destVertexStart = build->vertices_.Size();

                        for (unsigned j = 0; j < numVertices; ++j)
                            build->vertices_.Push(transform * data->vertexData_[j]);

                        for (unsigned j = 0; j < numIndices; ++j)
                            build->indices_.Push(data->indexData_[j] + destVertexStart);
                    }
                    break;

                case SHAPE_BOX:
                    {
                        unsigned destVertexStart = build->vertices_.Size();

                        build->vertices_.Push(transform * Vector3(-0.5f, 0.5f, -0.5f));
                        build->vertices_.Push(transform * Vector3(0.5f, 0.5f, -0.5f));
                        build->vertices_.Push(transform * Vector3(0.5f, -0.5f, -0.5f));
                        build->vertices_.Push(transform * Vector3(-0.5f, -0.5f, -0.5f));
                        build->vertices_.Push(transform * Vector3(-0.5f, 0.5f, 0.5f));
                        build->vertices_.Push(transform * Vector3(0.5f, 0.5f, 0.5f));
                        build->vertices_.Push(transform * Vector3(0.5f, -0.5f, 0.5f));
                        build->vertices_.Push(transform * Vector3(-0.5f, -0.5f, 0.5f));

                        const unsigned indices[] = {
                            0, 1, 2, 0, 2, 3, 1, 5, 6, 1, 6, 2, 4, 5, 1, 4, 1, 0, 5, 4, 7, 5, 7, 6,
                            4, 0, 3, 4, 3, 7, 1, 0, 4, 1, 4, 5
                        };

                        for (unsigned j = 0; j < 36; ++j)
                            build->indices_.Push(indices[j] + destVertexStart);
                    }
                    break;

                default:
                    break;
                }

                continue;
            }
#endif
            Drawable* drawable = dynamic_cast<Drawable*>(geometryList[i].component_);
            if (drawable)
            {
                const Vector<SourceBatch>& batches = drawable->GetBatches();

                for (unsigned j = 0; j < batches.Size(); ++j)
                    AddTriMeshGeometry(build, drawable->GetLodGeometry(j, geometryList[i].lodLevel_), transform);
            }
        }
    }
}
void NavigationMesh::CollectGeometries(Vector<NavigationGeometryInfo>& geometryList, Node* node, HashSet<Node*>& processedNodes,
    bool recursive)
{
    // Make sure nodes are not included twice
    if (processedNodes.Contains(node))
        return;
    // Exclude obstacles and crowd agents from consideration
    if (node->HasComponent<Obstacle>() || node->HasComponent<CrowdAgent>())
        return;
    processedNodes.Insert(node);

    Matrix3x4 inverse = node_->GetWorldTransform().Inverse();

#ifdef ATOMIC_PHYSICS
    // Prefer compatible physics collision shapes (triangle mesh, convex hull, box) if found.
    // Then fallback to visible geometry
    PODVector<CollisionShape*> collisionShapes;
    node->GetComponents<CollisionShape>(collisionShapes);
    bool collisionShapeFound = false;

    for (unsigned i = 0; i < collisionShapes.Size(); ++i)
    {
        CollisionShape* shape = collisionShapes[i];
        if (!shape->IsEnabledEffective())
            continue;

        ShapeType type = shape->GetShapeType();
        if ((type == SHAPE_BOX || type == SHAPE_TRIANGLEMESH || type == SHAPE_CONVEXHULL) && shape->GetCollisionShape())
        {
            Matrix3x4 shapeTransform(shape->GetPosition(), shape->GetRotation(), shape->GetSize());

            NavigationGeometryInfo info;
            info.component_ = shape;
            info.transform_ = inverse * node->GetWorldTransform() * shapeTransform;
            info.boundingBox_ = shape->GetWorldBoundingBox().Transformed(inverse);

            geometryList.Push(info);
            collisionShapeFound = true;
        }
    }
    if (!collisionShapeFound)
#endif
    {
        PODVector<Drawable*> drawables;
        node->GetDerivedComponents<Drawable>(drawables);

        for (unsigned i = 0; i < drawables.Size(); ++i)
        {
            /// \todo Evaluate whether should handle other types. Now StaticModel & TerrainPatch are supported, others skipped
            Drawable* drawable = drawables[i];
            if (!drawable->IsEnabledEffective())
                continue;

            NavigationGeometryInfo info;

            if (drawable->GetType() == StaticModel::GetTypeStatic())
                info.lodLevel_ = static_cast<StaticModel*>(drawable)->GetOcclusionLodLevel();
            else if (drawable->GetType() == TerrainPatch::GetTypeStatic())
                info.lodLevel_ = 0;
            else
                continue;

            info.component_ = drawable;
            info.transform_ = inverse * node->GetWorldTransform();
            info.boundingBox_ = drawable->GetWorldBoundingBox().Transformed(inverse);

            geometryList.Push(info);
        }
    }

    if (recursive)
    {
        const Vector<SharedPtr<Node> >& children = node->GetChildren();
        for (unsigned i = 0; i < children.Size(); ++i)
            CollectGeometries(geometryList, children[i], processedNodes, recursive);
    }
}
Esempio n. 25
0
void	CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
{
	RigidBody* body = ctrl->GetRigidBody();

	//this m_userPointer is just used for triggers, see CallbackTriggers
	body->m_userPointer = ctrl;

	body->setGravity( m_gravity );
	m_controllers.push_back(ctrl);

	m_collisionWorld->AddCollisionObject(body,ctrl->GetCollisionFilterGroup(),ctrl->GetCollisionFilterMask());

	assert(body->m_broadphaseHandle);

	BroadphaseInterface* scene =  GetBroadphase();


	CollisionShape* shapeinterface = ctrl->GetCollisionShape();

	assert(shapeinterface);

	const SimdTransform& t = ctrl->GetRigidBody()->getCenterOfMassTransform();
	
	body->m_cachedInvertedWorldTransform = body->m_worldTransform.inverse();

	SimdPoint3 minAabb,maxAabb;

	shapeinterface->GetAabb(t,minAabb,maxAabb);

	float timeStep = 0.02f;


	//extent it with the motion

	SimdVector3 linMotion = body->getLinearVelocity()*timeStep;

	float maxAabbx = maxAabb.getX();
	float maxAabby = maxAabb.getY();
	float maxAabbz = maxAabb.getZ();
	float minAabbx = minAabb.getX();
	float minAabby = minAabb.getY();
	float minAabbz = minAabb.getZ();

	if (linMotion.x() > 0.f)
		maxAabbx += linMotion.x(); 
	else
		minAabbx += linMotion.x();
	if (linMotion.y() > 0.f)
		maxAabby += linMotion.y(); 
	else
		minAabby += linMotion.y();
	if (linMotion.z() > 0.f)
		maxAabbz += linMotion.z(); 
	else
		minAabbz += linMotion.z();


	minAabb = SimdVector3(minAabbx,minAabby,minAabbz);
	maxAabb = SimdVector3(maxAabbx,maxAabby,maxAabbz);




}
Esempio n. 26
0
void MeshInstanceEditor::_menu_option(int p_option) {

	Ref<Mesh> mesh = node->get_mesh();
	if (mesh.is_null()) {
		err_dialog->set_text(TTR("Mesh is empty!"));
		err_dialog->popup_centered_minsize();
		return;
	}

	switch (p_option) {
		case MENU_OPTION_CREATE_STATIC_TRIMESH_BODY:
		case MENU_OPTION_CREATE_STATIC_CONVEX_BODY: {

			bool trimesh_shape = (p_option == MENU_OPTION_CREATE_STATIC_TRIMESH_BODY);

			EditorSelection *editor_selection = EditorNode::get_singleton()->get_editor_selection();
			UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();

			List<Node *> selection = editor_selection->get_selected_node_list();

			if (selection.empty()) {
				Ref<Shape> shape = trimesh_shape ? mesh->create_trimesh_shape() : mesh->create_convex_shape();
				if (shape.is_null())
					return;

				CollisionShape *cshape = memnew(CollisionShape);
				cshape->set_shape(shape);
				StaticBody *body = memnew(StaticBody);
				body->add_child(cshape);

				Node *owner = node == get_tree()->get_edited_scene_root() ? node : node->get_owner();

				if (trimesh_shape)
					ur->create_action(TTR("Create Static Trimesh Body"));
				else
					ur->create_action(TTR("Create Static Convex Body"));

				ur->add_do_method(node, "add_child", body);
				ur->add_do_method(body, "set_owner", owner);
				ur->add_do_method(cshape, "set_owner", owner);
				ur->add_do_reference(body);
				ur->add_undo_method(node, "remove_child", body);
				ur->commit_action();
				return;
			}

			if (trimesh_shape)
				ur->create_action(TTR("Create Static Trimesh Body"));
			else
				ur->create_action(TTR("Create Static Convex Body"));

			for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {

				MeshInstance *instance = E->get()->cast_to<MeshInstance>();
				if (!instance)
					continue;

				Ref<Mesh> m = instance->get_mesh();
				if (m.is_null())
					continue;

				Ref<Shape> shape = trimesh_shape ? m->create_trimesh_shape() : m->create_convex_shape();
				if (shape.is_null())
					continue;

				CollisionShape *cshape = memnew(CollisionShape);
				cshape->set_shape(shape);
				StaticBody *body = memnew(StaticBody);
				body->add_child(cshape);

				Node *owner = instance == get_tree()->get_edited_scene_root() ? instance : instance->get_owner();

				ur->add_do_method(instance, "add_child", body);
				ur->add_do_method(body, "set_owner", owner);
				ur->add_do_method(cshape, "set_owner", owner);
				ur->add_do_reference(body);
				ur->add_undo_method(instance, "remove_child", body);
			}

			ur->commit_action();

		} break;

		case MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE:
		case MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE: {

			if (node == get_tree()->get_edited_scene_root()) {
				err_dialog->set_text(TTR("This doesn't work on scene root!"));
				err_dialog->popup_centered_minsize();
				return;
			}

			bool trimesh_shape = (p_option == MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE);

			Ref<Shape> shape = trimesh_shape ? mesh->create_trimesh_shape() : mesh->create_convex_shape();
			if (shape.is_null())
				return;

			CollisionShape *cshape = memnew(CollisionShape);
			cshape->set_shape(shape);

			Node *owner = node->get_owner();

			UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();

			if (trimesh_shape)
				ur->create_action(TTR("Create Trimesh Shape"));
			else
				ur->create_action(TTR("Create Convex Shape"));

			ur->add_do_method(node->get_parent(), "add_child", cshape);
			ur->add_do_method(node->get_parent(), "move_child", cshape, node->get_index() + 1);
			ur->add_do_method(cshape, "set_owner", owner);
			ur->add_do_reference(cshape);
			ur->add_undo_method(node->get_parent(), "remove_child", cshape);
			ur->commit_action();

		} break;

		case MENU_OPTION_CREATE_NAVMESH: {

			Ref<NavigationMesh> nmesh = memnew(NavigationMesh);

			if (nmesh.is_null())
				return;

			nmesh->create_from_mesh(mesh);
			NavigationMeshInstance *nmi = memnew(NavigationMeshInstance);
			nmi->set_navigation_mesh(nmesh);

			Node *owner = node == get_tree()->get_edited_scene_root() ? node : node->get_owner();

			UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
			ur->create_action(TTR("Create Navigation Mesh"));

			ur->add_do_method(node, "add_child", nmi);
			ur->add_do_method(nmi, "set_owner", owner);

			ur->add_do_reference(nmi);
			ur->add_undo_method(node, "remove_child", nmi);
			ur->commit_action();
		} break;

		case MENU_OPTION_CREATE_OUTLINE_MESH: {

			outline_dialog->popup_centered(Vector2(200, 90));
		} break;
	}
}
Esempio n. 27
0
//=============================================================================
//=============================================================================
void Vehicle::Init()
{
    // This function is called only from the main program when initially creating the vehicle, not on scene load
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    
    StaticModel* hullObject = node_->CreateComponent<StaticModel>();
    hullBody_ = node_->CreateComponent<RigidBody>();
    CollisionShape* hullColShape = node_->CreateComponent<CollisionShape>();
    
    hullBody_->SetMass(1200.0f);
    hullBody_->SetLinearDamping(0.2f); // Some air resistance
    hullBody_->SetAngularDamping(0.5f);
    hullBody_->SetCollisionLayer(1);

    
    int rightIndex = 0;
    int upIndex = 1;
    int forwardIndex = 2;
    PhysicsWorld *pPhysWorld = GetScene()->GetComponent<PhysicsWorld>();
    btDynamicsWorld *pbtDynWorld = (btDynamicsWorld*)pPhysWorld->GetWorld();
    
    m_vehicleRayCaster = new btDefaultVehicleRaycaster( pbtDynWorld );
    m_vehicle = new btRaycastVehicle( m_tuning, hullBody_->GetBody(), m_vehicleRayCaster );
    pbtDynWorld->addVehicle( m_vehicle );
    
    

    
    m_vehicle->setCoordinateSystem( rightIndex, upIndex, forwardIndex );
    
    
    //Vector3 v3BoxExtents = Vector3::ONE;//Vector3(1.5f, 1.0f, 3.0f);
    hullObject->SetModel(cache->GetResource<Model>("MyProjects/MiniCooper/test/Chassis_001.mdl"));
    node_->SetScale( Vector3(1.0f, 1.0f, 1.0f) );
  
    
    hullColShape->SetConvexHull(cache->GetResource<Model>("MyProjects/MiniCooper/test/collision.mdl"));
    //hullColShape->SetConvexHull(cache->GetResource<Model>("Models/Box.mdl"));
    //hullColShape->SetBox((hullObject->GetBoundingBox()).Size());
    //hullColShape->SetTriangleMesh(cache->GetResource<Model>("Models/Box.mdl"));
    //hullColShape->SetSize(Vector3(1.0f, 1.0f, 3.0f));
    
    
    //hullColShape->SetPosition((hullObject->GetBoundingBox()).Center() - Vector3(0.0f, 0.0f, 0.0f) );
    //hullColShape->SetPosition( Vector3(0.0f, +0.2f, 0.0f) );
    
    
    
    
   
    
    hullObject->SetCastShadows(true);

    
    Node* patricleTest = node_->CreateChild("patricleTest");
    patricleTest->LoadXML(cache->GetResource<XMLFile>("MyProjects/MiniCooper/particleTest.xml")->GetRoot());
    patricleTest->SetPosition(Vector3(0.0f, 0.2f, -2.0f));

    Node* lightTest = node_->CreateChild("lightTest");
    lightTest->LoadXML(cache->GetResource<XMLFile>("MyProjects/MiniCooper/lightTest.xml")->GetRoot());
    lightTest->SetPosition(Vector3(0.0f, 0.2f, 2.0f));
    

    
    
    

    

    //float connectionHeight = -0.4f;//1.2f;
    //float connectionHeight = 0.0f;
    bool isFrontWheel=true;
    btVector3 wheelDirectionCS0(0,-1,0);
    btVector3 wheelAxleCS(1,0,0);
    
    double wheelOffset = 0.5;
    
    
    // front right
    //////////////
    Node* node_wheel_temp0 = GetScene()->CreateChild("node_wheel_temp0");
    StaticModel* model_wheel_temp0 = node_wheel_temp0->CreateComponent<StaticModel>();
    model_wheel_temp0->SetModel(cache->GetResource<Model>("MyProjects/MiniCooper/test/wheel_000.mdl"));
    model_wheel_temp0->ApplyMaterialList("MyProjects/MiniCooper/test/wheel_000.txt");
    model_wheel_temp0->SetCastShadows(true);

    //btVector3 connectionPointCS0(((model_wheel_temp0->GetBoundingBox()).Center()).x_, ((model_wheel_temp0->GetBoundingBox()).Center()).y_, ((model_wheel_temp0->GetBoundingBox()).Center()).z_);
    //wheelRadius = model_wheel_temp0->GetBoundingBox().HalfSize().y_;
    //m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel);
    btVector3 connectionPointCS0((model_wheel_temp0->GetBoundingBox()).Center().x_,((model_wheel_temp0->GetBoundingBox()).Center()).y_ + wheelOffset,((model_wheel_temp0->GetBoundingBox()).Center()).z_);
    m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,btVector3(-1,0,0),suspensionRestLength,wheelRadius,m_tuning,isFrontWheel);


    Node* node_wheel_0 = GetScene()->CreateChild("node_wheel_0");
    node_wheel_0->SetPosition((model_wheel_temp0->GetBoundingBox()).Center());
    node_wheel_0->SetRotation(Quaternion(0.0f, 0.0f, 90.0f));
    node_wheel_temp0->SetParent(node_wheel_0);
    m_vpNodeWheel.Push( node_wheel_0 );

    //SDL_Log( "node_wheel_temp0: %f, %f, %f \n", ((model_wheel_temp0->GetBoundingBox()).Center()).x_, ((model_wheel_temp0->GetBoundingBox()).Center()).y_, ((model_wheel_temp0->GetBoundingBox()).Center()).z_);
    //SDL_Log( "node_wheel_temp0.HalfSize: %s \n", model_wheel_temp0->GetBoundingBox().HalfSize().ToString().CString() );

    //SDL_Log("##################### \n");
    //SDL_Log("node_wheel_temp0WorldP: %f, %f, %f \n", node_wheel_temp0->GetWorldPosition().x_, node_wheel_temp0->GetWorldPosition().y_, node_wheel_temp0->GetWorldPosition().z_);
    //SDL_Log("node_wheel_temp0P: %f, %f, %f \n", node_wheel_temp0->GetPosition().x_, node_wheel_temp0->GetPosition().y_, node_wheel_temp0->GetPosition().z_);

    //SDL_Log( "model_wheel_temp0BoundP: %f, %f, %f \n", ((model_wheel_temp0->GetBoundingBox()).Center()).x_, ((model_wheel_temp0->GetBoundingBox()).Center()).y_, ((model_wheel_temp0->GetBoundingBox()).Center()).z_);

    //node_wheel_temp0->SetPosition(node_wheel_temp0->GetPosition() - (model_wheel_temp0->GetBoundingBox()).Center());

    //SDL_Log("transform: %f, %f, %f \n", v3Origin.x_, v3Origin.y_, v3Origin.z_);
    //v3Origin = v3Origin - Vector3(0.704, 0.379, 1.19);
    //SDL_Log("transform: %f, %f, %f \n", v3Origin.x_, v3Origin.y_, v3Origin.z_);





    // front left
    /////////////
    Node* node_wheel_temp1 = GetScene()->CreateChild("node_wheel_temp1");
    StaticModel* model_wheel_temp1 = node_wheel_temp1->CreateComponent<StaticModel>();
    model_wheel_temp1->SetModel(cache->GetResource<Model>("MyProjects/MiniCooper/test/wheel_001.mdl"));
    model_wheel_temp1->SetCastShadows(true);

    //btVector3 connectionPointCS0(((model_wheel_temp0->GetBoundingBox()).Center()).x_, ((model_wheel_temp0->GetBoundingBox()).Center()).y_, ((model_wheel_temp0->GetBoundingBox()).Center()).z_);
    //wheelRadius = model_wheel_temp0->GetBoundingBox().HalfSize().y_;
    //m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel);
    connectionPointCS0 = btVector3((model_wheel_temp1->GetBoundingBox()).Center().x_,((model_wheel_temp1->GetBoundingBox()).Center()).y_ + wheelOffset,((model_wheel_temp1->GetBoundingBox()).Center()).z_);
    m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,btVector3(-1,0,0),suspensionRestLength,wheelRadius,m_tuning,isFrontWheel);


    Node* node_wheel_1 = GetScene()->CreateChild("node_wheel_1");
    node_wheel_1->SetPosition((model_wheel_temp1->GetBoundingBox()).Center());
    node_wheel_1->SetRotation(Quaternion(0.0f, 0.0f, -90.0f));
    node_wheel_temp1->SetParent(node_wheel_1);
    m_vpNodeWheel.Push( node_wheel_1 );



    

    
    
    isFrontWheel = false;


    // back right
    /////////////
    Node* node_wheel_temp2 = GetScene()->CreateChild("node_wheel_temp2");
    StaticModel* model_wheel_temp2 = node_wheel_temp2->CreateComponent<StaticModel>();
    model_wheel_temp2->SetModel(cache->GetResource<Model>("MyProjects/MiniCooper/test/wheel_002.mdl"));
    model_wheel_temp2->SetCastShadows(true);

    //btVector3 connectionPointCS0(((model_wheel_temp0->GetBoundingBox()).Center()).x_, ((model_wheel_temp0->GetBoundingBox()).Center()).y_, ((model_wheel_temp0->GetBoundingBox()).Center()).z_);
    //wheelRadius = model_wheel_temp0->GetBoundingBox().HalfSize().y_;
    //m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel);
    connectionPointCS0 = btVector3((model_wheel_temp2->GetBoundingBox()).Center().x_,((model_wheel_temp2->GetBoundingBox()).Center()).y_ + wheelOffset,((model_wheel_temp2->GetBoundingBox()).Center()).z_);
    m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,btVector3(-1,0,0),suspensionRestLength,wheelRadius,m_tuning,isFrontWheel);


    Node* node_wheel_2 = GetScene()->CreateChild("node_wheel_2");
    node_wheel_2->SetPosition((model_wheel_temp2->GetBoundingBox()).Center());
    node_wheel_2->SetRotation(Quaternion(0.0f, 0.0f, 90.0f));
    node_wheel_temp2->SetParent(node_wheel_2);
    m_vpNodeWheel.Push( node_wheel_2 );




    // back left
    /////////////
    /// \brief objectNode3


    Node* node_wheel_temp3 = GetScene()->CreateChild("node_wheel_temp3");
    StaticModel* model_wheel_temp3 = node_wheel_temp3->CreateComponent<StaticModel>();
    model_wheel_temp3->SetModel(cache->GetResource<Model>("MyProjects/MiniCooper/test/wheel_003.mdl"));
    model_wheel_temp3->SetCastShadows(true);

    //btVector3 connectionPointCS0(((model_wheel_temp0->GetBoundingBox()).Center()).x_, ((model_wheel_temp0->GetBoundingBox()).Center()).y_, ((model_wheel_temp0->GetBoundingBox()).Center()).z_);
    //wheelRadius = model_wheel_temp0->GetBoundingBox().HalfSize().y_;
    //m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel);
    connectionPointCS0 = btVector3((model_wheel_temp3->GetBoundingBox()).Center().x_,((model_wheel_temp3->GetBoundingBox()).Center()).y_ + wheelOffset,((model_wheel_temp3->GetBoundingBox()).Center()).z_);
    m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,btVector3(-1,0,0),suspensionRestLength,wheelRadius,m_tuning,isFrontWheel);


    Node* node_wheel_3 = GetScene()->CreateChild("node_wheel_2");
    node_wheel_3->SetPosition((model_wheel_temp3->GetBoundingBox()).Center());
    node_wheel_3->SetRotation(Quaternion(0.0f, 0.0f, -90.0f));
    node_wheel_temp3->SetParent(node_wheel_3);
    m_vpNodeWheel.Push( node_wheel_3 );





    
  /*
    for ( int i = 0; i < m_vehicle->getNumWheels(); i++ )
    {
        btWheelInfo& wheel = m_vehicle->getWheelInfo( i );
        wheel.m_suspensionStiffness = suspensionStiffness;
        wheel.m_wheelsDampingRelaxation = suspensionDamping;
        wheel.m_wheelsDampingCompression = suspensionCompression;
        wheel.m_frictionSlip = wheelFriction;
        wheel.m_rollInfluence = rollInfluence;

        
        
    }
    */
    
    if ( m_vehicle )
    {
        m_vehicle->resetSuspension();
        
        for ( int i = 0; i < m_vehicle->getNumWheels(); i++ )
        {
            //synchronize the wheels with the (interpolated) chassis worldtransform
            m_vehicle->updateWheelTransform(i,true);

            btTransform transform = m_vehicle->getWheelTransformWS( i );

            /*

            //Vector3 v3Origin = ToVector3( transform.getOrigin() );
            //Quaternion qRot = ToQuaternion( transform.getRotation() );

            // create wheel node
            Node *wheelNode = GetScene()->CreateChild();


            //wheelNode->SetPosition( v3Origin );

            //btWheelInfo whInfo = m_vehicle->getWheelInfo( i );
            //Vector3 v3PosLS = ToVector3( whInfo.m_chassisConnectionPointCS );



            //wheelNode->SetRotation( v3PosLS.x_ >= 0.0 ? Quaternion(0.0f, 0.0f, -90.0f) : Quaternion(0.0f, 0.0f, 90.0f) );
            //wheelNode->SetScale(Vector3(1.0f, 0.65f, 1.0f));

            StaticModel *pWheel = wheelNode->CreateComponent<StaticModel>();
            if(i == 0)
                pWheel->SetModel(cache->GetResource<Model>("MyProjects/SimpeCar/wheel.mdl"));
            else
                pWheel->SetModel(cache->GetResource<Model>("MyProjects/SimpeCar/wheel.mdl"));

            if(i == 0) {
                //wheelNode->SetPosition( Vector3(50,50,50) );
                //wheelNode->SetRotation(Quaternion(0.0f, 0.0f, 0.0f));
            }else {
                //wheelNode->SetPosition( v3Origin );
                //wheelNode->SetRotation(Quaternion(0.0f, 0.0f, 0.0f));
            }

            m_vpNodeWheel.Push( wheelNode );

            //pWheel->SetModel(cache->GetResource<Model>("MyProjects/MiniCooper/test/wheel_004.mdl"));
            pWheel->SetMaterial(cache->GetResource<Material>("MyProjects/SimpeCar/TireTextureMaterial.xml"));
            pWheel->SetCastShadows(true);
            */
        }
    }
}
Esempio n. 28
0
void PhysicsStressTest::CreateScene()
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();
    
    scene_ = new Scene(context_);
    
    // Create octree, use default volume (-1000, -1000, -1000) to (1000, 1000, 1000)
    // Create a physics simulation world with default parameters, which will update at 60fps. Like the Octree must
    // exist before creating drawable components, the PhysicsWorld must exist before creating physics components.
    // Finally, create a DebugRenderer component so that we can draw physics debug geometry
    scene_->CreateComponent<Octree>();
    scene_->CreateComponent<PhysicsWorld>();
    scene_->CreateComponent<DebugRenderer>();
    
    // Create a Zone component for ambient lighting & fog control
    Node* zoneNode = scene_->CreateChild("Zone");
    Zone* zone = zoneNode->CreateComponent<Zone>();
    zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f));
    zone->SetAmbientColor(Color(0.15f, 0.15f, 0.15f));
    zone->SetFogColor(Color(0.5f, 0.5f, 0.7f));
    zone->SetFogStart(100.0f);
    zone->SetFogEnd(300.0f);
    
    // Create a directional light to the world. Enable cascaded shadows on it
    Node* lightNode = scene_->CreateChild("DirectionalLight");
    lightNode->SetDirection(Vector3(0.6f, -1.0f, 0.8f));
    Light* light = lightNode->CreateComponent<Light>();
    light->SetLightType(LIGHT_DIRECTIONAL);
    light->SetCastShadows(true);
    light->SetShadowBias(BiasParameters(0.00025f, 0.5f));
    // Set cascade splits at 10, 50 and 200 world units, fade shadows out at 80% of maximum shadow distance
    light->SetShadowCascade(CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f));
    
    {
        // Create a floor object, 500 x 500 world units. Adjust position so that the ground is at zero Y
        Node* floorNode = scene_->CreateChild("Floor");
        floorNode->SetPosition(Vector3(0.0f, -0.5f, 0.0f));
        floorNode->SetScale(Vector3(500.0f, 1.0f, 500.0f));
        StaticModel* floorObject = floorNode->CreateComponent<StaticModel>();
        floorObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
        floorObject->SetMaterial(cache->GetResource<Material>("Materials/StoneTiled.xml"));
        
        // Make the floor physical by adding RigidBody and CollisionShape components
        RigidBody* body = floorNode->CreateComponent<RigidBody>();
        CollisionShape* shape = floorNode->CreateComponent<CollisionShape>();
        shape->SetBox(Vector3::ONE);
    }
    
    {
        // Create static mushrooms with triangle mesh collision
        const unsigned NUM_MUSHROOMS = 50;
        for (unsigned i = 0; i < NUM_MUSHROOMS; ++i)
        {
            Node* mushroomNode = scene_->CreateChild("Mushroom");
            mushroomNode->SetPosition(Vector3(Random(400.0f) - 200.0f, 0.0f, Random(400.0f) - 200.0f));
            mushroomNode->SetRotation(Quaternion(0.0f, Random(360.0f), 0.0f));
            mushroomNode->SetScale(5.0f + Random(5.0f));
            StaticModel* mushroomObject = mushroomNode->CreateComponent<StaticModel>();
            mushroomObject->SetModel(cache->GetResource<Model>("Models/Mushroom.mdl"));
            mushroomObject->SetMaterial(cache->GetResource<Material>("Materials/Mushroom.xml"));
            mushroomObject->SetCastShadows(true);

            RigidBody* body = mushroomNode->CreateComponent<RigidBody>();
            CollisionShape* shape = mushroomNode->CreateComponent<CollisionShape>();
            // By default the highest LOD level will be used, the LOD level can be passed as an optional parameter
            shape->SetTriangleMesh(mushroomObject->GetModel());
        }
    }
    
    {
        // Create a large amount of falling physics objects
        const unsigned NUM_OBJECTS = 1000;
        for (unsigned i = 0; i < NUM_OBJECTS; ++i)
        {
            Node* boxNode = scene_->CreateChild("Box");
            boxNode->SetPosition(Vector3(0.0f, i * 2.0f + 100.0f, 0.0f));
            StaticModel* boxObject = boxNode->CreateComponent<StaticModel>();
            boxObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
            boxObject->SetMaterial(cache->GetResource<Material>("Materials/StoneSmall.xml"));
            boxObject->SetCastShadows(true);
            
            // Give the RigidBody mass to make it movable and also adjust friction
            RigidBody* body = boxNode->CreateComponent<RigidBody>();
            body->SetMass(1.0f);
            body->SetFriction(1.0f);
            // Disable collision event signaling to reduce CPU load of the physics simulation
            body->SetCollisionEventMode(COLLISION_NEVER);
            CollisionShape* shape = boxNode->CreateComponent<CollisionShape>();
            shape->SetBox(Vector3::ONE);
        }
    }
    
    // Create the camera. Limit far clip distance to match the fog. Note: now we actually create the camera node outside
    // the scene, because we want it to be unaffected by scene load / save
    cameraNode_ = new Node(context_);
    Camera* camera = cameraNode_->CreateComponent<Camera>();
    camera->SetFarClip(300.0f);
    
    // Set an initial position for the camera scene node above the floor
    cameraNode_->SetPosition(Vector3(0.0f, 3.0f, -20.0f));
}
Esempio n. 29
0
void	SimulationIsland::UpdateAabbs(IDebugDraw* debugDrawer,BroadphaseInterface* scene,float	timeStep)
{
	std::vector<CcdPhysicsController*>::iterator i;


	//
			// update aabbs, only for moving objects (!)
			//
			for (i=m_controllers.begin();
				!(i==m_controllers.end()); i++)
			{
				CcdPhysicsController* ctrl = (*i);
				RigidBody* body = ctrl->GetRigidBody();


				SimdPoint3 minAabb,maxAabb;
				CollisionShape* shapeinterface = ctrl->GetCollisionShape();



				shapeinterface->CalculateTemporalAabb(body->getCenterOfMassTransform(),
					body->getLinearVelocity(),
					//body->getAngularVelocity(),
					SimdVector3(0.f,0.f,0.f),//no angular effect for now //body->getAngularVelocity(),
					timeStep,minAabb,maxAabb);


				SimdVector3 manifoldExtraExtents(gContactBreakingTreshold,gContactBreakingTreshold,gContactBreakingTreshold);
				minAabb -= manifoldExtraExtents;
				maxAabb += manifoldExtraExtents;

				BroadphaseProxy* bp = body->m_broadphaseHandle;
				if (bp)
				{

					SimdVector3 color (1,1,0);

					class IDebugDraw*	m_debugDrawer = 0;
/*
					if (m_debugDrawer)
					{	
						//draw aabb
						switch (body->GetActivationState())
						{
						case ISLAND_SLEEPING:
							{
								color.setValue(1,1,1);
								break;
							}
						case WANTS_DEACTIVATION:
							{
								color.setValue(0,0,1);
								break;
							}
						case ACTIVE_TAG:
							{
								break;
							}
						case DISABLE_DEACTIVATION:
							{
								color.setValue(1,0,1);
							};

						};

						if (m_debugDrawer->GetDebugMode() & IDebugDraw::DBG_DrawAabb)
						{
							DrawAabb(m_debugDrawer,minAabb,maxAabb,color);
						}
					}
*/

			
					if ( (maxAabb-minAabb).length2() < 1e12f)
					{
						scene->SetAabb(bp,minAabb,maxAabb);
					} else
					{
						//something went wrong, investigate
						//removeCcdPhysicsController(ctrl);
						body->SetActivationState(DISABLE_SIMULATION);

						static bool reportMe = true;
						if (reportMe)
						{
							reportMe = false;
							printf("Overflow in AABB, object removed from simulation \n");
							printf("If you can reproduce this, please email [email protected]\n");
							printf("Please include above information, your Platform, version of OS.\n");
							printf("Thanks.\n");
						}
						
					}

				}
			}
}
Esempio n. 30
0
void CharacterDemo::CreateScene()
{
    ResourceCache* cache = GetSubsystem<ResourceCache>();

    scene_ = new Scene(context_);

    // Create scene subsystem components
    scene_->CreateComponent<Octree>();
    scene_->CreateComponent<PhysicsWorld>();

    // Create camera and define viewport. We will be doing load / save, so it's convenient to create the camera outside the scene,
    // so that it won't be destroyed and recreated, and we don't have to redefine the viewport on load
    cameraNode_ = new Node(context_);
    Camera* camera = cameraNode_->CreateComponent<Camera>();
    camera->SetFarClip(300.0f);
    GetSubsystem<Renderer>()->SetViewport(0, new Viewport(context_, scene_, camera));

    // Create static scene content. First create a zone for ambient lighting and fog control
    Node* zoneNode = scene_->CreateChild("Zone");
    Zone* zone = zoneNode->CreateComponent<Zone>();
    zone->SetAmbientColor(Color(0.15f, 0.15f, 0.15f));
    zone->SetFogColor(Color(0.5f, 0.5f, 0.7f));
    zone->SetFogStart(100.0f);
    zone->SetFogEnd(300.0f);
    zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f));

    // Create a directional light with cascaded shadow mapping
    Node* lightNode = scene_->CreateChild("DirectionalLight");
    lightNode->SetDirection(Vector3(0.3f, -0.5f, 0.425f));
    Light* light = lightNode->CreateComponent<Light>();
    light->SetLightType(LIGHT_DIRECTIONAL);
    light->SetCastShadows(true);
    light->SetShadowBias(BiasParameters(0.00025f, 0.5f));
    light->SetShadowCascade(CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f));
    light->SetSpecularIntensity(0.5f);

    // Create the floor object
    Node* floorNode = scene_->CreateChild("Floor");
    floorNode->SetPosition(Vector3(0.0f, -0.5f, 0.0f));
    floorNode->SetScale(Vector3(200.0f, 1.0f, 200.0f));
    StaticModel* object = floorNode->CreateComponent<StaticModel>();
    object->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
    object->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml"));

    RigidBody* body = floorNode->CreateComponent<RigidBody>();
    // Use collision layer bit 2 to mark world scenery. This is what we will raycast against to prevent camera from going
    // inside geometry
    body->SetCollisionLayer(2);
    CollisionShape* shape = floorNode->CreateComponent<CollisionShape>();
    shape->SetBox(Vector3::ONE);

    // Create mushrooms of varying sizes
    const unsigned NUM_MUSHROOMS = 60;
    for (unsigned i = 0; i < NUM_MUSHROOMS; ++i)
    {
        Node* objectNode = scene_->CreateChild("Mushroom");
        objectNode->SetPosition(Vector3(Random(180.0f) - 90.0f, 0.0f, Random(180.0f) - 90.0f));
        objectNode->SetRotation(Quaternion(0.0f, Random(360.0f), 0.0f));
        objectNode->SetScale(2.0f + Random(5.0f));
        StaticModel* object = objectNode->CreateComponent<StaticModel>();
        object->SetModel(cache->GetResource<Model>("Models/Mushroom.mdl"));
        object->SetMaterial(cache->GetResource<Material>("Materials/Mushroom.xml"));
        object->SetCastShadows(true);

        RigidBody* body = objectNode->CreateComponent<RigidBody>();
        body->SetCollisionLayer(2);
        CollisionShape* shape = objectNode->CreateComponent<CollisionShape>();
        shape->SetTriangleMesh(object->GetModel(), 0);
    }

    // Create movable boxes. Let them fall from the sky at first
    const unsigned NUM_BOXES = 100;
    for (unsigned i = 0; i < NUM_BOXES; ++i)
    {
        float scale = Random(2.0f) + 0.5f;

        Node* objectNode = scene_->CreateChild("Box");
        objectNode->SetPosition(Vector3(Random(180.0f) - 90.0f, Random(10.0f) + 10.0f, Random(180.0f) - 90.0f));
        objectNode->SetRotation(Quaternion(Random(360.0f), Random(360.0f), Random(360.0f)));
        objectNode->SetScale(scale);
        StaticModel* object = objectNode->CreateComponent<StaticModel>();
        object->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
        object->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml"));
        object->SetCastShadows(true);

        RigidBody* body = objectNode->CreateComponent<RigidBody>();
        body->SetCollisionLayer(2);
        // Bigger boxes will be heavier and harder to move
        body->SetMass(scale * 2.0f);
        CollisionShape* shape = objectNode->CreateComponent<CollisionShape>();
        shape->SetBox(Vector3::ONE);
    }
}