Node* GameApplication::add_object(Node* pParentNode, const String& nodeName,enObjectType type,float x,float y,float z,const char* modelUrl,const char* material) { ResourceCache* cache = GetSubsystem<ResourceCache>(); Node* pNode = pParentNode->CreateChild(nodeName); pNode->SetPosition(Vector3(x, y, z)); if(type == enObjectType_StaticModel) { StaticModel* pModel = pNode->CreateComponent<StaticModel>(); pModel->SetModel(cache->GetResource<Model>(modelUrl)); if(material != NULL) pModel->SetMaterial(0,cache->GetResource<Material>(material)); pModel->SetCastShadows(true); } else { AnimatedModel* pAniModel = pNode->CreateComponent<AnimatedModel>(); pAniModel->SetModel(cache->GetResource<Model>(modelUrl)); if(material != NULL) pAniModel->SetMaterial(0,cache->GetResource<Material>(material)); pAniModel->SetCastShadows(true); } return pNode; }
void StaticModel::SetModel(Model* model) { if (model == model_) return; // If script erroneously calls StaticModel::SetModel on an AnimatedModel, warn and redirect if (GetType() == AnimatedModel::GetTypeStatic()) { ATOMIC_LOGWARNING("StaticModel::SetModel() called on AnimatedModel. Redirecting to AnimatedModel::SetModel()"); AnimatedModel* animatedModel = static_cast<AnimatedModel*>(this); animatedModel->SetModel(model); return; } // Unsubscribe from the reload event of previous model (if any), then subscribe to the new if (model_) UnsubscribeFromEvent(model_, E_RELOADFINISHED); model_ = model; if (model) { SubscribeToEvent(model, E_RELOADFINISHED, ATOMIC_HANDLER(StaticModel, HandleModelReloadFinished)); // Copy the subgeometry & LOD level structure SetNumGeometries(model->GetNumGeometries()); const Vector<Vector<SharedPtr<Geometry> > >& geometries = model->GetGeometries(); const PODVector<Vector3>& geometryCenters = model->GetGeometryCenters(); const Matrix3x4* worldTransform = node_ ? &node_->GetWorldTransform() : (const Matrix3x4*)0; for (unsigned i = 0; i < geometries.Size(); ++i) { batches_[i].worldTransform_ = worldTransform; geometries_[i] = geometries[i]; geometryData_[i].center_ = geometryCenters[i]; // ATOMIC BEGIN geometryData_[i].enabled_ = true; geometryData_[i].batchGeometry_ = 0; // ATOMIC END } SetBoundingBox(model->GetBoundingBox()); ResetLodLevels(); } else { SetNumGeometries(0); SetBoundingBox(BoundingBox()); } MarkNetworkUpdate(); }
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>(); }
void Urho3DTemplate::CreateScene() { ResourceCache* cache = GetSubsystem<ResourceCache>(); scene_ = new Scene(context_); //Create octree, use default volume (-1000, -1000, -1000) to (1000,1000,1000) //Also create a DebugRenderer component so that we can draw debug geometry scene_->CreateComponent<Octree>(); scene_->CreateComponent<DebugRenderer>(); //Create scene node & StaticModel component for showing a static plane Node* planeNode = scene_->CreateChild("Plane"); planeNode->SetScale(Vector3(100.0f, 1.0f, 100.0f)); StaticModel* planeObject = planeNode->CreateComponent<StaticModel>(); planeObject->SetModel(cache->GetResource<Model>("Models/Plane.mdl")); planeObject->SetMaterial(cache->GetResource<Material>("Materials/StoneTiled.xml")); //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, 200 world unitys, fade shadows at 80% of maximum shadow distance light->SetShadowCascade(CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f)); //Create some mushrooms const unsigned NUM_MUSHROOMS = 100; for (unsigned i = 0; i < NUM_MUSHROOMS; ++i) CreateMushroom(Vector3(Random(90.0f) - 45.0f, 0.0f, Random(90.0f) - 45.0f)); //Create randomly sized boxes. If boxes are big enough make them occluders const unsigned NUM_BOXES = 20; for (unsigned i = 0; i <NUM_BOXES; ++i) { Node* boxNode = scene_->CreateChild("Box"); float size = 1.0f + Random(10.0f); boxNode->SetPosition(Vector3(Random(80.0f) - 40.0f, size * 0.5f, Random(80.0f) - 40.0f)); boxNode->SetScale(size); StaticModel* boxObject = boxNode->CreateComponent<StaticModel>(); boxObject->SetModel(cache->GetResource<Model>("Models/Box.mdl")); boxObject->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml")); boxObject->SetCastShadows(true); if (size >= 3.0f) boxObject->SetOccluder(true); } //Create Jack node that will follow the path jackNode_ = scene_->CreateChild("Jack"); jackNode_->SetPosition(Vector3(-5.0f, 0.0f, 20.0f)); AnimatedModel* modelObject = jackNode_->CreateComponent<AnimatedModel>(); modelObject->SetModel(cache->GetResource<Model>("Model/Jack.mdl")); modelObject->SetMaterial(cache->GetResource<Material>("Materials/Jack.xml")); modelObject->SetCastShadows(true); //Create the camera. Limit far clip distance to match the fog cameraNode_ = scene_->CreateChild("Camera"); 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)); }
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 SkeletalAnimation::CreateScene() { ResourceCache* cache = GetSubsystem<ResourceCache>(); scene_ = new Scene(context_); // Create octree, use default volume (-1000, -1000, -1000) to (1000, 1000, 1000) // Also create a DebugRenderer component so that we can draw debug geometry scene_->CreateComponent<Octree>(); scene_->CreateComponent<DebugRenderer>(); // Create scene node & StaticModel component for showing a static plane Node* planeNode = scene_->CreateChild("Plane"); planeNode->SetScale(Vector3(100.0f, 1.0f, 100.0f)); StaticModel* planeObject = planeNode->CreateComponent<StaticModel>(); planeObject->SetModel(cache->GetResource<Model>("Models/Plane.mdl")); planeObject->SetMaterial(cache->GetResource<Material>("Materials/StoneTiled.xml")); // 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("Directional light"); 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.0001f, 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 animated models const unsigned NUM_MODELS = 100; const float MODEL_MOVE_SPEED = 2.0f; const float MODEL_ROTATE_SPEED = 100.0f; const BoundingBox bounds(Vector3(-47.0f, 0.0f, -47.0f), Vector3(47.0f, 0.0f, 47.0f)); for (unsigned i = 0; i < NUM_MODELS; ++i) { Node* modelNode = scene_->CreateChild("Jack"); modelNode->SetPosition(Vector3(Random(90.0f) - 45.0f, 0.0f, Random(90.0f) - 45.0f)); modelNode->SetRotation(Quaternion(0.0f, Random(360.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); // Create an AnimationState for a walk animation. Its time position will need to be manually updated to advance the // animation, The alternative would be to use an AnimationController component which updates the animation automatically, // but we need to update the model's position manually in any case Animation* walkAnimation = cache->GetResource<Animation>("Models/Jack_Walk.ani"); AnimationState* state = modelObject->AddAnimationState(walkAnimation); // Enable full blending weight and looping state->SetWeight(1.0f); state->SetLooped(true); // Create our custom Mover component that will move & animate the model during each frame's update Mover* mover = modelNode->CreateComponent<Mover>(); mover->SetParameters(MODEL_MOVE_SPEED, MODEL_ROTATE_SPEED, bounds); } // Create the camera. Limit far clip distance to match the fog cameraNode_ = scene_->CreateChild("Camera"); 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)); }
void RibbonTrailDemo::CreateScene() { ResourceCache* cache = GetSubsystem<ResourceCache>(); scene_ = new Scene(context_); // Create octree, use default volume (-1000, -1000, -1000) to (1000, 1000, 1000) scene_->CreateComponent<Octree>(); // Create scene node & StaticModel component for showing a static plane Node* planeNode = scene_->CreateChild("Plane"); planeNode->SetScale(Vector3(100.0f, 1.0f, 100.0f)); StaticModel* planeObject = planeNode->CreateComponent<StaticModel>(); planeObject->SetModel(cache->GetResource<Model>("Models/Plane.mdl")); planeObject->SetMaterial(cache->GetResource<Material>("Materials/StoneTiled.xml")); // Create a directional light to the world. Node* lightNode = scene_->CreateChild("DirectionalLight"); lightNode->SetDirection(Vector3(0.6f, -1.0f, 0.8f)); // The direction vector does not need to be normalized Light* light = lightNode->CreateComponent<Light>(); light->SetLightType(LIGHT_DIRECTIONAL); light->SetCastShadows(true); light->SetShadowBias(BiasParameters(0.00005f, 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 first box for face camera trail demo with 1 column. boxNode1_ = scene_->CreateChild("Box1"); StaticModel* box1 = boxNode1_->CreateComponent<StaticModel>(); box1->SetModel(cache->GetResource<Model>("Models/Box.mdl")); box1->SetCastShadows(true); RibbonTrail* boxTrail1 = boxNode1_->CreateComponent<RibbonTrail>(); boxTrail1->SetMaterial(cache->GetResource<Material>("Materials/RibbonTrail.xml")); boxTrail1->SetStartColor(Color(1.0f, 0.5f, 0.0f, 1.0f)); boxTrail1->SetEndColor(Color(1.0f, 1.0f, 0.0f, 0.0f)); boxTrail1->SetWidth(0.5f); boxTrail1->SetUpdateInvisible(true); // Create second box for face camera trail demo with 4 column. // This will produce less distortion than first trail. boxNode2_ = scene_->CreateChild("Box2"); StaticModel* box2 = boxNode2_->CreateComponent<StaticModel>(); box2->SetModel(cache->GetResource<Model>("Models/Box.mdl")); box2->SetCastShadows(true); RibbonTrail* boxTrail2 = boxNode2_->CreateComponent<RibbonTrail>(); boxTrail2->SetMaterial(cache->GetResource<Material>("Materials/RibbonTrail.xml")); boxTrail2->SetStartColor(Color(1.0f, 0.5f, 0.0f, 1.0f)); boxTrail2->SetEndColor(Color(1.0f, 1.0f, 0.0f, 0.0f)); boxTrail2->SetWidth(0.5f); boxTrail2->SetTailColumn(4); boxTrail2->SetUpdateInvisible(true); // Load ninja animated model for bone trail demo. Node* ninjaNode = scene_->CreateChild("Ninja"); ninjaNode->SetPosition(Vector3(5.0f, 0.0f, 0.0f)); ninjaNode->SetRotation(Quaternion(0.0f, 180.0f, 0.0f)); AnimatedModel* ninja = ninjaNode->CreateComponent<AnimatedModel>(); ninja->SetModel(cache->GetResource<Model>("Models/NinjaSnowWar/Ninja.mdl")); ninja->SetMaterial(cache->GetResource<Material>("Materials/NinjaSnowWar/Ninja.xml")); ninja->SetCastShadows(true); // Create animation controller and play attack animation. ninjaAnimCtrl_ = ninjaNode->CreateComponent<AnimationController>(); ninjaAnimCtrl_->PlayExclusive("Models/NinjaSnowWar/Ninja_Attack3.ani", 0, true, 0.0f); // Add ribbon trail to tip of sword. Node* swordTip = ninjaNode->GetChild("Joint29", true); swordTrail_ = swordTip->CreateComponent<RibbonTrail>(); // Set sword trail type to bone and set other parameters. swordTrail_->SetTrailType(TT_BONE); swordTrail_->SetMaterial(cache->GetResource<Material>("Materials/SlashTrail.xml")); swordTrail_->SetLifetime(0.22f); swordTrail_->SetStartColor(Color(1.0f, 1.0f, 1.0f, 0.75f)); swordTrail_->SetEndColor(Color(0.2f, 0.5f, 1.0f, 0.0f)); swordTrail_->SetTailColumn(4); swordTrail_->SetUpdateInvisible(true); // Add floating text for info. Node* boxTextNode1 = scene_->CreateChild("BoxText1"); boxTextNode1->SetPosition(Vector3(-1.0f, 2.0f, 0.0f)); Text3D* boxText1 = boxTextNode1->CreateComponent<Text3D>(); boxText1->SetText(String("Face Camera Trail (4 Column)")); boxText1->SetFont(cache->GetResource<Font>("Fonts/BlueHighway.sdf"), 24); Node* boxTextNode2 = scene_->CreateChild("BoxText2"); boxTextNode2->SetPosition(Vector3(-6.0f, 2.0f, 0.0f)); Text3D* boxText2 = boxTextNode2->CreateComponent<Text3D>(); boxText2->SetText(String("Face Camera Trail (1 Column)")); boxText2->SetFont(cache->GetResource<Font>("Fonts/BlueHighway.sdf"), 24); Node* ninjaTextNode2 = scene_->CreateChild("NinjaText"); ninjaTextNode2->SetPosition(Vector3(4.0f, 2.5f, 0.0f)); Text3D* ninjaText = ninjaTextNode2->CreateComponent<Text3D>(); ninjaText->SetText(String("Bone Trail (4 Column)")); ninjaText->SetFont(cache->GetResource<Font>("Fonts/BlueHighway.sdf"), 24); // Create the camera. cameraNode_ = scene_->CreateChild("Camera"); cameraNode_->CreateComponent<Camera>(); // Set an initial position for the camera scene node above the plane cameraNode_->SetPosition(Vector3(0.0f, 2.0f, -14.0f)); }
void Navigation::CreateScene() { ResourceCache* cache = GetSubsystem<ResourceCache>(); scene_ = new Scene(context_); // Create octree, use default volume (-1000, -1000, -1000) to (1000, 1000, 1000) // Also create a DebugRenderer component so that we can draw debug geometry scene_->CreateComponent<Octree>(); scene_->CreateComponent<DebugRenderer>(); // Create scene node & StaticModel component for showing a static plane Node* planeNode = scene_->CreateChild("Plane"); planeNode->SetScale(Vector3(100.0f, 1.0f, 100.0f)); StaticModel* planeObject = planeNode->CreateComponent<StaticModel>(); planeObject->SetModel(cache->GetResource<Model>("Models/Plane.mdl")); planeObject->SetMaterial(cache->GetResource<Material>("Materials/StoneTiled.xml")); // 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 some mushrooms const unsigned NUM_MUSHROOMS = 100; for (unsigned i = 0; i < NUM_MUSHROOMS; ++i) CreateMushroom(Vector3(Random(90.0f) - 45.0f, 0.0f, Random(90.0f) - 45.0f)); // Create randomly sized boxes. If boxes are big enough, make them occluders const unsigned NUM_BOXES = 20; for (unsigned i = 0; i < NUM_BOXES; ++i) { Node* boxNode = scene_->CreateChild("Box"); float size = 1.0f + Random(10.0f); boxNode->SetPosition(Vector3(Random(80.0f) - 40.0f, size * 0.5f, Random(80.0f) - 40.0f)); boxNode->SetScale(size); StaticModel* boxObject = boxNode->CreateComponent<StaticModel>(); boxObject->SetModel(cache->GetResource<Model>("Models/Box.mdl")); boxObject->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml")); boxObject->SetCastShadows(true); if (size >= 3.0f) boxObject->SetOccluder(true); } // Create Jack node that will follow the path jackNode_ = scene_->CreateChild("Jack"); jackNode_->SetPosition(Vector3(-5.0f, 0.0f, 20.0f)); AnimatedModel* modelObject = jackNode_->CreateComponent<AnimatedModel>(); modelObject->SetModel(cache->GetResource<Model>("Models/Jack.mdl")); modelObject->SetMaterial(cache->GetResource<Material>("Materials/Jack.xml")); modelObject->SetCastShadows(true); // Create a NavigationMesh component to the scene root NavigationMesh* navMesh = scene_->CreateComponent<NavigationMesh>(); // Create a Navigable component to the scene root. This tags all of the geometry in the scene as being part of the // navigation mesh. By default this is recursive, but the recursion could be turned off from Navigable scene_->CreateComponent<Navigable>(); // Add padding to the navigation mesh in Y-direction so that we can add objects on top of the tallest boxes // in the scene and still update the mesh correctly navMesh->SetPadding(Vector3(0.0f, 10.0f, 0.0f)); // Now build the navigation geometry. This will take some time. Note that the navigation mesh will prefer to use // physics geometry from the scene nodes, as it often is simpler, but if it can not find any (like in this example) // it will use renderable geometry instead navMesh->Build(); // Create the camera. Limit far clip distance to match the fog cameraNode_ = scene_->CreateChild("Camera"); Camera* camera = cameraNode_->CreateComponent<Camera>(); camera->SetFarClip(300.0f); // Set an initial position for the camera scene node above the plane and looking down cameraNode_->SetPosition(Vector3(0.0f, 50.0f, 0.0f)); pitch_ = 80.0f; cameraNode_->SetRotation(Quaternion(pitch_, yaw_, 0.0f)); }