Tutorial 4: movement

Irrlicht.Net is no longer developed or supported, Irrlicht.Net Cross Platform is a much more complete wrapper. Please ask your C# related questions on their forums first.
Locked
Zitzu
Posts: 28
Joined: Sun Jul 03, 2005 9:18 am

Tutorial 4: movement

Post by Zitzu »

This is a c# version of Tutorial nr 4. Hope it helps!
Disclaimer 1: It works for me :twisted:
Disclaimer 2: maybe you'll have to change the path variable to fit your configuration
Disclaimer 3: I took some code and inspiration from this article: http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=10289 by the_bob. I hope you don't mind, the_bob :)
Ok, that's all: here we go...

Code: Select all

/*
This Tutorial shows how to load a Quake 3 map into the
engine, create a SceneNode for optimizing the speed of
rendering and how to create a user controlled camera.

Lets start like the HelloWorld example: We include
the irrlicht header files and an additional file to be able
to ask the user for a driver type using the console.
*/
using System;
using System.Text;
using System.IO;

using Irrlicht;
using Irrlicht.Video;
using Irrlicht.Core;
using Irrlicht.Scene;

namespace _04.Movement
{
	class Program: IEventReceiver
	{
		string path="../../../../media/";
		ISceneNode node=null;
		/// <summary>
		/// Main entry point for the program.
		/// </summary>
		/// <param name="args">Arguments to pass the software.</param>
		[STAThread]
		static void Main(string[] args)
		{
			Program prog = new Program();
			prog.run();
		}
		public bool OnEvent(Event p_e)
		{
			if (node!=null&& p_e.Type == EventType.KeyInput &&
				!p_e.KeyPressedDown)
			{
				switch(p_e.Key)
				{
					case KeyCode.KEY_KEY_W:
					case KeyCode.KEY_KEY_S:
					{
						Vector3D v = node.Position;
						v.Y += p_e.Key == KeyCode.KEY_KEY_W ? 2.0f : -2.0f;
						node.Position=v;
					}
						return true;
				}
			}

			return false;
		}

		public void run()
		{
			/* Like in the HelloWorld example, we create an IrrlichtDevice with
			createDevice(). The difference now is that we ask the user to select
			which hardware accelerated driver to use. The Software device would be
			too slow to draw a huge Quake 3 map, but just for the fun of it, we make
			this decision possible too.
			*/

			// ask user for driver
			DriverType driverType;

			// Ask user to select driver:
			StringBuilder sb = new StringBuilder();
			sb.Append("Please select the driver you want for this example:\n");
			sb.Append("\n(a) Direct3D 9.0c\n(b) Direct3D 8.1\n(c) OpenGL 1.5");
			sb.Append("\n(d) Software Renderer\n(e)Apfelbaum Software Renderer");
			sb.Append("\n(f) Null Device\n(otherKey) exit\n\n");

			// Get the user's input:
			TextReader tIn = Console.In;
			TextWriter tOut = Console.Out;
			tOut.Write(sb.ToString());
			string input = tIn.ReadLine();

			// Select device based on user's input:
			switch (input) 
			{
				case "a":
					driverType = DriverType.DIRECT3D9;
					break;
				case "b":
					driverType = DriverType.DIRECT3D8;
					break;
				case "c":
					driverType = DriverType.OPENGL;
					break;
				case "d":
					driverType = DriverType.SOFTWARE;
					break;
				case "e":
					driverType = DriverType.SOFTWARE2;
					break;
				case "f":
					driverType = DriverType.NULL_DRIVER;
					break;
				default:
					return;
			}

			// Create device and exit if creation fails:
			IrrlichtDevice device = new IrrlichtDevice(driverType, new Dimension2D(1024, 768), 32, true, true, true);

			if (device == null) 
			{
				tOut.Write("Device creation failed.");
				return;
			}

			/* set this as event receiver*/
			device.EventReceiver=this;
			/*
			Get a pointer to the video driver and the SceneManager so that
			we do not always have to write device->getVideoDriver() and
			device->getSceneManager().
			*/
			// I just left these lines here for example purposes:
			//irrv.IVideoDriver driver = device.VideoDriver;
			//irrs.ISceneManager smgr = device.SceneManager;
			ISceneManager smgr=device.SceneManager;
			IVideoDriver driver=device.VideoDriver;

			/*Create the node for moving it with the 'W' and 'S' key. We create a 
			 'test node', which is a cube built in into the engine for testing purposes. 
			 We place the node a (0,0,30) and we assign a texture to it to let it look a 
			 little bit more interesting.*/
			node = smgr.AddTestSceneNode(10,null,0,new Vector3D(0,0,30),new Vector3D(),new Vector3D(1,1,1));
			node.SetMaterialTexture(0,driver.GetTexture(path+"wall.bmp"));

			/* Now we create another node, moving using a scene node animator. Scene 
			   node animators modify scene nodes and can be attached to any scene node 
			   like mesh scene nodes, billboards, lights and even camera scene nodes. 
			   Scene node animators are not only able to modify the position of a scene 
			   node, they can also animate the textures of an object for example. We create
			   a test scene node again an attach a 'fly circle' scene node to it, letting 
			   this node fly around our first test scene node.*/
			ISceneNode n = smgr.AddTestSceneNode(10,null,0,new Vector3D(),new Vector3D(),new Vector3D(1,1,1));
			n.SetMaterialTexture(0,driver.GetTexture(path+"t351sml.jpg"));
			ISceneNodeAnimator anim = smgr.CreateFlyCircleAnimator(new Vector3D(0,0,30),20,0.001f);
			n.AddAnimator(anim);
			//is this really necessary?
			anim.__dtor();
			/*The last scene node we add to show possibilities of scene node animators 
			  is a md2 model, which uses a 'fly straight' animator to run between two 
			  points.*/

			IAnimatedMeshSceneNode anms = smgr.AddAnimatedMeshSceneNode(
				smgr.GetMesh(path+"sydney.md2"),null,0);
			if (!anms.Equals(null))
			{
				anim= smgr.CreateFlyStraightAnimator(new Vector3D(100,0,60),new Vector3D(-100,0,60),10000,true);
				anms.AddAnimator(anim);
				anim.__dtor();

				/*To make to model look better, we disable lighting (we have created no lights, 
				  and so the model would be black), set the frames between which the animation
				  should loop, rotate the model around 180 degrees, and adjust the animation 
				  speed and the texture.
				  To set the right animation (frames and speed), we would also be able to just 
				  call "anms->setMD2Animation(scene::EMAT_RUN)" for the 'run' animation 
				  instead of "setFrameLoop" and "setAnimationSpeed", but this only works with
				  MD2 animations, and so you know how to start other animations.*/
				anms.Position=new Vector3D(0,0,40);
				anms.SetMaterialFlag(MaterialFlag.LIGHTING,false);
				anms.SetFrameLoop(320,360);
				anms.AnimationSpeed=30;
				anms.Rotation=new Vector3D(0,180,0);
				anms.SetMaterialTexture(0,driver.GetTexture(path+"sydney.BMP"));
			}

			/*To be able to look at and move around in this scene, we create a first person 
			 * shooter style camera and make the mouse cursor invisible.*/
			ICameraSceneNode camera = smgr.AddCameraSceneNodeFPS(null,100,100,0);
			camera.Position=new Vector3D(0,0,0);
			device.CursorControl.Visible=false;
			
			/*
			We have done everything, so lets draw it. We also write the current
			frames per second and the drawn primitives to the caption of the
			window. 
			*/
			int lastFPS = -1;

			while (device.Run()) 
			{
				if (device.WindowActive) 
				{
					device.VideoDriver.BeginScene(true, true, new Color(0, 200, 200, 200));
					device.SceneManager.DrawAll();
					device.VideoDriver.EndScene();

					int fps = device.VideoDriver.FPS;
					if (lastFPS != fps) 
					{
						device.WindowCaption = "Irrlicht Engine - Movement example [" +
							device.VideoDriver.Name + "] FPS:" + fps.ToString();
						lastFPS = fps;
					}
				}
			}


			/*
			In the end, delete the Irrlicht device.
			*/
			// Instead of device->drop, we'll use:
			GC.Collect();
           
		}
	}
}
[/url]
the_bob
Posts: 37
Joined: Fri Dec 09, 2005 6:49 pm
Location: Michigan

No problem!

Post by the_bob »

I don't mind at all. I'm happy to see that someone else might be just as new to this stuff as me. Maybe if we get this stuff posted, and Niko puts the .NET examples into the next SDK release, more .NET developers will become interested.

The more devs that get involved, the richer the community experience will become. Hopefully, it will spur Niko and/or others on to creating a full .NET version of the engine.

I'm still pretty new to Irrlicht, but it seems to be a pretty powerful (yet easy to use) engine, and I'd just love to be able to harness that power with C#.
3D in .NET - Who would've guessed!
austcro

Post by austcro »

On that note- there is a full c# port of Irrlicht progressing along at a leisurely pace. Based on 0.14 it should be as complete as the native version. Shortly there will be a release on Sourceforge. Keep visiting these forums for updates on the progress. If you would like to get involved and contribute then let me know. Any code that can be contributed will be gladly accepted and integrated into the engine.

Steve
Kikketer
Posts: 9
Joined: Fri Nov 11, 2005 3:41 pm
Location: Wisconsin
Contact:

Post by Kikketer »

Thank you very much for these translations. I was doing it myself before, and it was getting frustrating.

Cheers!
- Give a weed an inch, it'll take a yard -
the_bob
Posts: 37
Joined: Fri Dec 09, 2005 6:49 pm
Location: Michigan

Works great!

Post by the_bob »

I sent you a private message about my experience with this tutorial. Like I noted, there were only a couple of things I noticed, but the tutorial worked fine, overall.

I'm hoping that austcro (Steve) has some more information about when the pure .NET version of the engine will be available. I'm kind of looking forward to trying that out.

Until then, I'll keep looking through the tutorials you posted, and try to share my experiences with all.
3D in .NET - Who would've guessed!
the_bob
Posts: 37
Joined: Fri Dec 09, 2005 6:49 pm
Location: Michigan

Minor fix...

Post by the_bob »

Zitzu, as we talked about, I'll post my (only slightly) cleaned up version here. It can be posted in the wiki anytime, as far as I'm concerned. I'm not sure how to do that yet, so you can do it, if you want.

The things I changed were:
1) I cleaned up a couple of the comments to make them more applicable to .NET
2) Fixed the bug --> "if (!anms.Equals(null))" to "if (anms != null)"
3) Left both path versions in. Right above/below eachother.


Heres the code:

Code: Select all

/*
This Tutorial shows how to move and animate SceneNodes. The
basic concept of SceneNodeAnimators is shown as well as manual
movement of nodes using the keyboard.
*/

using System;
using System.Text;
using System.IO;

using Irrlicht;
using Irrlicht.Video;
using Irrlicht.Core;
using Irrlicht.Scene;

namespace _04.Movement
{
	/*
	In this tutorial, one of our goals is to move a scene node using some
	keys on the keyboard. We store a pointer to the scene node we want to
	move with the keys here.
	The other pointer is a pointer to the Irrlicht Device, which we need
	int the EventReceiver to manipulate the scene node and to get the 
	active camera.
	*/

	/*
	To get events like mouse and keyboard input, or GUI events like 
	"the OK button has been clicked", we need an object wich is derived from the 
	IEventReceiver object. There is only one method to override: OnEvent. 
	This method will be called by the engine when an event happened. 
	We will use this input to move the scene node with the keys W and S.
	*/
	class Program : IEventReceiver
	{
		// Use this line for the default path to the Irrlicht standard media.
		//string path = "../../../../media/";

		// the_bob just puts the media in the executable folder, so I'm using this:
		string path = string.Empty;

		ISceneNode node = null;
		IrrlichtDevice device = null;

		/// <summary>
		/// Main entry point for the program.
		/// </summary>
		/// <param name="args">Arguments to pass the software.</param>
		[STAThread]
		static void Main(string[] args)
		{
			Program prog = new Program();
			prog.run();
		}

		public bool OnEvent(Event p_e)
		{
			if (node != null && p_e.Type == EventType.KeyInput &&
			   !p_e.KeyPressedDown) {
				switch (p_e.Key) {
					case KeyCode.KEY_ESCAPE:
						device.CloseDevice();
						break;
					case KeyCode.KEY_KEY_W:
					case KeyCode.KEY_KEY_S: {
							Vector3D v = node.Position;
							v.Y += p_e.Key == KeyCode.KEY_KEY_W ? 2.0f : -2.0f;
							node.Position = v;
						}
						return true;
				}
			}

			return false;
		}

		public void run()
		{
			/* Like in the HelloWorld example, we create an IrrlichtDevice with
			new(). The difference now is that we ask the user to select
			which hardware accelerated driver to use. The Software device would be
			too slow to draw a huge Quake 3 map, but just for the fun of it, we make
			this decision possible too.
			*/

			// ask user for driver
			DriverType driverType;

			// Ask user to select driver:
			StringBuilder sb = new StringBuilder();
			sb.Append("Please select the driver you want for this example:\n");
			sb.Append("\n(a) Direct3D 9.0c\n(b) Direct3D 8.1\n(c) OpenGL 1.5");
			sb.Append("\n(d) Software Renderer\n(e)Apfelbaum Software Renderer");
			sb.Append("\n(f) Null Device\n(otherKey) exit\n\n");

			// Get the user's input:
			TextReader tIn = Console.In;
			TextWriter tOut = Console.Out;
			tOut.Write(sb.ToString());
			string input = tIn.ReadLine();

			// Select device based on user's input:
			switch (input) {
				case "a":
					driverType = DriverType.DIRECT3D9;
					break;
				case "b":
					driverType = DriverType.DIRECT3D8;
					break;
				case "c":
					driverType = DriverType.OPENGL;
					break;
				case "d":
					driverType = DriverType.SOFTWARE;
					break;
				case "e":
					driverType = DriverType.SOFTWARE2;
					break;
				case "f":
					driverType = DriverType.NULL_DRIVER;
					break;
				default:
					return;
			}

			// Create device and exit if creation fails:
			device = new IrrlichtDevice(driverType, new Dimension2D(1024, 768), 32, true, true, true);	// Bob changed this.

			if (device == null) {
				tOut.Write("Device creation failed.");
				return;
			}

			/* set this as event receiver*/
			device.EventReceiver = this;
			/*
			Get a reference to the video driver and the SceneManager so that
			we do not always have to write device.VideoDriver and
			device.SceneManager.
			*/
			ISceneManager smgr = device.SceneManager;
			IVideoDriver driver = device.VideoDriver;

			/*Create the node for moving it with the 'W' and 'S' key. We create a
			 'test node', which is a cube built in into the engine for testing purposes.
			 We place the node a (0,0,30) and we assign a texture to it to let it look a
			 little bit more interesting.*/
			node = smgr.AddTestSceneNode(10, null, 0, new Vector3D(0, 0, 30), new Vector3D(), new Vector3D(1, 1, 1));
			node.SetMaterialTexture(0, driver.GetTexture(path + "wall.bmp"));

			/* Now we create another node, moving using a scene node animator. Scene
			   node animators modify scene nodes and can be attached to any scene node
			   like mesh scene nodes, billboards, lights and even camera scene nodes.
			   Scene node animators are not only able to modify the position of a scene
			   node, they can also animate the textures of an object for example. We create
			   a test scene node again an attach a 'fly circle' scene node to it, letting
			   this node fly around our first test scene node.*/
			ISceneNode n = smgr.AddTestSceneNode(10, null, 0, new Vector3D(), new Vector3D(), new Vector3D(1, 1, 1));
			n.SetMaterialTexture(0, driver.GetTexture(path + "t351sml.jpg"));
			ISceneNodeAnimator anim = smgr.CreateFlyCircleAnimator(new Vector3D(0, 0, 30), 20, 0.001f);
			n.AddAnimator(anim);
			//is this really necessary?
			anim.__dtor();
			/*The last scene node we add to show possibilities of scene node animators
			  is a md2 model, which uses a 'fly straight' animator to run between two
			  points.*/

			IAnimatedMeshSceneNode anms = smgr.AddAnimatedMeshSceneNode(
			   smgr.GetMesh(path + "sydney.md2"), null, 0);
			if (anms != null) {
				anim = smgr.CreateFlyStraightAnimator(new Vector3D(100, 0, 60), new Vector3D(-100, 0, 60), 10000, true);
				anms.AddAnimator(anim);
				anim.__dtor();

				/*To make to model look better, we disable lighting (we have created no lights,
				  and so the model would be black), set the frames between which the animation
				  should loop, rotate the model around 180 degrees, and adjust the animation
				  speed and the texture.
				  To set the right animation (frames and speed), we would also be able to just
				  call "anms->setMD2Animation(scene::EMAT_RUN)" for the 'run' animation
				  instead of "setFrameLoop" and "setAnimationSpeed", but this only works with
				  MD2 animations, and so you know how to start other animations.*/
				anms.Position = new Vector3D(0, 0, 40);
				anms.SetMaterialFlag(MaterialFlag.LIGHTING, false);
				anms.SetFrameLoop(320, 360);
				anms.AnimationSpeed = 30;
				anms.Rotation = new Vector3D(0, 180, 0);
				anms.SetMaterialTexture(0, driver.GetTexture(path + "sydney.BMP"));
			}

			/*To be able to look at and move around in this scene, we create a first person
			 * shooter style camera and make the mouse cursor invisible.*/
			ICameraSceneNode camera = smgr.AddCameraSceneNodeFPS(null, 100, 100, 0);
			camera.Position = new Vector3D(0, 0, 0);
			device.CursorControl.Visible = false;

			/*
			We have done everything, so lets draw it. We also write the current
			frames per second and the drawn primitives to the caption of the
			window.
			*/
			int lastFPS = -1;

			while (device.Run()) {
				if (device.WindowActive) {
					device.VideoDriver.BeginScene(true, true, new Color(0, 200, 200, 200));
					device.SceneManager.DrawAll();
					device.VideoDriver.EndScene();

					int fps = device.VideoDriver.FPS;
					if (lastFPS != fps) {
						device.WindowCaption = "Irrlicht Engine - Movement example [" +
						   device.VideoDriver.Name + "] FPS:" + fps.ToString();
						lastFPS = fps;
					}
				}
			}


			/*
			In the end, delete the Irrlicht device.
			*/
			// Instead of device->drop, we'll use:
			GC.Collect();

		}
	}
} 
That should about be it. I'll try to post any cleanups, etc I have for Tutorial 5 soon.
3D in .NET - Who would've guessed!
forrestcupp
Posts: 5
Joined: Fri Nov 03, 2006 8:16 pm

Post by forrestcupp »

I don't have an AddTestSceneNode. I had to change it to AddCubeSceneNode which appears to be the same thing with a different name.
jayvatar
Posts: 6
Joined: Mon Nov 13, 2006 4:44 pm
Location: Kansas City, MO

Post by jayvatar »

I keep getting an error saying:

"An unhandled exception of type 'System.IO.IOException' occurred in mscorlib.dll

Additional information: The handle is invalid."

at the line:

string input = tIn.ReadLine();
Locked