예제 #1
0
        static void Main()
        {
            bool shadows = AskForRealtimeShadows();

            DriverType?driverType = AskForDriver();

            if (!driverType.HasValue)
            {
                return;
            }

            IrrlichtDevice device = IrrlichtDevice.CreateDevice(driverType.Value, new Dimension2Di(640, 480), 16, false, shadows);

            if (device == null)
            {
                return;
            }

            VideoDriver  driver = device.VideoDriver;
            SceneManager smgr   = device.SceneManager;

            AnimatedMesh mesh = smgr.GetMesh("../../media/room.3ds");

            smgr.MeshManipulator.MakePlanarTextureMapping(mesh.GetMesh(0), 0.004f);

            SceneNode node = smgr.AddAnimatedMeshSceneNode(mesh);

            node.SetMaterialTexture(0, driver.GetTexture("../../media/wall.jpg"));
            node.GetMaterial(0).SpecularColor = new Color(0);

            mesh = smgr.AddHillPlaneMesh("myHill",
                                         new Dimension2Df(20, 20),
                                         new Dimension2Di(40, 40), null, 0,
                                         new Dimension2Df(0),
                                         new Dimension2Df(10, 10));

            node          = smgr.AddWaterSurfaceSceneNode(mesh.GetMesh(0), 3.0f, 300.0f, 30.0f);
            node.Position = new Vector3Df(0, 7, 0);

            node.SetMaterialTexture(0, driver.GetTexture("../../media/stones.jpg"));
            node.SetMaterialTexture(1, driver.GetTexture("../../media/water.jpg"));

            node.SetMaterialType(MaterialType.Reflection2Layer);

            // create light

            node = smgr.AddLightSceneNode(null, new Vector3Df(0), new Colorf(1.0f, 0.6f, 0.7f, 1.0f), 800);
            SceneNodeAnimator anim = smgr.CreateFlyCircleAnimator(new Vector3Df(0, 150, 0), 250);

            node.AddAnimator(anim);
            anim.Drop();

            // attach billboard to light

            node = smgr.AddBillboardSceneNode(node, new Dimension2Df(50, 50));
            node.SetMaterialFlag(MaterialFlag.Lighting, false);
            node.SetMaterialType(MaterialType.TransparentAddColor);
            node.SetMaterialTexture(0, driver.GetTexture("../../media/particlewhite.bmp"));

            // create a particle system

            ParticleSystemSceneNode ps = smgr.AddParticleSystemSceneNode(false);

            if (ps != null)
            {
                ParticleEmitter em = ps.CreateBoxEmitter(
                    new AABBox(-7, 0, -7, 7, 1, 7),   // emitter size
                    new Vector3Df(0.0f, 0.06f, 0.0f), // initial direction
                    80, 100,                          // emit rate
                    new Color(255, 255, 255, 0),      // darkest color
                    new Color(255, 255, 255, 0),      // brightest color
                    800, 2000, 0,                     // min and max age, angle
                    new Dimension2Df(10.0f),          // min size
                    new Dimension2Df(20.0f));         // max size

                ps.Emitter = em;                      // this grabs the emitter
                em.Drop();                            // so we can drop it here without deleting it

                ParticleAffector paf = ps.CreateFadeOutParticleAffector();

                ps.AddAffector(paf);                 // same goes for the affector
                paf.Drop();

                ps.Position = new Vector3Df(-70, 60, 40);
                ps.Scale    = new Vector3Df(2);
                ps.SetMaterialFlag(MaterialFlag.Lighting, false);
                ps.SetMaterialFlag(MaterialFlag.ZWrite, false);
                ps.SetMaterialTexture(0, driver.GetTexture("../../media/fire.bmp"));
                ps.SetMaterialType(MaterialType.TransparentAddColor);
            }

            VolumeLightSceneNode n = smgr.AddVolumeLightSceneNode(null, -1,
                                                                  32,                          // Subdivisions on U axis
                                                                  32,                          // Subdivisions on V axis
                                                                  new Color(255, 255, 255, 0), // foot color
                                                                  new Color(0, 0, 0, 0));      // tail color

            if (n != null)
            {
                n.Scale    = new Vector3Df(56);
                n.Position = new Vector3Df(-120, 50, 40);

                // load textures for animation
                List <Texture> textures = new List <Texture>();
                for (int i = 7; i > 0; i--)
                {
                    string s = string.Format("../../media/portal{0}.bmp", i);
                    textures.Add(driver.GetTexture(s));
                }

                // create texture animator
                SceneNodeAnimator glow = smgr.CreateTextureAnimator(textures, 0.150f);

                // add the animator
                n.AddAnimator(glow);

                // drop the animator because it was created with a create() function
                glow.Drop();
            }

            // add animated character

            mesh = smgr.GetMesh("../../media/dwarf.x");
            AnimatedMeshSceneNode anode = smgr.AddAnimatedMeshSceneNode(mesh);

            anode.Position       = new Vector3Df(-50, 20, -60);
            anode.AnimationSpeed = 15;

            // add shadow
            anode.AddShadowVolumeSceneNode();
            smgr.ShadowColor = new Color(0, 0, 0, 150);

            // make the model a little bit bigger and normalize its normals
            // because of the scaling, for correct lighting
            anode.Scale = new Vector3Df(2);
            anode.SetMaterialFlag(MaterialFlag.NormalizeNormals, true);

            CameraSceneNode camera = smgr.AddCameraSceneNodeFPS();

            camera.Position = new Vector3Df(-50, 50, -150);

            // disable mouse cursor
            device.CursorControl.Visible = false;

            int lastFPS = -1;

            while (device.Run())
            {
                if (device.WindowActive)
                {
                    driver.BeginScene(ClearBufferFlag.All, new Color(0));
                    smgr.DrawAll();
                    driver.EndScene();

                    int fps = driver.FPS;
                    if (lastFPS != fps)
                    {
                        device.SetWindowCaption(String.Format(
                                                    "SpecialFX example - Irrlicht Engine [{0}] fps: {1}",
                                                    driver.Name, fps));

                        lastFPS = fps;
                    }
                }
            }

            device.Drop();
        }
예제 #2
0
        static void Main()
        {
            DriverType?driverType = AskForDriver();

            if (!driverType.HasValue)
            {
                return;
            }

            IrrlichtDevice device = IrrlichtDevice.CreateDevice(driverType.Value, new Dimension2Di(640, 480));

            if (device == null)
            {
                return;
            }

            VideoDriver    driver = device.VideoDriver;
            SceneManager   smgr   = device.SceneManager;
            GUIEnvironment env    = device.GUIEnvironment;

            driver.SetTextureCreationFlag(TextureCreationFlag.Always32Bit, true);

            // add irrlicht logo
            env.AddImage(driver.GetTexture("../../media/irrlichtlogoalpha2.tga"), new Vector2Di(10));

            // add camera
            CameraSceneNode camera = smgr.AddCameraSceneNodeFPS();

            camera.Position = new Vector3Df(-200, 200, -200);

            // disable mouse cursor
            device.CursorControl.Visible = false;

            driver.Fog = new Fog(new Color(138, 125, 81, 0), FogType.Linear, 250, 1000, 0.003f, true, false);

            AnimatedMesh roomMesh = smgr.GetMesh("../../media/room.3ds");
            SceneNode    room     = null;
            SceneNode    earth    = null;

            if (roomMesh != null)
            {
                // the room mesh doesn't have proper texture mapping on the floor,
                // so we can recreate them on runtime
                smgr.MeshManipulator.MakePlanarTextureMapping(roomMesh.GetMesh(0), 0.003f);

                Texture normalMap = driver.GetTexture("../../media/rockwall_height.bmp");
                if (normalMap != null)
                {
                    driver.MakeNormalMapTexture(normalMap, 9.0f);
                }

                Mesh tangentMesh = smgr.MeshManipulator.CreateMeshWithTangents(roomMesh.GetMesh(0));
                room = smgr.AddMeshSceneNode(tangentMesh);
                room.SetMaterialTexture(0, driver.GetTexture("../../media/rockwall.jpg"));
                room.SetMaterialTexture(1, normalMap);
                room.GetMaterial(0).SpecularColor = new Color(0);
                room.GetMaterial(0).Shininess     = 0.0f;
                room.SetMaterialFlag(MaterialFlag.Fog, true);
                room.SetMaterialType(MaterialType.ParallaxMapSolid);
                room.GetMaterial(0).MaterialTypeParam = 1.0f / 64.0f; // adjust height for parallax effect

                tangentMesh.Drop();                                   // drop mesh because we created it with a "create" call
            }

            // add earth sphere
            AnimatedMesh earthMesh = smgr.GetMesh("../../media/earth.x");

            if (earthMesh != null)
            {
                // perform various task with the mesh manipulator
                MeshManipulator manipulator = smgr.MeshManipulator;

                // create mesh copy with tangent informations from original earth.x mesh
                Mesh tangentSphereMesh = manipulator.CreateMeshWithTangents(earthMesh.GetMesh(0));

                // set the alpha value of all vertices to 200
                manipulator.SetVertexColorAlpha(tangentSphereMesh, 200);

                // scale the mesh by factor 50
                Matrix m = new Matrix();
                m.Scale = new Vector3Df(50);
                manipulator.Transform(tangentSphereMesh, m);

                earth          = smgr.AddMeshSceneNode(tangentSphereMesh);
                earth.Position = new Vector3Df(-70, 130, 45);

                // load heightmap, create normal map from it and set it
                Texture earthNormalMap = driver.GetTexture("../../media/earthbump.jpg");
                if (earthNormalMap != null)
                {
                    driver.MakeNormalMapTexture(earthNormalMap, 20);
                    earth.SetMaterialTexture(1, earthNormalMap);
                    earth.SetMaterialType(MaterialType.NormalMapTransparentVertexAlpha);
                }

                // adjust material settings
                earth.SetMaterialFlag(MaterialFlag.Fog, true);

                // add rotation animator
                SceneNodeAnimator anim = smgr.CreateRotationAnimator(new Vector3Df(0, 0.1f, 0));
                earth.AddAnimator(anim);
                anim.Drop();

                // drop mesh because we created it with a "create" call.
                tangentSphereMesh.Drop();
            }

            // add light 1 (more green)
            LightSceneNode light1 = smgr.AddLightSceneNode(null, new Vector3Df(), new Colorf(0.5f, 1.0f, 0.5f, 0.0f), 800);

            if (light1 != null)
            {
                light1.DebugDataVisible = DebugSceneType.BBox;

                // add fly circle animator to light
                SceneNodeAnimator anim = smgr.CreateFlyCircleAnimator(new Vector3Df(50, 300, 0), 190.0f, -0.003f);
                light1.AddAnimator(anim);
                anim.Drop();

                // attach billboard to the light
                BillboardSceneNode bill = smgr.AddBillboardSceneNode(light1, new Dimension2Df(60, 60));
                bill.SetMaterialFlag(MaterialFlag.Lighting, false);
                bill.SetMaterialFlag(MaterialFlag.ZWrite, false);
                bill.SetMaterialType(MaterialType.TransparentAddColor);
                bill.SetMaterialTexture(0, driver.GetTexture("../../media/particlegreen.jpg"));
            }

            // add light 2 (red)
            SceneNode light2 = smgr.AddLightSceneNode(null, new Vector3Df(), new Colorf(1.0f, 0.2f, 0.2f, 0.0f), 800.0f);

            if (light2 != null)
            {
                // add fly circle animator to light
                SceneNodeAnimator anim = smgr.CreateFlyCircleAnimator(new Vector3Df(0, 150, 0), 200.0f, 0.001f, new Vector3Df(0.2f, 0.9f, 0.0f));
                light2.AddAnimator(anim);
                anim.Drop();

                // attach billboard to light
                SceneNode bill = smgr.AddBillboardSceneNode(light2, new Dimension2Df(120, 120));
                bill.SetMaterialFlag(MaterialFlag.Lighting, false);
                bill.SetMaterialFlag(MaterialFlag.ZWrite, false);
                bill.SetMaterialType(MaterialType.TransparentAddColor);
                bill.SetMaterialTexture(0, driver.GetTexture("../../media/particlered.bmp"));

                // add particle system
                ParticleSystemSceneNode ps = smgr.AddParticleSystemSceneNode(false, light2);

                // create and set emitter
                ParticleEmitter em = ps.CreateBoxEmitter(
                    new AABBox(-3, 0, -3, 3, 1, 3),
                    new Vector3Df(0.0f, 0.03f, 0.0f),
                    80, 100,
                    new Color(255, 255, 255, 10), new Color(255, 255, 255, 10),
                    400, 1100);

                em.MinStartSize = new Dimension2Df(30.0f, 40.0f);
                em.MaxStartSize = new Dimension2Df(30.0f, 40.0f);

                ps.Emitter = em;
                em.Drop();

                // create and set affector
                ParticleAffector paf = ps.CreateFadeOutParticleAffector();
                ps.AddAffector(paf);
                paf.Drop();

                // adjust some material settings
                ps.SetMaterialFlag(MaterialFlag.Lighting, false);
                ps.SetMaterialFlag(MaterialFlag.ZWrite, false);
                ps.SetMaterialTexture(0, driver.GetTexture("../../media/fireball.bmp"));
                ps.SetMaterialType(MaterialType.TransparentAddColor);
            }

            MyEventReceiver receiver = new MyEventReceiver(device, room, earth);

            int lastFPS = -1;

            while (device.Run())
            {
                if (device.WindowActive)
                {
                    driver.BeginScene(ClearBufferFlag.All, new Color(0));

                    smgr.DrawAll();
                    env.DrawAll();

                    driver.EndScene();

                    int fps = driver.FPS;
                    if (lastFPS != fps)
                    {
                        device.SetWindowCaption(String.Format(
                                                    "Per pixel lighting example - Irrlicht Engine [{0}] fps: {1}",
                                                    driver.Name, fps));

                        lastFPS = fps;
                    }
                }
            }

            device.Drop();
        }
예제 #3
0
        static void Main()
        {
            DriverType?driverType = AskForDriver();

            if (!driverType.HasValue)
            {
                return;
            }

            IrrlichtDevice device = IrrlichtDevice.CreateDevice(driverType.Value, new Dimension2Di(640, 480));

            if (device == null)
            {
                return;
            }

            VideoDriver  driver = device.VideoDriver;
            SceneManager smgr   = device.SceneManager;

            device.FileSystem.AddFileArchive("../../media/map-20kdm2.pk3");

            AnimatedMesh  q3levelmesh = smgr.GetMesh("20kdm2.bsp");
            MeshSceneNode q3node      = null;

            // The Quake mesh is pickable, but doesn't get highlighted.
            if (q3levelmesh != null)
            {
                q3node = smgr.AddOctreeSceneNode(q3levelmesh.GetMesh(0), null, IDFlag_IsPickable);
            }

            TriangleSelector selector = null;

            if (q3node != null)
            {
                q3node.Position         = new Vector3Df(-1350, -130, -1400);
                selector                = smgr.CreateOctreeTriangleSelector(q3node.Mesh, q3node, 128);
                q3node.TriangleSelector = selector;
                // We're not done with this selector yet, so don't drop it.
            }

            // Set a jump speed of 3 units per second, which gives a fairly realistic jump
            // when used with the gravity of (0, -1000, 0) in the collision response animator.
            CameraSceneNode camera = smgr.AddCameraSceneNodeFPS(null, 100.0f, 0.3f, ID_IsNotPickable, null, true, 3.0f);

            camera.Position = new Vector3Df(50, 50, -60);
            camera.Target   = new Vector3Df(-70, 30, -60);

            if (selector != null)
            {
                SceneNodeAnimator anim = smgr.CreateCollisionResponseAnimator(
                    selector,
                    camera,
                    new Vector3Df(30, 50, 30),
                    new Vector3Df(0, -1000, 0),
                    new Vector3Df(0, 30, 0));

                selector.Drop();             // As soon as we're done with the selector, drop it.
                camera.AddAnimator(anim);
                anim.Drop();                 // And likewise, drop the animator when we're done referring to it.
            }

            // Now I create three animated characters which we can pick, a dynamic light for
            // lighting them, and a billboard for drawing where we found an intersection.

            // First, let's get rid of the mouse cursor. We'll use a billboard to show what we're looking at.
            device.CursorControl.Visible = false;

            // Add the billboard.
            BillboardSceneNode bill = smgr.AddBillboardSceneNode();

            bill.SetMaterialType(MaterialType.TransparentAddColor);
            bill.SetMaterialTexture(0, driver.GetTexture("../../media/particle.bmp"));
            bill.SetMaterialFlag(MaterialFlag.Lighting, false);
            bill.SetMaterialFlag(MaterialFlag.ZBuffer, false);
            bill.SetSize(20, 20, 20);
            bill.ID = ID_IsNotPickable;             // This ensures that we don't accidentally ray-pick it

            AnimatedMeshSceneNode node = null;

            // Add an MD2 node, which uses vertex-based animation.
            node          = smgr.AddAnimatedMeshSceneNode(smgr.GetMesh("../../media/faerie.md2"), null, IDFlag_IsPickable | IDFlag_IsHighlightable);
            node.Position = new Vector3Df(-90, -15, -140); // Put its feet on the floor.
            node.Scale    = new Vector3Df(1.6f);           // Make it appear realistically scaled
            node.SetMD2Animation(AnimationTypeMD2.Point);
            node.AnimationSpeed = 20.0f;
            node.GetMaterial(0).SetTexture(0, driver.GetTexture("../../media/faerie2.bmp"));
            node.GetMaterial(0).Lighting         = true;
            node.GetMaterial(0).NormalizeNormals = true;

            // Now create a triangle selector for it.  The selector will know that it
            // is associated with an animated node, and will update itself as necessary.
            selector = smgr.CreateTriangleSelector(node);
            node.TriangleSelector = selector;
            selector.Drop();             // We're done with this selector, so drop it now.

            // And this B3D file uses skinned skeletal animation.
            node                = smgr.AddAnimatedMeshSceneNode(smgr.GetMesh("../../media/ninja.b3d"), null, IDFlag_IsPickable | IDFlag_IsHighlightable);
            node.Scale          = new Vector3Df(10);
            node.Position       = new Vector3Df(-75, -66, -80);
            node.Rotation       = new Vector3Df(0, 90, 0);
            node.AnimationSpeed = 8.0f;
            node.GetMaterial(0).NormalizeNormals = true;
            // Just do the same as we did above.
            selector = smgr.CreateTriangleSelector(node);
            node.TriangleSelector = selector;
            selector.Drop();

            // This X files uses skeletal animation, but without skinning.
            node                  = smgr.AddAnimatedMeshSceneNode(smgr.GetMesh("../../media/dwarf.x"), null, IDFlag_IsPickable | IDFlag_IsHighlightable);
            node.Position         = new Vector3Df(-70, -66, -30); // Put its feet on the floor.
            node.Rotation         = new Vector3Df(0, -90, 0);     // And turn it towards the camera.
            node.AnimationSpeed   = 20.0f;
            selector              = smgr.CreateTriangleSelector(node);
            node.TriangleSelector = selector;
            selector.Drop();

            // And this mdl file uses skinned skeletal animation.
            node          = smgr.AddAnimatedMeshSceneNode(smgr.GetMesh("../../media/yodan.mdl"), null, IDFlag_IsPickable | IDFlag_IsHighlightable);
            node.Position = new Vector3Df(-90, -25, 20);
            node.Scale    = new Vector3Df(0.8f);
            node.GetMaterial(0).Lighting = true;
            node.AnimationSpeed          = 20.0f;

            // Just do the same as we did above.
            selector = smgr.CreateTriangleSelector(node);
            node.TriangleSelector = selector;
            selector.Drop();

            // Add a light, so that the unselected nodes aren't completely dark.
            LightSceneNode light = smgr.AddLightSceneNode(null, new Vector3Df(-60, 100, 400), new Colorf(1.0f, 1.0f, 1.0f), 600.0f);

            light.ID = ID_IsNotPickable;             // Make it an invalid target for selection.

            // Remember which scene node is highlighted
            SceneNode             highlightedSceneNode = null;
            SceneCollisionManager collMan = smgr.SceneCollisionManager;
            int lastFPS = -1;

            // draw the selection triangle only as wireframe
            Material material = new Material();

            material.Lighting  = false;
            material.Wireframe = true;

            while (device.Run())
            {
                if (device.WindowActive)
                {
                    driver.BeginScene(ClearBufferFlag.All, new Color(0));
                    smgr.DrawAll();

                    // Unlight any currently highlighted scene node
                    if (highlightedSceneNode != null)
                    {
                        highlightedSceneNode.SetMaterialFlag(MaterialFlag.Lighting, true);
                        highlightedSceneNode = null;
                    }

                    // All intersections in this example are done with a ray cast out from the camera to
                    // a distance of 1000.  You can easily modify this to check (e.g.) a bullet
                    // trajectory or a sword's position, or create a ray from a mouse click position using
                    // collMan.GetRayFromScreenCoordinates()
                    Line3Df ray = new Line3Df();
                    ray.Start = camera.Position;
                    ray.End   = ray.Start + (camera.Target - ray.Start).Normalize() * 1000.0f;

                    // This call is all you need to perform ray/triangle collision on every scene node
                    // that has a triangle selector, including the Quake level mesh.  It finds the nearest
                    // collision point/triangle, and returns the scene node containing that point.
                    // Irrlicht provides other types of selection, including ray/triangle selector,
                    // ray/box and ellipse/triangle selector, plus associated helpers.
                    // See the methods of ISceneCollisionManager
                    SceneNode selectedSceneNode =
                        collMan.GetSceneNodeAndCollisionPointFromRay(
                            ray,
                            out Vector3Df intersection,             // This will be the position of the collision
                            out Triangle3Df hitTriangle,            // This will be the triangle hit in the collision
                            IDFlag_IsPickable);                     // This ensures that only nodes that we have set up to be pickable are considered

                    // If the ray hit anything, move the billboard to the collision position
                    // and draw the triangle that was hit.
                    if (selectedSceneNode != null)
                    {
                        bill.Position = intersection;

                        // We need to reset the transform before doing our own rendering.
                        driver.SetTransform(TransformationState.World, Matrix.Identity);
                        driver.SetMaterial(material);
                        driver.Draw3DTriangle(hitTriangle, new Color(255, 0, 0));

                        // We can check the flags for the scene node that was hit to see if it should be
                        // highlighted. The animated nodes can be highlighted, but not the Quake level mesh
                        if ((selectedSceneNode.ID & IDFlag_IsHighlightable) == IDFlag_IsHighlightable)
                        {
                            highlightedSceneNode = selectedSceneNode;

                            // Highlighting in this case means turning lighting OFF for this node,
                            // which means that it will be drawn with full brightness.
                            highlightedSceneNode.SetMaterialFlag(MaterialFlag.Lighting, false);
                        }
                    }

                    // We're all done drawing, so end the scene.
                    driver.EndScene();

                    int fps = driver.FPS;
                    if (lastFPS != fps)
                    {
                        device.SetWindowCaption(String.Format(
                                                    "Collision detection example - Irrlicht Engine [{0}] fps: {1}",
                                                    driver.Name, fps));

                        lastFPS = fps;
                    }
                }
            }

            device.Drop();
        }