void CreateScene() { var cache = GetSubsystem <ResourceCache>(); scene = new Scene(); // 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(); Camera camera = CameraNode.CreateComponent <Camera>(); camera.FarClip = 500.0f; GetSubsystem <Renderer>().SetViewport(0, new Viewport(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.AmbientColor = new Color(0.15f, 0.15f, 0.15f); zone.FogColor = new Color(0.5f, 0.5f, 0.7f); zone.FogStart = 300.0f; zone.FogEnd = 500.0f; zone.SetBoundingBox(new BoundingBox(-2000.0f, 2000.0f)); // Create a directional light with cascaded shadow mapping Node lightNode = scene.CreateChild("DirectionalLight"); lightNode.SetDirection(new Vector3(0.3f, -0.5f, 0.425f)); Light light = lightNode.CreateComponent <Light>(); light.LightType = LightType.LIGHT_DIRECTIONAL; light.CastShadows = true; light.ShadowBias = new BiasParameters(0.00025f, 0.5f); light.ShadowCascade = new CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f); light.SpecularIntensity = 0.5f; // Create heightmap terrain with collision Node terrainNode = scene.CreateChild("Terrain"); terrainNode.Position = (Vector3.Zero); Terrain terrain = terrainNode.CreateComponent <Terrain>(); terrain.PatchSize = 64; terrain.Spacing = new Vector3(2.0f, 0.1f, 2.0f); // Spacing between vertices and vertical resolution of the height map terrain.Smoothing = true; terrain.SetHeightMap(cache.Get <Image>("Textures/HeightMap.png")); terrain.Material = cache.Get <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.Occluder = true; RigidBody body = terrainNode.CreateComponent <RigidBody>(); body.CollisionLayer = 2; // Use layer bitmask 2 for static geometry CollisionShape shape = terrainNode.CreateComponent <CollisionShape>(); shape.SetTerrain(0); // Create 1000 mushrooms in the terrain. Always face outward along the terrain normal const uint numMushrooms = 1000; for (uint i = 0; i < numMushrooms; ++i) { Node objectNode = scene.CreateChild("Mushroom"); Vector3 position = new Vector3(NextRandom(2000.0f) - 1000.0f, 0.0f, NextRandom(2000.0f) - 1000.0f); position.Y = terrain.GetHeight(position) - 0.1f; objectNode.Position = (position); // Create a rotation quaternion from up vector to terrain normal objectNode.Rotation = Quaternion.FromRotationTo(Vector3.UnitY, terrain.GetNormal(position)); objectNode.SetScale(3.0f); StaticModel sm = objectNode.CreateComponent <StaticModel>(); sm.Model = (cache.Get <Model>("Models/Mushroom.mdl")); sm.SetMaterial(cache.Get <Material>("Materials/Mushroom.xml")); sm.CastShadows = true; body = objectNode.CreateComponent <RigidBody>(); body.CollisionLayer = 2; shape = objectNode.CreateComponent <CollisionShape>(); shape.SetTriangleMesh(sm.Model, 0, Vector3.One, Vector3.Zero, Quaternion.Identity); } }