Finally I had the time to put a little (very basic) ODE+Irrlicht demo.
As you can see rotations seem to be (are)... wrong!
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
}