MOGRE EN WINDOWS FORM

ZIDUKXUD

15-03-2011 20:04:32

Hola que tal a todos, quiero compartir con ustedes el siguiente programa para aquellos que hacen interfaces gráficas para proyectos con comunicacion a distintos hardware como por ejemplo microcontroladores. El siguiente programa esta creado en c# usando como motor grafico MOGRE. Como se puede apreciar en el programa, el robot se anima a medida que se le da la orden de avanzar.

Me gustaria que me ayudaran creando una parte de codigo para que pueda haber colision entre el robot y la cabeza del ogro, haciendo uso de mogrenewt o tambien ode.net para poder aprender y aplicarlo a mi proyecto, ya que estoy barado en esta parte.

He logrado que por lo menos cuando se acerque el robot a la cabeza del ogro me salga un label que me indique que hay una collision. si no es posible hacer la colision con alguno de estos motores fisicos "mogrenewt y ODE.NET", me gustaria que me ayudaran haciendo una funcion o metodo llamado "Colission();" que me haga restrinccion con el paso del objeto.

No importa si me responden en ingles o español, pero si necesito ayuda con esto por favor.

using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Mogre;
using MogreFramework;

namespace Prueba_mogre_winform
{
public partial class Form1 : Form
{
protected OgreWindow mogreWin;

int robot_Option = 0;
float Posnx = 0;
float Posny = 0;
float dPosx = 0;
float dPosy = 0;
float Posax = 0;
float Posay = 0;
float traslx = 1;
float trasly = 1;


public Form1()
{
InitializeComponent();
this.Disposed += new EventHandler(Form1_Disposed);

mogreWin = new OgreWindow(new Point(100, 30), panel1.Handle);
mogreWin.InitMogre();
}


void Form1_Disposed(object sender, EventArgs e)
{
mogreWin.Dispose();
}

private void Form1_Load(object sender, EventArgs e)
{
timer1.Enabled = true;
timer1.Interval = 50;
timer1.Stop();

timer2.Enabled = true;
timer2.Interval = 50;
timer2.Start();
}

private void panel1_Paint_1(object sender, PaintEventArgs e)
{
mogreWin.Paint();
}


private void timer1_Tick(object sender, EventArgs e)
{

switch (robot_Option)
{
case 0:
mogreWin.trasx_robot((float)(traslx));
break;
case 1:
mogreWin.trasx_robot((float)(-traslx));
break;
case 2:
mogreWin.trasy_robot((float)(trasly));
break;
case 3:
mogreWin.trasy_robot((float)(-trasly));
break;
}
}

private void trasx_MouseDown(object sender, MouseEventArgs e)
{
robot_Option = 0;
timer1.Start();
}
private void trasx_MouseClick(object sender, MouseEventArgs e)
{
timer1.Stop();
}

private void trasnx_MouseDown(object sender, MouseEventArgs e)
{
robot_Option = 1;
timer1.Start();
}
private void trasnx_MouseClick(object sender, MouseEventArgs e)
{
timer1.Stop();
}

private void trasy_MouseDown(object sender, MouseEventArgs e)
{
robot_Option = 2;
timer1.Start();
}
private void trasy_MouseClick(object sender, MouseEventArgs e)
{
timer1.Stop();
}
private void trasny_MouseDown(object sender, MouseEventArgs e)
{
robot_Option = 3;
timer1.Start();
}
private void trasny_MouseClick(object sender, MouseEventArgs e)
{
timer1.Stop();
}

private void timer2_Tick(object sender, EventArgs e)
{
Posnx = mogreWin.Get_posx_robot();
Posny = mogreWin.Get_posy_robot();
dPosx = Posax - Posnx;
dPosy = Posay - Posny;

if(dPosx!=0)
{
mogreWin.animacion((float)(0.1));
}
else
{
mogreWin.animacionidle((float)(0.1));
}
Posax=Posnx;
}

}

public class OgreWindow
{
public Root root;
public SceneManager sceneMgr;

public FrameEvent evt;
public SceneNode node;
public Entity ent;
public Entity ent_objeto;
public SceneNode node_objeto;

protected Camera camera;
protected Viewport viewport;
protected RenderWindow window;
protected Point position;
protected IntPtr hWnd;




public static AnimationState mAnimationState; //The AnimationState the moving object


public OgreWindow(Point origin, IntPtr hWnd)
{
position = origin;
this.hWnd = hWnd;
}

public void InitMogre()
{

//-----------------------------------------------------
// 1 enter ogre
//-----------------------------------------------------
root = new Root();

//-----------------------------------------------------
// 2 configure resource paths
//-----------------------------------------------------
ConfigFile cf = new ConfigFile();
cf.Load("resources.cfg", "\t:=", true);

// Go through all sections & settings in the file
ConfigFile.SectionIterator seci = cf.GetSectionIterator();

String secName, typeName, archName;

// Normally we would use the foreach syntax, which enumerates the values, but in this case we need CurrentKey too;
while (seci.MoveNext())
{
secName = seci.CurrentKey;
ConfigFile.SettingsMultiMap settings = seci.Current;
foreach (KeyValuePair<string, string> pair in settings)
{
typeName = pair.Key;
archName = pair.Value;
ResourceGroupManager.Singleton.AddResourceLocation(archName, typeName, secName);
}
}

//-----------------------------------------------------
// 3 Configures the application and creates the window
//-----------------------------------------------------
bool foundit = false;
foreach (RenderSystem rs in root.GetAvailableRenderers())
{
root.RenderSystem = rs;
String rname = root.RenderSystem.Name;
if (rname == "Direct3D9 Rendering Subsystem")
{
foundit = true;
break;
}
}

if (!foundit)
return; //we didn't find it... Raise exception?

//we found it, we might as well use it!
root.RenderSystem.SetConfigOption("Full Screen", "No");
root.RenderSystem.SetConfigOption("Video Mode", "640 x 480 @ 32-bit colour");

root.Initialise(false);
NameValuePairList misc = new NameValuePairList();
misc["externalWindowHandle"] = hWnd.ToString();
window = root.CreateRenderWindow("Simple Mogre Form Window", 0, 0, false, misc);
ResourceGroupManager.Singleton.InitialiseAllResourceGroups();


//-----------------------------------------------------
// 4 Create the SceneManager
//
// ST_GENERIC = octree
// ST_EXTERIOR_CLOSE = simple terrain
// ST_EXTERIOR_FAR = nature terrain (depreciated)
// ST_EXTERIOR_REAL_FAR = paging landscape
// ST_INTERIOR = Quake3 BSP
//-----------------------------------------------------
sceneMgr = root.CreateSceneManager(SceneType.ST_GENERIC, "SceneMgr");
sceneMgr.AmbientLight = new ColourValue(0.5f, 0.5f, 0.5f);

//-----------------------------------------------------
// 5 Create the camera
//-----------------------------------------------------
camera = sceneMgr.CreateCamera("SimpleCamera");
camera.Position = new Vector3(0f, 0f, 100f);
// Look back along -Z
camera.LookAt(new Vector3(0f, 0f, -300f));
camera.NearClipDistance = 5;

viewport = window.AddViewport(camera);
viewport.BackgroundColour = new ColourValue(0.0f, 0.0f, 0.0f, 1.0f);


ent = sceneMgr.CreateEntity("Robot", "Robot.mesh");
node = sceneMgr.RootSceneNode.CreateChildSceneNode("ogreNode");
node.AttachObject(ent);
node.SetPosition(-80f, -50f, -100f);

ent_objeto = sceneMgr.CreateEntity("Objeto", "ogrehead.mesh");
node_objeto = sceneMgr.RootSceneNode.CreateChildSceneNode("ogreNode2");
node_objeto.AttachObject(ent_objeto);
node_objeto.SetPosition(50f, -20f, -100f);

Light luz = sceneMgr.CreateLight("Light");
luz.Type = Light.LightTypes.LT_POINT;
luz.Position = new Vector3(250, 150, 250);
luz.DiffuseColour = ColourValue.White;
luz.SpecularColour = ColourValue.White;

}

public void Paint()
{
root.StartRendering();

}

public void trasx_robot(float tx)
{
node.Translate(new Vector3(tx, 0, 0), Mogre.Node.TransformSpace.TS_LOCAL);
}
public void trasy_robot(float ty)
{
node.Translate(new Vector3(0, ty, 0), Mogre.Node.TransformSpace.TS_LOCAL);
}


public void animacion(float anim)
{
mAnimationState = ent.GetAnimationState("Walk");
mAnimationState.Loop = true;
mAnimationState.Enabled = true;
mAnimationState.AddTime(anim);
}

public void animacionidle(float anim2)
{
mAnimationState = ent.GetAnimationState("Idle");
mAnimationState.Loop = true;
mAnimationState.Enabled = true;
mAnimationState.AddTime(anim2);
}


public void Dispose()
{
if (root != null)
{
root.Dispose();
root = null;
}
}
}

}

McDonte

16-03-2011 12:07:33

Can you post your message again in English please?

AliAkdurak

17-03-2011 08:24:24

I am sorry my Spanish is little rusty but from what I understand you are trying to mimic something like the gazebo and player project (Robot simulation and development enviroment with physics). The collision detection should be done by a proper physics motor which from what I understand you tried mogrenewt but only got the Collision has happened message and dont know how to react to that so they should move like they should? like stop going in through each other. and you want our help for writing this Collision() function.

And it does not matter to have the replies in English or Spanish.

Well first of all if possible even with simple English if you can write this in English more people will try to help.

Now for helping you. You may use timers to move stuff around but it is actually not preferred way and it will make what you want to achieve much harder.

-Check out FrameStarted event of Mogre.Root and start to listen that. That has a very important parameter which gives you time since last frame. There are a lot of examples how animation should be done in this kind of a way.

-Then Make you objects have different classes so that they can carry their own move or stop flags or just put that in your main class.

-When Collision happens and you get the message for that from the physics it should also give you who has collided see which models or entities you should stop like that.

-And by using an "if" structure in your frame started you get what you want.

Also Mogre is exactly same as Ogre and Ogre has spanish wiki and forums which I think you can get a lot more help.

Yo podría tratar de escribir esto en español. Pero mi español es muy malo en la escritura.

ZIDUKXUD

17-03-2011 22:00:05

Hi everybody,

I'm trying to make some restrinctions by using a metod "collision()" , where:

"OgreWindow.cs"

Here i define the enities and nodes of both objects (Robot and ogrehead)

ent_robot = sceneMgr.CreateEntity("Robot", "Robot.mesh");
node_robot = sceneMgr.RootSceneNode.CreateChildSceneNode("ogreNode");
node_robot.AttachObject(ent_robot);
node_robot.SetPosition(-80f, -50f, -100f);

ent_objeto = sceneMgr.CreateEntity("Objeto", "ogrehead.mesh");
node_objeto = sceneMgr.RootSceneNode.CreateChildSceneNode("ogreNode2");
node_objeto.AttachObject(ent_objeto);
node_objeto.SetPosition(50f, -20f, -100f);

Here i translate my robot along the edges X and Y

public void trasx_robot(float tx)
{
node_robot.Translate(new Vector3(tx, 0, 0), Mogre.Node.TransformSpace.TS_LOCAL);
}
public void trasy_robot(float ty)
{
node_robot.Translate(new Vector3(0, ty, 0), Mogre.Node.TransformSpace.TS_LOCAL);
}



Here i Get robot's world position in X, and Y, in a variable float

public float Get_posx_robot()
{
return node_robot.WorldPosition.x;
}
public float Get_posy_robot()
{
return node_robot.WorldPosition.y;
}


Here i Get objects position in X, and Y

public float Get_objeto_Px()
{
return node_objeto.Position.x;
}
public float Get_objeto_Py()
{
return node_objeto.Position.y;
}


Form1.cs

By Using just Windows Form.

Here i save on variables the initial distance between the Robot and Ogrehead

private void Form1_Load(object sender, EventArgs e)
{

Distancia_Px1 = mogreWin.Get_objeto_Px() - mogreWin.Get_posx_robot();
Distancia_Py1 = mogreWin.Get_objeto_Py() - mogreWin.Get_posy_robot();


timer_mover_robot.Enabled = true;
timer_mover_robot.Interval = 50;
timer_mover_robot.Stop();

}

Here i Calculate distances every time with my timer "timer_mover_robot"

public void Distancia()
{
Distancia_Px1 = mogreWin.Get_objeto_Px() - mogreWin.Get_posx_robot();
Distancia_Py1 = mogreWin.Get_objeto_Py() - mogreWin.Get_posy_robot();

}

Here i detect with a label if i have a collision when the robot moves toward the ogrehead

public void Colisión()
{
if ((Distancia_Px1 < 50 && Distancia_Px1 > -50) && (Distancia_Py1 < 50t && Distancia_Py1 > -50))
{

label4.Text = "Colission";

}
else
{

label4.Text = "Sin colission";
}
}

This is my timer, here i move my robot

private void timer_mover_robot_Tick(object sender, EventArgs e)
{

switch (robot_Option)
{
case 0:
mogreWin.trasx_robot((float)(traslx));
textBox1.Text = Distancia_Px1.ToString();
Distancia();
Colisión();
break;

case 1:
mogreWin.trasx_robot((float)(-traslx));
textBox1.Text = Distancia_Px1.ToString();
Distancia();
Colisión();
break;

case 2:
mogreWin.trasy_robot((float)(trasly));
textBox2.Text = Distancia_Py1.ToString();
Distancia();
Colisión();
break;

case 3:
mogreWin.trasy_robot((float)(-trasly));
textBox2.Text = Distancia_Py1.ToString();
Distancia();
Colisión();
break;
}
}

private void trasx_MouseDown(object sender, MouseEventArgs e)
{
robot_Option = 0;
timer_mover_robot.Start();
}
private void trasx_MouseClick(object sender, MouseEventArgs e)
{
timer_mover_robot.Stop();
}

private void trasnx_MouseDown(object sender, MouseEventArgs e)
{
robot_Option = 1;
timer_mover_robot.Start();
}
private void trasnx_MouseClick(object sender, MouseEventArgs e)
{
timer_mover_robot.Stop();
}

private void trasy_MouseDown(object sender, MouseEventArgs e)
{
robot_Option = 2;
timer_mover_robot.Start();
}
private void trasy_MouseClick(object sender, MouseEventArgs e)
{
timer_mover_robot.Stop();
}
private void trasny_MouseDown(object sender, MouseEventArgs e)
{
robot_Option = 3;
timer_mover_robot.Start();
}
private void trasny_MouseClick(object sender, MouseEventArgs e)
{
timer_mover_robot.Stop();
}

So i just need that my robot cannot pass through the ogrehead by doing a restrinction.

All my code is based on windows form and rendered on a panel as you can see in my prevous image, i don't want to use any other window because my programming skill is not good as i wish, so i only know how to write code in "Windows application" because of my university solutions.

If you know how to use (Mogrenewt or ODE.Net) by this way i appreciate your help to teach me with an example using Windows Application.

Thanks again for your help, May God Bless you