ODE.NET and Irrlicht.net

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
Mr. XYZ

ODE.NET and Irrlicht.net

Post by Mr. XYZ »

Hi,

i tried to use ode with irrlicht.net but i failed because of some missing funktions in the .net wrapper, i think.

The Ode.net wrapper:

http://www.thejamesrainenetwork.co.uk/ODE/ode.html

The problem is to convert the irrlicht mesh to ODE trimesh because i couldn't find the function "mesh->getMeshBuffer(i)" in irrlicht.net...

Code: Select all

 // count vertices and indices
    for(i=0;igetMeshBufferCount();i++){
      irr::scene::IMeshBuffer* mb=mesh->getMeshBuffer(i);
      indexcount+=mb->getIndexCount();
      vertexcount+=mb->getVertexCount();
    }
    // build structure for ode trimesh geom
    vertices=new dVector3[vertexcount];
    indices=new int[indexcount];
    // fill trimesh geom
    ci=0; // current index in the indices array
    cif=0; // offset of the irrlicht-vertex-index in the vetices array 
    cv=0; // current index in the vertices array
    for(i=0;i<m->getMeshBufferCount();i++){
      irr::scene::IMeshBuffer* mb=mesh->getMeshBuffer(i);
Has anyone created an app using irrlicht.net and a physic-engine?

Niko, how about implementing the functions in the next version? :wink:
shurijo
Posts: 148
Joined: Sat Feb 21, 2004 3:04 am

Post by shurijo »

The MeshBuffer is on the Irrlicht.NET Todo list included in the source code zip file.
Zitzu
Posts: 28
Joined: Sun Jul 03, 2005 9:18 am

Post by Zitzu »

I was fiddling with ODE.NET too, but it seems ODE and Irrlicht rotation matrices are not quite the same, or at least it seem I cannot siimply do this (sorry for the ugly code!):

Code: Select all

// body is an ODE body object            
m = new Irrlicht.Core.Matrix4();

m.set_M(0,0,body.Rotation.M11);
m.set_M(0,1,body.Rotation.M12);
m.set_M(0,2,body.Rotation.M13);
m.set_M(0,3,body.Rotation.M14);
m.set_M(1,0,body.Rotation.M21);
m.set_M(1,1,body.Rotation.M22);
m.set_M(1,2,body.Rotation.M23);
m.set_M(1,3,body.Rotation.M24);
m.set_M(2,0,body.Rotation.M31);
m.set_M(2,1,body.Rotation.M32);
m.set_M(2,2,body.Rotation.M33);
m.set_M(2,3,body.Rotation.M34);
m.set_M(3,0,body.Rotation.M41);
m.set_M(3,1,body.Rotation.M42);
m.set_M(3,2,body.Rotation.M43);
m.set_M(3,3,body.Rotation.M44);
because the bodies (I am using simple cubes) seems to act slightly oddly: object position seems to be right but rotations aren't. :shock:

Is there another way to perform Irrlicht <-> ODE rotation matrix conversion or am I doing totally wrong? :oops:
Guest

Post by Guest »

Iam not sure but I think Ode has Quaternion Rotations and Irrlicht uses Euler...

Here is the c++ code

Code: Select all


	void Bounceable::QuaternionToEuler(const dQuaternion quaternion,irr::core::vector3df &euler){
		dReal w,x,y,z;
		w=quaternion[0];
		x=quaternion[1];
		y=quaternion[2];
		z=quaternion[3];
		double sqw = w*w;    
		double sqx = x*x;    
		double sqy = y*y;    
		double sqz = z*z; 
		// heading
		euler.Z = (irr::f32) (atan2(2.0 * (x*y + z*w),(sqx - sqy - sqz + sqw))*irr::core::GRAD_PI);
		// bank
		euler.X = (irr::f32) (atan2(2.0 * (y*z + x*w),(-sqx - sqy + sqz + sqw))*irr::core::GRAD_PI);  
		// attitude
		euler.Y = (irr::f32) (asin(-2.0 * (x*z - y*w))*irr::core::GRAD_PI);
	}

[/code]
Zitzu
Posts: 28
Joined: Sun Jul 03, 2005 9:18 am

Post by Zitzu »

Thanks for the hint... I will try and report my results as soon as possible!
Zitzu
Posts: 28
Joined: Sun Jul 03, 2005 9:18 am

Post by Zitzu »

It seems quaternions weren't ported to Irrlicht.NET still.... so we have to cope with rotation matrices or wait till version ... Nikoooo!

Thankyou anyway! :)

Some other suggestions?
Mr. XYZ

Post by Mr. XYZ »

No problem... do you have icq or msn? iam very interested in implementing a physic engine in irrlicht... my icq# is 249-367-925 ...

maybe you can send me some of your source :?:
Zitzu
Posts: 28
Joined: Sun Jul 03, 2005 9:18 am

Post by Zitzu »

I will post as soon as possible my code... I just have to reorganize it because I tend to separate the code in many files :)
Rob Loach

Tao.ODE

Post by Rob Loach »

The Tao Framework ( http://www.mono-project.com/Tao ) implements Tao.Ode which binds a .NET library directly to ODE through P/Invoke function calls. You might want to check it out.
Zitzu
Posts: 28
Joined: Sun Jul 03, 2005 9:18 am

ODE Irrlicht .NET integration

Post by Zitzu »

Mr. XYZ wrote:No problem... do you have icq or msn? iam very interested in implementing a physic engine in irrlicht... my icq# is 249-367-925 ...

maybe you can send me some of your source :?:
Finally I had the time to put a little (very basic) ODE+Irrlicht demo.
You will need the ODE wrapper and, naturally Irlicht.NET wrapper.

Docs: move camera with arrows. Press 'q' to shoot a cube to break the wall. You can shoot as many cubes as you want (but there is an ODE limitation: too much cubes = stack overflow exception since in this demo I don't bother destroying cubes which are too far to be seen.

As you can see rotations seem to be (are)... wrong!


Disclaimer: I think my code is horrible! :oops:

Code: Select all

using System;
using System.Collections;
using Irrlicht; 
using Irrlicht.Video;
using Irrlicht.Core;
using Irrlicht.Scene;
using ODE;
using ODE.NoMDX;

namespace OdeIrrSimple
{
	public class ODEEnv: IEventReceiver
	{	
		[STAThread]
		static void Main(string[] args)
		{
			ODEEnv t_env = new ODEEnv();
			t_env.start();
		}
	


		private World m_world;
		private Space m_space;
		private ODE.DefaultCollider m_collider;
		private ArrayList m_blocks;
		//Irrlicht Setup
		public IrrlichtDevice m_device;
		public Irrlicht.Video.IVideoDriver m_videoDriver;
		public ITexture m_texWall ;
		public ITexture m_tex2 ;
		public ITexture m_texCar ;
		public IAnimatedMesh m_meshPunto;
		public ITexture m_texRuota ;
		public IAnimatedMesh m_meshRuota;
		public Irrlicht.Scene.ISceneManager m_sceneManager;
		private Irrlicht.GUI.IGUIEnvironment m_guiEnv;
		private Irrlicht.IO.IFileSystem m_fileSystem;
		private ICameraSceneNode m_camera;
		float m_step = 0.02f;
		public string m_path="../../../../media/";
		Plane m_plane;

		public void start()
		{
			m_blocks = new ArrayList();
			m_device = new IrrlichtDevice(DriverType.OPENGL,new Dimension2D(640,480),16,false,false,false);
			m_videoDriver = m_device.VideoDriver;
			m_sceneManager = m_device.SceneManager;
			m_fileSystem = m_device.FileSystem;
			m_device.ResizeAble = true;
			m_device.WindowCaption = "ODEIrr";
			m_device.EventReceiver=this;
			m_texWall= m_videoDriver.GetTexture(m_path+@"wall.bmp");
			m_tex2= m_videoDriver.GetTexture(m_path+@"stones.jpg");
			m_camera = 	m_sceneManager.AddCameraSceneNodeFPS(
				null, //parent
				100, // rotatespeed
				100, // movespeed
				-1); // id
			m_camera.Position=new Vector3D(0,10,-150);
			m_device.CursorControl.Visible = false;

			// ODE Setup
			m_world = new ODE.World();
			m_space = new ODE.Space();
			m_world.Gravity = new Vector3(0,-9.81f,0);
			m_collider = new ODE.DefaultCollider(m_world);
			m_space.Collider = new ODE.CollisionDelegate(m_collider.Collide);
			///////////////////////////
			m_plane = new Plane(this,m_space,new Vector3(0,1,0),-100);
			createWall();

			while(m_device.Run())
			{
				/*ode start*/
				m_space.Collide();
				m_world.QuickStep(m_step, 15);
				m_collider.ClearContactJoints();
				foreach(Block block in m_blocks)
					block.Render();
				/*ode end*/
				m_videoDriver.BeginScene(true, true, new Color(0,100,100,100));
				m_sceneManager.DrawAll();
				m_device.GUIEnvironment.DrawAll();
				m_videoDriver.EndScene();
			}
		}
	
		/// <summary>
		/// Receives events (like input from mouse and keyboard) from the Irrlicht Engine
		/// </summary>
		public bool OnEvent(Event p_e)
		{
			switch (p_e.Type )
			{
				case(EventType.LogText):
					System.Console.Out.WriteLine(p_e.LogText);
					break;
				case  (EventType.KeyInput):
					if (p_e.KeyPressedDown)
					{
						switch(p_e.KeyCharacter)
						{
							case('q'):
								AddBlock();
								break;
						}
					}
					break;
			}		
			return false;
		}

		// shoot!
		private void AddBlock()
		{
			Box t_box = new Box(this, m_world, m_space, 0.1f, 15, 15, 15, new Vector3(7, -90, -100)) ;
			t_box.setVel(new Vector3(0,50,500));
			m_blocks.Add(t_box);
		}

		//well ... creates the wall
		private void createWall()
		{
			int t_x =-7;
			int t_w=15;
			for (float j=-92.5f;j<0;j+=t_w)
			{
				if(t_x==-7)
					t_x=0;
				else
					t_x=-7;
				for (int i=-75;i<75;i+=t_w)
				{
					m_blocks.Add(
						new Box(
						this, 
						m_world, 
						m_space, 
						1, t_w, t_w, t_w, 
						new Vector3(i+t_x, j, 0)) );
				}
			}
		}
	}

	/// <summary>
	///  Block.
	/// </summary>
	public abstract class Block
	{
		public ODE.Geoms.Geom m_geom;
		public Body m_body;
		protected ODE.Space m_space;
		protected IMesh m_mesh;
		public ISceneNode m_node;
		public abstract void Render();

		protected Vector3D toIrr (Vector3 p_v)
		{
			return new Vector3D((float)p_v.X,(float)p_v.Y,(float)p_v.Z);
		}

		protected  Vector3 toODE (Vector3D p_v)
		{
			return new Vector3(p_v.X,p_v.Y,p_v.Z);
		}

		public void setVel(Vector3 p_vel)
		{
			m_body.Velocity=p_vel;
		}
	}

	/// <summary>
	/// Really simple encapsulation of a box shaped rigid body.
	/// </summary>
	public class Box : Block
	{
		private float m_w, m_h, m_d;
		private Matrix4 t_m;
		public Box(ODEEnv p_env,World p_world, Space p_space, float p_m, float p_w, float p_h, float p_d, Vector3 p_pos)
		{
			m_w = p_w;
			m_h = p_h;
			m_d = p_d;
			m_body = new Body(p_world);
			m_body.Mass = Mass.BoxTotal(p_m, p_w, p_h, p_d);
			m_geom = new ODE.Geoms.Box(p_w, p_h, p_d);
			p_space.Add(m_geom);
			m_geom.RigidBody = m_body;
			m_body.Position = p_pos;
			// Add body/node on Irrlicht
			m_node = p_env.m_device.SceneManager.AddTestSceneNode(p_w,
				null, -1, toIrr(p_pos));
			m_node.SetMaterialTexture(0, p_env.m_texWall);
		}

		public override void Render()
		{
			m_node.Position= toIrr(m_body.Position);
			t_m = new Matrix4();
			t_m.set_M(0,0,(float)m_body.Rotation.M11);
			t_m.set_M(0,1,(float)m_body.Rotation.M12);
			t_m.set_M(0,2,(float)m_body.Rotation.M13);
			t_m.set_M(0,3,(float)m_body.Rotation.M14);
			t_m.set_M(1,0,(float)m_body.Rotation.M21);
			t_m.set_M(1,1,(float)m_body.Rotation.M22);
			t_m.set_M(1,2,(float)m_body.Rotation.M23);
			t_m.set_M(1,3,(float)m_body.Rotation.M24);
			t_m.set_M(2,0,(float)m_body.Rotation.M31);
			t_m.set_M(2,1,(float)m_body.Rotation.M32);
			t_m.set_M(2,2,(float)m_body.Rotation.M33);
			t_m.set_M(2,3,(float)m_body.Rotation.M34);
			t_m.set_M(3,0,(float)m_body.Rotation.M41);
			t_m.set_M(3,1,(float)m_body.Rotation.M42);
			t_m.set_M(3,2,(float)m_body.Rotation.M43);
			t_m.set_M(3,3,(float)m_body.Rotation.M44);
			m_node.Rotation=t_m.GetRotationDegrees();
		}
	}

	public class Plane
	{
		public ODE.Geoms.Plane m_odePlane;
		public ISceneNode m_irrPlaneNode;
		ODEEnv m_env;
		Plane3D m_irrPlane;
	
		public Plane(ODEEnv p_envODEnv, Space p_space, Vector3 p_normal, float p_d)
		{
			m_env = p_envODEnv;
			//ode
			m_odePlane = new ODE.Geoms.Plane(p_normal, p_d);
			// just to see where the plane lies
			m_irrPlane = new Plane3D(
				new Vector3D(0, p_d, 0),
				new Vector3D((float)p_normal.X,(float)p_normal.Y,(float)p_normal.Z));
			p_space.Add(m_odePlane);
			Vector3D t_irrPos=new Vector3D(0,p_d,0);
			IAnimatedMesh t_irrPlaneMesh= m_env.m_sceneManager.GetMesh(m_env.m_path+"piano1.obj");
			m_irrPlaneNode = m_env.m_sceneManager.AddMeshSceneNode(t_irrPlaneMesh.GetMesh(0),null,1); 
			m_irrPlaneNode.Position=t_irrPos;
			m_irrPlaneNode.Scale=new Vector3D(5,5,5);
			m_irrPlaneNode.SetMaterialTexture(0,m_env.m_tex2);
			m_irrPlaneNode.SetMaterialFlag(Irrlicht.Video.MaterialFlag.LIGHTING,false);
			m_irrPlaneNode.SetMaterialFlag(Irrlicht.Video.MaterialFlag.BACK_FACE_CULLING,false);
		}
	}//classe
}

Zitzu
Posts: 28
Joined: Sun Jul 03, 2005 9:18 am

Post by Zitzu »

I could find by myself which problem was affecting the rotations in my little ODE->Irrlicht integration.

Hope it will help someone... not too much feedback :)

Anyway, to fix it in my previously posted code just replace the Render() method with this one:

Code: Select all

      public override void Render()
      {
         m_node.Position= toIrr(m_body.Position);
         t_m = new Matrix4();
         t_m.set_M(0,0,(float)m_body.Rotation.M11);
         t_m.set_M(0,1,(float)m_body.Rotation.M21);
         t_m.set_M(0,2,(float)m_body.Rotation.M31);
         t_m.set_M(0,3,(float)m_body.Rotation.M41);
         t_m.set_M(1,0,(float)m_body.Rotation.M12);
         t_m.set_M(1,1,(float)m_body.Rotation.M22);
         t_m.set_M(1,2,(float)m_body.Rotation.M32);
         t_m.set_M(1,3,(float)m_body.Rotation.M42);
         t_m.set_M(2,0,(float)m_body.Rotation.M13);
         t_m.set_M(2,1,(float)m_body.Rotation.M23);
         t_m.set_M(2,2,(float)m_body.Rotation.M33);
         t_m.set_M(2,3,(float)m_body.Rotation.M43);
         t_m.set_M(3,0,(float)m_body.Rotation.M14);
         t_m.set_M(3,1,(float)m_body.Rotation.M24);
         t_m.set_M(3,2,(float)m_body.Rotation.M34);
         t_m.set_M(3,3,(float)m_body.Rotation.M44);
         m_node.Rotation=t_m.GetRotationDegrees();
      } 

-Francesco
Mr. XyZ

Post by Mr. XyZ »

Thank you very much for the code!

Do you have any idea how to let the boxes collide with a loaded map?
Locked