Пример #1
0
        public void Fire(Vector3Df position, Vector3Df direction, uint time)
        {
            Shot s = new Shot();

            s.direction = direction;

            Vector3Df e = position + s.direction * worldInfinity;
            Line3Df   l = new Line3Df(position, e);

            Vector3Df   cv;
            Triangle3Df ct;
            SceneNode   cn;

            if (sceneManager.SceneCollisionManager.GetCollisionPoint(l, worldTriangles, out cv, out ct, out cn))
            {
                e = cv;
            }

            s.deathTime = time + (uint)((e - position).Length / shotSpeed);

            s.node = sceneManager.AddSphereSceneNode(10);
            s.node.SetMaterialFlag(MaterialFlag.Lighting, false);
            sceneManager.MeshManipulator.SetVertexColors(((MeshSceneNode)s.node).Mesh, Color.OpaqueWhite);

            s.node.AddAnimator(sceneManager.CreateFlyStraightAnimator(position, e, (s.deathTime - time) / 1000.0f));
            s.node.AnimatorList[0].Drop();

            sceneManager.AddLightSceneNode(s.node);

            shots.Add(s);
        }
Пример #2
0
        public void MouseClick(int x, int y, bool isRight)
        {
            if (m_state != State.Playing)
            {
                return;
            }

            Vector2Di m = new Vector2Di(x, y);
            Line3Df   l = m_device.SceneManager.SceneCollisionManager.GetRayFromScreenCoordinates(m);
            SceneNode n = m_device.SceneManager.SceneCollisionManager.GetSceneNodeFromRayBB(l, 0x10000, m_root);

            if (n != null && n.ID >= 0x10000)
            {
                int i = n.ID - 0x10000;

                if (isRight)
                {
                    flagCell(m_board[i]);
                }
                else
                {
                    revealCell(m_board[i]);
                }
            }
        }
Пример #3
0
		public void Fire(Vector3Df position, Vector3Df direction, uint time)
		{
			Shot s = new Shot();
			s.direction = direction;

			Vector3Df e = position + s.direction * worldInfinity;
			Line3Df l = new Line3Df(position, e);

			Vector3Df cv;
			Triangle3Df ct;
			SceneNode cn;
			if (sceneManager.SceneCollisionManager.GetCollisionPoint(l, worldTriangles, out cv, out ct, out cn))
				e = cv;

			s.deathTime = time + (uint)((e - position).Length / shotSpeed);

			s.node = sceneManager.AddSphereSceneNode(10);
			s.node.SetMaterialFlag(MaterialFlag.Lighting, false);
			sceneManager.MeshManipulator.SetVertexColors(((MeshSceneNode)s.node).Mesh, Color.OpaqueWhite);

			s.node.AddAnimator(sceneManager.CreateFlyStraightAnimator(position, e, (s.deathTime - time) / 1000.0f));
			s.node.AnimatorList[0].Drop();

			sceneManager.AddLightSceneNode(s.node);

			shots.Add(s);
		}
Пример #4
0
        static bool device_OnEvent(Event evnt)
        {
            if (evnt.Type == EventType.Mouse &&
                evnt.Mouse.Type == MouseEventType.RightDown)
            {
                Vector3Df   v;
                Triangle3Df t;
                SceneNode   n;

                Line3Df l = scene.SceneCollisionManager.GetRayFromScreenCoordinates(new Vector2Di(evnt.Mouse.X, evnt.Mouse.Y));
                if (scene.SceneCollisionManager.GetCollisionPoint(l, sphere.TriangleSelector, out v, out t, out n))
                {
                    path.AddPoint(v);
                    return(true);
                }
            }

            if (evnt.Type == EventType.Key)
            {
                switch (evnt.Key.Key)
                {
                case KeyCode.Left:
                    camera.Inclination++;
                    return(true);

                case KeyCode.Right:
                    camera.Inclination--;
                    return(true);

                case KeyCode.Up:
                    camera.Azimuth--;
                    return(true);

                case KeyCode.Down:
                    camera.Azimuth++;
                    return(true);

                case KeyCode.KeyC:
                    path.Clear();
                    return(true);

                //case KeyCode.KeyS:
                //    path.Save("../../media/SphereCameraPath.xml");
                //    return true;

                case KeyCode.KeyR:
                    path.Load("../../media/SphereCameraPath.xml");
                    return(true);
                }
            }

            return(false);
        }
Пример #5
0
        public Triangle3Df interpolateFrom2D(Vector2Di input)
        {
            //We can assume two things:
            //That the hand will be considered in front of the object
            //And that the hand will always be orbiting around the object
            //So we calculate based off of sin and cos and relative positions
            SceneCollisionManager collisionManager = device.SceneManager.SceneCollisionManager;
            Line3Df ray = device.SceneManager.SceneCollisionManager.GetRayFromScreenCoordinates(input);

            //calcLine.End = calcLine.End.Normalize();
            //calcLine.End *= new Vector3Df(20);
            // Tracks the current intersection point with the level or a mesh
            Vector3Df intersection;
            // Used to show with triangle has been hit
            Triangle3Df hitTriangle;

            SceneNode selectedSceneNode =
                device.SceneManager.SceneCollisionManager.GetSceneNodeAndCollisionPointFromRay(
                    ray,
                    out intersection, // This will be the position of the collision
                    out hitTriangle); // This ensures that only nodes that we have set up to be pickable are considered
            SceneNode highlightedSceneNode = null;

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

                // We need to reset the transform before doing our own rendering.
                device.VideoDriver.SetTransform(TransformationState.World, new Matrix());
                //device.VideoDriver.SetMaterial(material);
                device.VideoDriver.Draw3DTriangle(hitTriangle, new Color(255, 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

                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);
            }
            return(hitTriangle);
        }
        private void irrlichtPanel_MouseClick(object sender, MouseEventArgs e)
        {
            // need to have a click plus the ctrl key down
            if (pickKeyDown)
            {
                ViewFrustum f = smgr.ActiveCamera.ViewFrustum;

                Vector3Df farLeftUp   = f.FarLeftUp;
                Vector3Df lefttoright = f.FarRightUp - farLeftUp;
                Vector3Df uptodown    = f.FarLeftDown - farLeftUp;

                float dx = e.X / (float)viewPort.Width;
                float dy = e.Y / (float)viewPort.Height;

                Line3Df   ray        = new Line3Df(f.CameraPosition, farLeftUp + (lefttoright * dx) + (uptodown * dy));
                SceneNode pickedNode = smgr.SceneCollisionManager.GetSceneNodeFromRayBB(ray);

                if (pickedNode != null)
                {
                    RenderMessage message = new RenderMessage(MessageType.HIGHLIGHT_NODE, pickedNode);
                    commandQueue.Enqueue(message);

                    propertiesDlg.SetProperties(pickedNode);
                    if (!propertiesDlg.Visible)
                    {
                        propertiesDlg.Show(this);
                    }

                    if (backgroundSearcher.IsBusy)
                    {
                        backgroundSearcher.CancelAsync();
                    }
                    backgroundSearcher.RunWorkerAsync(pickedNode.ID);
                }
            }
        }
Пример #7
0
        static bool device_OnEvent(Event evnt)
        {
            if (evnt.Type == EventType.Mouse &&
                evnt.Mouse.Type == MouseEventType.Move)
            {
                Vector2Di m = new Vector2Di(evnt.Mouse.X, evnt.Mouse.Y);
                Line3Df   l = device.SceneManager.SceneCollisionManager.GetRayFromScreenCoordinates(m);
                Plane3Df  p = new Plane3Df(new Vector3Df(0, 0, 0), new Vector3Df(100, 0, 0), new Vector3Df(0, 0, 100));
                Vector3Df i = p.GetIntersectionWithLimitedLine(l.Start, l.End);
                if (i != null)
                {
                    camera.Target = game.CenterOfTheBoard + new Vector3Df(
                        (m.Y - device.VideoDriver.ScreenSize.Height / 2) / 100.0f,
                        0,
                        (m.X - device.VideoDriver.ScreenSize.Width / 2) / 100.0f);

                    i.Y           += 25;           // we want light to be a little bit above
                    light.Position = i;
                }
            }

            if (window == null &&
                evnt.Type == EventType.Mouse &&
                (evnt.Mouse.Type == MouseEventType.LeftDown || evnt.Mouse.Type == MouseEventType.RightDown))
            {
                text.Visible = false;                 // if user started to play - remove the gui text
                game.MouseClick(evnt.Mouse.X, evnt.Mouse.Y, evnt.Mouse.Type == MouseEventType.RightDown);

                if (game.StateOfTheGame != Game.State.Playing)
                {
                    text.Visible = true;
                    text.Text    = game.StateOfTheGame == Game.State.Won ? TextWon : TextLost;
                }

                return(true);
            }

            if (evnt.Type == EventType.Key &&
                evnt.Key.PressedDown &&
                evnt.Key.Key == KeyCode.Esc)
            {
                if (window != null)
                {
                    window.Remove();
                    window = null;
                    return(true);
                }

                GUIEnvironment gui = device.GUIEnvironment;

                window = gui.AddWindow(new Recti(100, 100, 400, 400), true, "GAME MENU");

                gui.AddButton(new Recti(20, 40, window.ClientRect.Width - 20, 60), window, 1510, "NEW GAME 5x5");
                gui.AddButton(new Recti(20, 60, window.ClientRect.Width - 20, 80), window, 1520, "NEW GAME 10x10");
                gui.AddButton(new Recti(20, 80, window.ClientRect.Width - 20, 100), window, 1530, "NEW GAME 15x15");
                gui.AddButton(new Recti(20, 100, window.ClientRect.Width - 20, 120), window, 1540, "NEW GAME 20x20");

                gui.AddCheckBox(optionShadows, new Recti(20, 140, window.ClientRect.Width - 20, 160), "SHOW REALTIME SHADOWS", window, 1710);
                gui.AddCheckBox(optionBackground, new Recti(20, 160, window.ClientRect.Width - 20, 180), "SHOW BACKGROUND", window, 1720);
                gui.AddCheckBox(optionFPS, new Recti(20, 180, window.ClientRect.Width - 20, 200), "SHOW FPS", window, 1730);

                gui.AddButton(new Recti(20, 260, window.ClientRect.Width - 20, 280), window, 1590, "EXIT GAME");

                return(true);
            }

            if (window != null &&
                evnt.Type == EventType.GUI)
            {
                if (evnt.GUI.Caller == window &&
                    evnt.GUI.Type == GUIEventType.ElementClosed)
                {
                    window.Remove();
                    window = null;
                    return(true);
                }

                if (evnt.GUI.Caller.ID == 1510 &&
                    evnt.GUI.Type == GUIEventType.ButtonClicked)
                {
                    window.Remove();
                    window = null;
                    game.NewGame(5, 5);
                    setupCameraPositionAndTarget();
                    return(true);
                }

                if (evnt.GUI.Caller.ID == 1520 &&
                    evnt.GUI.Type == GUIEventType.ButtonClicked)
                {
                    window.Remove();
                    window = null;
                    game.NewGame(10, 10);
                    setupCameraPositionAndTarget();
                    return(true);
                }

                if (evnt.GUI.Caller.ID == 1530 &&
                    evnt.GUI.Type == GUIEventType.ButtonClicked)
                {
                    window.Remove();
                    window = null;
                    game.NewGame(15, 15);
                    setupCameraPositionAndTarget();
                    return(true);
                }

                if (evnt.GUI.Caller.ID == 1540 &&
                    evnt.GUI.Type == GUIEventType.ButtonClicked)
                {
                    window.Remove();
                    window = null;
                    game.NewGame(20, 20);
                    setupCameraPositionAndTarget();
                    return(true);
                }

                if (evnt.GUI.Caller.ID == 1590 &&
                    evnt.GUI.Type == GUIEventType.ButtonClicked)
                {
                    device.Close();
                    return(true);
                }

                if (evnt.GUI.Caller.ID == 1710 &&
                    evnt.GUI.Type == GUIEventType.CheckBoxChanged)
                {
                    optionShadows     = (evnt.GUI.Caller as GUICheckBox).Checked;
                    light.CastShadows = optionShadows;
                    return(true);
                }

                if (evnt.GUI.Caller.ID == 1720 &&
                    evnt.GUI.Type == GUIEventType.CheckBoxChanged)
                {
                    optionBackground = (evnt.GUI.Caller as GUICheckBox).Checked;
                    device.SceneManager.GetSceneNodeFromID(7777).Visible = optionBackground;
                    return(true);
                }

                if (evnt.GUI.Caller.ID == 1730 &&
                    evnt.GUI.Type == GUIEventType.CheckBoxChanged)
                {
                    optionFPS = (evnt.GUI.Caller as GUICheckBox).Checked;
                    return(true);
                }
            }

            return(false);
        }
Пример #8
0
        static void Main(string[] args)
        {
            // Initialize device.

            DriverType driverType;

            if (!AskUserForDriver(out driverType))
            {
                return;
            }

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

            if (device == null)
            {
                return;
            }

            // Add event handling.

            device.OnEvent += new IrrlichtDevice.EventHandler(device_OnEvent);

            // Save important pointers.

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

            // Initialize joysticks and print info about them.

            List <JoystickInfo> joystickList = device.ActivateJoysticks();

            if (joystickList != null)
            {
                logger.Log("Joystick support is enabled and " + joystickList.Count.ToString() + " joystick(s) are present.");

                foreach (JoystickInfo j in joystickList)
                {
                    logger.Log("Joystick " + j.Joystick.ToString() + ":");
                    logger.Log("\tName: \"" + j.Name + "\"");
                    logger.Log("\tAxisCount: " + j.AxisCount.ToString());
                    logger.Log("\tButtonCount: " + j.ButtonCount.ToString());
                    logger.Log("\tPovHat: " + j.PovHat.ToString());
                }
            }
            else
            {
                logger.Log("Joystick support is not enabled.");
            }

            device.SetWindowCaption("Mouse and joystick - Irrlicht Lime - " + joystickList.Count.ToString() + " joystick(s)");

            // Create an arrow mesh and move it around either with the joystick axis/hat,
            // or make it follow the mouse pointer (when no joystick movement).

            SceneNode node = smgr.AddMeshSceneNode(
                smgr.AddArrowMesh(
                    "Arrow",
                    new Color(255, 0, 0),
                    new Color(0, 255, 0),
                    16, 16,
                    2.0f, 1.3f,
                    0.1f, 0.6f
                    )
                );

            node.SetMaterialFlag(MaterialFlag.Lighting, false);

            CameraSceneNode camera = smgr.AddCameraSceneNode();

            camera.Position = new Vector3Df(0, 0, -10);

            // As in example #4, we'll use framerate independent movement.
            uint        then          = device.Timer.Time;
            const float MovementSpeed = 5.0f;

            // Run main cycle.

            while (device.Run())
            {
                // Work out a frame delta time.
                uint  now            = device.Timer.Time;
                float frameDeltaTime = (float)(now - then) / 1000.0f;                 // in seconds
                then = now;

                bool      movedWithJoystick = false;
                Vector3Df nodePosition      = node.Position;

                if (joystickList.Count > 0)
                {
                    float moveHorizontal = 0.0f;                   // range is -1.0 for full left to +1.0 for full right
                    float moveVertical   = 0.0f;                   // range is -1.0 for full down to +1.0 for full up

                    // We receive the full analog range of the axes, and so have to implement our own dead zone.
                    // This is an empirical value, since some joysticks have more jitter or creep around the center
                    // point than others. We'll use 5% of the range as the dead zone, but generally you would want
                    // to give the user the option to change this.
                    float DeadZone = 0.05f;

                    moveHorizontal = joystickState.Axis[0] / 32767.0f;                     // "0" for X axis
                    if (Math.Abs(moveHorizontal) < DeadZone)
                    {
                        moveHorizontal = 0.0f;
                    }

                    moveVertical = joystickState.Axis[1] / -32767.0f;                     // "1" for Y axis
                    if (Math.Abs(moveVertical) < DeadZone)
                    {
                        moveVertical = 0.0f;
                    }

                    // POV will contain 65535 if POV hat info no0t supported, so we can check its range.
                    ushort povDegrees = (ushort)(joystickState.POV / 100);
                    if (povDegrees < 360)
                    {
                        if (povDegrees > 0 && povDegrees < 180)
                        {
                            moveHorizontal = +1.0f;
                        }
                        else if (povDegrees > 180)
                        {
                            moveHorizontal = -1.0f;
                        }

                        if (povDegrees > 90 && povDegrees < 270)
                        {
                            moveVertical = -1.0f;
                        }
                        else if (povDegrees > 270 || povDegrees < 90)
                        {
                            moveVertical = +1.0f;
                        }
                    }

                    // If we have any movement, apply it.
                    if (Math.Abs(moveHorizontal) > 0.0001f || Math.Abs(moveVertical) > 0.0001f)
                    {
                        float m = frameDeltaTime * MovementSpeed;
                        nodePosition      = new Vector3Df(moveHorizontal * m, moveVertical * m, nodePosition.Z);
                        movedWithJoystick = true;
                    }
                }

                // If the arrow node isn't being moved with the joystick, then have it follow the mouse cursor.
                if (!movedWithJoystick)
                {
                    // Create a ray through the mouse cursor.
                    Line3Df ray = smgr.SceneCollisionManager.GetRayFromScreenCoordinates(mouseState.Position, camera);

                    // And intersect the ray with a plane around the node facing towards the camera.
                    Plane3Df  plane = new Plane3Df(nodePosition, new Vector3Df(0, 0, -1));
                    Vector3Df mousePosition;
                    if (plane.GetIntersectionWithLine(ray.Start, ray.Vector, out mousePosition))
                    {
                        // We now have a mouse position in 3d space; move towards it.
                        Vector3Df toMousePosition   = mousePosition - nodePosition;
                        float     availableMovement = frameDeltaTime * MovementSpeed;

                        if (toMousePosition.Length <= availableMovement)
                        {
                            nodePosition = mousePosition;                             // jump to the final position
                        }
                        else
                        {
                            nodePosition += toMousePosition.Normalize() * availableMovement;                             // move towards it
                        }
                    }
                }

                node.Position = nodePosition;

                // Turn lighting on and off depending on whether the left mouse button is down.
                node.SetMaterialFlag(MaterialFlag.Lighting, mouseState.IsLeftButtonDown);

                // Draw all.
                driver.BeginScene(true, true, new Color(113, 113, 133));
                smgr.DrawAll();
                driver.EndScene();
            }

            // Drop the device.

            device.Drop();
        }
Пример #9
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();
        }
Пример #10
0
		static void Main(string[] args)
		{
			DriverType driverType;
			if (!AskUserForDriver(out driverType))
				return;

			IrrlichtDevice device = IrrlichtDevice.CreateDevice(driverType, 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, -10, 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, -10, 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(true, true, 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
				// ISceneCollisionManager::getRayFromScreenCoordinates()
				Line3Df ray = new Line3Df();
				ray.Start = new Vector3Df(camera.Position);
				ray.End = ray.Start + (camera.Target - ray.Start).Normalize() * 1000.0f;

				// Tracks the current intersection point with the level or a mesh
				Vector3Df intersection;
				// Used to show with triangle has been hit
				Triangle3Df hitTriangle;

				// 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 intersection, // This will be the position of the collision
						out 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 = new Vector3Df(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();
		}
Пример #11
0
        /// <summary>
        /// The irrlicht thread for rendering.
        /// </summary>
        private void StartIrr()
        {
            try
            {
                //Setup
                IrrlichtCreationParameters irrparam = new IrrlichtCreationParameters();
                if (irrlichtPanel.IsDisposed)
                {
                    throw new Exception("Form closed!");
                }
                if (irrlichtPanel.InvokeRequired)
                {
                    irrlichtPanel.Invoke(new MethodInvoker(delegate { irrparam.WindowID = irrlichtPanel.Handle; }));
                }
                irrparam.DriverType   = DriverType.Direct3D9;
                irrparam.DriverType   = DriverType.OpenGL;
                irrparam.BitsPerPixel = 16;

                device = IrrlichtDevice.CreateDevice(irrparam);

                if (device == null)
                {
                    throw new NullReferenceException("Could not create device for engine!");
                }

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

                var cam = smgr.AddCameraSceneNode(null);
                cam.TargetAndRotationBinding = true;
                cam.Position = new Vector3Df(-100.0f, 500.0f, 100.0f);
                cam.Target   = new Vector3Df(0.0f);
                cam.FarValue = 42000.0f;

                device.CursorControl.Visible = false;

                //Terrain
                heightmap = driver.CreateImage("Terrain\\basemap.bmp");

                terrain = smgr.AddTerrainSceneNode(
                    "Terrain\\basemap.bmp",
                    null,
                    -1,
                    new Vector3Df(0.0f)
                    );
                terrain.Scale = new Vector3Df(32, 5, 32);
                terrain.SetMaterialFlag(MaterialFlag.Lighting, false);

                terrain.SetMaterialTexture(0, driver.GetTexture("Terrain\\rockwall.jpg"));
                selector = smgr.CreateTerrainTriangleSelector(terrain, 0);

                var arrow = smgr.AddAnimatedMeshSceneNode(smgr.AddArrowMesh("arrow", new IrrlichtLime.Video.Color(255, 255, 0, 0), new IrrlichtLime.Video.Color(255, 0, 255, 0)), null);
                arrow.SetMaterialFlag(MaterialFlag.Lighting, false);
                arrow.Scale    = new Vector3Df(100.0f);
                arrow.Rotation = new Vector3Df(0.0f, 0.0f, 180.0f);

                //Skybox and skydome
                driver.SetTextureCreationFlag(TextureCreationFlag.CreateMipMaps, false);

                /*var box = smgr.AddSkyBoxSceneNode(
                 *  ("Terrain\\irrlicht2_up.jpg"),
                 *  ("Terrain\\irrlicht2_dn.jpg"),
                 *  ("Terrain\\irrlicht2_lf.jpg"),
                 *  ("Terrain\\irrlicht2_rt.jpg"),
                 *  ("Terrain\\irrlicht2_ft.jpg"),
                 *  ("Terrain\\irrlicht2_bk.jpg"));
                 * box.Visible = true;*/

                var dome = smgr.AddSkyDomeSceneNode(driver.GetTexture("Terrain\\skydome.jpg"), 16, 8, 0.95f, 2.0f);
                dome.Visible = true;
                driver.SetTextureCreationFlag(TextureCreationFlag.CreateMipMaps, true);

                var helpq = gui.AddStaticText("Press Q to disable focus!",
                                              new Recti(0, this.ClientSize.Height - 40, 100, this.ClientSize.Height), true, true, null, 1, true);
                var helpesc = gui.AddStaticText("Press ESC to quit",
                                                new Recti(0, this.ClientSize.Height - 20, 100, this.ClientSize.Height), true, true, null, 1, true);
                middletext = gui.AddStaticText("Click to enable mouselook and move with WASD",
                                               new Recti(ClientSize.Width / 2 - 100, this.ClientSize.Height / 2, ClientSize.Width / 2 + 100, this.ClientSize.Height / 2 + 30), true, true, null, 1, true);
                middletext.OverrideColor   = IrrlichtLime.Video.Color.SolidWhite;
                middletext.BackgroundColor = IrrlichtLime.Video.Color.SolidBlack;
                var irrTimer = device.Timer;
                var then     = 0;
                var then30   = 0;

                device.CursorControl.Visible = false;

                Vector2Df lastcurr = new Vector2Df(0f);
                uint      dt       = 0;
                while (device.Run())
                {
                    driver.BeginScene(ClearBufferFlag.All);

                    if (catchmouse)
                    {
                        // move the arrow to the nearest vertex ...
                        IrrlichtLime.Core.Vector2Di center = new IrrlichtLime.Core.Vector2Di(irrlichtPanel.Width / 2, irrlichtPanel.Height / 2);
                        Line3Df     ray = smgr.SceneCollisionManager.GetRayFromScreenCoordinates(center, cam);
                        Vector3Df   pos;
                        Triangle3Df Tri;
                        var         curr = device.CursorControl.RelativePosition;

                        // Threshold and periodical check so we don't spin around due to float conversions
                        if (device.Timer.Time > dt && curr.GetDistanceFrom(lastcurr) > 0.01f)
                        {
                            Line3Df cursor_ray = smgr.SceneCollisionManager
                                                 .GetRayFromScreenCoordinates(new Vector2Di((int)(curr.X * irrlichtPanel.Width), (int)(curr.Y * irrlichtPanel.Height)), cam);

                            smgr.ActiveCamera.Target = cursor_ray.Middle;
                            dt       = device.Timer.Time + 30;
                            lastcurr = curr;
                            device.CursorControl.Position = center;
                        }

                        if (smgr.SceneCollisionManager.GetCollisionPoint(ray, selector, out pos, out Tri, out outnode))
                        {
                            var scale = 32;  // terrain is scaled 32X
                            var size  = 512; // heightmap is 512x512 pixels
                            var x     = (pos.X / scale);
                            var z     = (pos.Z / scale);
                            var index = x * size + z;

                            x *= scale;
                            z *= scale;

                            arrow.Position = new Vector3Df(x, terrain.GetHeight(x, z) + 100, z);
                        }
                    }

                    smgr.DrawAll();
                    gui.DrawAll();

                    driver.EndScene();

                    //device.CursorControl.Position = new Vector2Di(irrlichtPanel.
                }

                device.Drop();
            }
            catch (ThreadAbortException) { }
            catch (NullReferenceException) { }
            catch (Exception ex)
            {
                if (!this.IsDisposed)
                {
                    MessageBox.Show(ex.Message);
                    //this.Invoke(new MethodInvoker(delegate { this.Close(); }));
                }
            }
        }