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);
            }
        }
Exemple #2
0
        void CreateScene()
        {
            var cache = GetSubsystem <ResourceCache>();

            scene = new Scene();

            // 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(new BoundingBox(-1000.0f, 1000.0f));
            zone.AmbientColor = new Color(0.15f, 0.15f, 0.15f);
            zone.FogColor     = new Color(0.5f, 0.5f, 0.7f);
            zone.FogStart     = 100.0f;
            zone.FogEnd       = 300.0f;

            // Create a directional light to the world. Enable cascaded shadows on it
            Node lightNode = scene.CreateChild("DirectionalLight");

            lightNode.SetDirection(new Vector3(0.6f, -1.0f, 0.8f));
            Light light = lightNode.CreateComponent <Light>();

            light.LightType   = LightType.LIGHT_DIRECTIONAL;
            light.CastShadows = true;
            light.ShadowBias  = new 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.ShadowCascade = new 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.Position = new Vector3(0.0f, -0.5f, 0.0f);
                floorNode.Scale    = new Vector3(500.0f, 1.0f, 500.0f);
                StaticModel floorObject = floorNode.CreateComponent <StaticModel>();
                floorObject.Model = cache.Get <Model>("Models/Box.mdl");
                floorObject.SetMaterial(cache.Get <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, Vector3.Zero, Quaternion.Identity);
            }

            {
                // Create static mushrooms with triangle mesh collision
                const uint numMushrooms = 50;
                for (uint i = 0; i < numMushrooms; ++i)
                {
                    Node mushroomNode = scene.CreateChild("Mushroom");
                    mushroomNode.Position = new Vector3(NextRandom(400.0f) - 200.0f, 0.0f, NextRandom(400.0f) - 200.0f);
                    mushroomNode.Rotation = new Quaternion(0.0f, NextRandom(360.0f), 0.0f);
                    mushroomNode.SetScale(5.0f + NextRandom(5.0f));
                    StaticModel mushroomObject = mushroomNode.CreateComponent <StaticModel>();
                    mushroomObject.Model = (cache.Get <Model>("Models/Mushroom.mdl"));
                    mushroomObject.SetMaterial(cache.Get <Material>("Materials/Mushroom.xml"));
                    mushroomObject.CastShadows = true;

                    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.Model, 0, Vector3.One, Vector3.Zero, Quaternion.Identity);
                }
            }

            {
                // Create a large amount of falling physics objects
                const uint numObjects = 1000;
                for (uint i = 0; i < numObjects; ++i)
                {
                    Node boxNode = scene.CreateChild("Box");
                    boxNode.Position = new Vector3(0.0f, i * 2.0f + 100.0f, 0.0f);
                    StaticModel boxObject = boxNode.CreateComponent <StaticModel>();
                    boxObject.Model = cache.Get <Model>("Models/Box.mdl");
                    boxObject.SetMaterial(cache.Get <Material>("Materials/StoneSmall.xml"));
                    boxObject.CastShadows = true;

                    // Give the RigidBody mass to make it movable and also adjust friction
                    RigidBody body = boxNode.CreateComponent <RigidBody>();
                    body.Mass     = 1.0f;
                    body.Friction = 1.0f;
                    // Disable collision event signaling to reduce CPU load of the physics simulation
                    body.CollisionEventMode = CollisionEventMode.COLLISION_NEVER;
                    CollisionShape shape = boxNode.CreateComponent <CollisionShape>();
                    shape.SetBox(Vector3.One, Vector3.Zero, Quaternion.Identity);
                }
            }

            // 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();
            Camera camera = CameraNode.CreateComponent <Camera>();

            camera.FarClip = 300.0f;

            // Set an initial position for the camera scene node above the floor
            CameraNode.Position = new Vector3(0.0f, 3.0f, -20.0f);
        }
Exemple #3
0
        void CreateScene()
        {
            var cache = ResourceCache;

            scene = new Scene();

            // Create scene subsystem components
            scene.CreateComponent <Octree>();
            physicsWorld = 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 = 300.0f;
            Renderer.SetViewport(0, new Viewport(Context, scene, camera, null));

            // 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     = 100.0f;
            zone.FogEnd       = 300.0f;
            zone.SetBoundingBox(new BoundingBox(-1000.0f, 1000.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.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 the floor object
            Node floorNode = scene.CreateChild("Floor");

            floorNode.Position = new Vector3(0.0f, -0.5f, 0.0f);
            floorNode.Scale    = new Vector3(200.0f, 1.0f, 200.0f);
            StaticModel sm = floorNode.CreateComponent <StaticModel>();

            sm.Model = cache.GetModel("Models/Box.mdl");
            sm.SetMaterial(cache.GetMaterial("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.CollisionLayer = 2;
            CollisionShape shape = floorNode.CreateComponent <CollisionShape>();

            shape.SetBox(Vector3.One, Vector3.Zero, Quaternion.Identity);

            // Create mushrooms of varying sizes
            const uint numMushrooms = 60;

            for (uint i = 0; i < numMushrooms; ++i)
            {
                Node objectNode = scene.CreateChild("Mushroom");
                objectNode.Position = new Vector3(NextRandom(180.0f) - 90.0f, 0.0f, NextRandom(180.0f) - 90.0f);
                objectNode.Rotation = new Quaternion(0.0f, NextRandom(360.0f), 0.0f);
                objectNode.SetScale(2.0f + NextRandom(5.0f));
                StaticModel o = objectNode.CreateComponent <StaticModel>();
                o.Model = cache.GetModel("Models/Mushroom.mdl");
                o.SetMaterial(cache.GetMaterial("Materials/Mushroom.xml"));
                o.CastShadows = true;

                body = objectNode.CreateComponent <RigidBody>();
                body.CollisionLayer = 2;
                shape = objectNode.CreateComponent <CollisionShape>();
                shape.SetTriangleMesh(o.Model, 0, Vector3.One, Vector3.Zero, Quaternion.Identity);
            }

            // Create movable boxes. Let them fall from the sky at first
            const uint numBoxes = 100;

            for (uint i = 0; i < numBoxes; ++i)
            {
                float scale = NextRandom(2.0f) + 0.5f;

                Node objectNode = scene.CreateChild("Box");
                objectNode.Position = new Vector3(NextRandom(180.0f) - 90.0f, NextRandom(10.0f) + 10.0f, NextRandom(180.0f) - 90.0f);
                objectNode.Rotation = new Quaternion(NextRandom(360.0f), NextRandom(360.0f), NextRandom(360.0f));
                objectNode.SetScale(scale);
                StaticModel o = objectNode.CreateComponent <StaticModel>();
                o.Model = cache.GetModel("Models/Box.mdl");
                o.SetMaterial(cache.GetMaterial("Materials/Stone.xml"));
                o.CastShadows = true;

                body = objectNode.CreateComponent <RigidBody>();
                body.CollisionLayer = 2;
                // Bigger boxes will be heavier and harder to move
                body.Mass = scale * 2.0f;
                shape     = objectNode.CreateComponent <CollisionShape>();
                shape.SetBox(Vector3.One, Vector3.Zero, Quaternion.Identity);
            }
        }