Issues Using MogreNewt

materialDefender

26-01-2010 04:45:59

To all of you Mogre users out there using MogreNewt:

How did you learn how to use MogreNewt?

I've tried about every combination of Mogre/MogreNewt I could find, I've searched the forums, I've tried to find MogreNewt tutorials, and I've looked through many samples (they use some sort of sample application framework that I don't have).


My latest attempt gave me an Access Violation Exception at this line (using Mogre SDK 1.4.8 and its packaged version of MogreNewt):

Body body = new Body(world, col, true);
I'd be wonderfully happy if you could point out some problem with this, I'd be just as happy if you could tell me a way to use MogreNewt with Mogre to detect convex hull collisions.


My entire code, for your perusal (much is commented due to constant revision):

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
using MogreNewt;
using Mogre;

namespace PuzzleSolver
{
static class Program
{
[STAThread]
static void Main()
{
OgreStartup ogre = new OgreStartup();
ogre.Go();
}
}

class OgreStartup
{
Root root = null;
World world; //MogreNewt
float ticks = 0;

public void Go()
{
CreateRoot();
DefineResources();
SetupRenderSystem();
CreateRenderWindow();
InitializeResourceGroups();
CreateScene();
StartRenderLoop();
}

void CreateRoot()
{
try
{
root = new Root();
}
catch (System.Runtime.InteropServices.SEHException)
{
if (OgreException.IsThrown)
MessageBox.Show(OgreException.LastException.FullDescription,
"An Ogre exception has occurred!");
else
throw;
}
world = new World(); //MogreNewt
}

void DefineResources()
{
ConfigFile configFile = new ConfigFile();
configFile.Load("resources.cfg", "\t:=", true);
ConfigFile.SectionIterator seci = configFile.GetSectionIterator();
String secName, typeName, archName;

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);
}
}
}

void SetupRenderSystem()
{
RenderSystem renderSystem = root.GetRenderSystemByName("Direct3D9 Rendering Subsystem");
root.RenderSystem = renderSystem;
renderSystem.SetConfigOption("Full Screen", "No");
renderSystem.SetConfigOption("Video Mode", "640 x 480 @ 32-bit colour");
}

void CreateRenderWindow()
{
root.Initialise(true, "3D Puzzle Solver");
}

void InitializeResourceGroups()
{
TextureManager.Singleton.DefaultNumMipmaps = 5;
ResourceGroupManager.Singleton.InitialiseAllResourceGroups();
}

private void CreateScene()
{
SceneManager mgr = root.CreateSceneManager(SceneType.ST_GENERIC);
Camera cam = mgr.CreateCamera("Camera");
cam.NearClipDistance = 2;
cam.FarClipDistance = 2000;
root.AutoCreatedWindow.AddViewport(cam);

//Each point in a piece is 2 Mogre units (1 BU = 2 MU)

Entity piece1 = mgr.CreateEntity("Piece1", "Piece1.mesh");
mgr.RootSceneNode.CreateChildSceneNode().AttachObject(piece1);

Entity piece2 = mgr.CreateEntity("Piece2", "Piece2.mesh");
mgr.RootSceneNode.CreateChildSceneNode().AttachObject(piece2);

/*Entity piece3 = mgr.CreateEntity("Piece3", "Piece3.mesh");
mgr.RootSceneNode.CreateChildSceneNode().AttachObject(piece3);

Entity piece4 = mgr.CreateEntity("Piece4", "Piece4.mesh");
mgr.RootSceneNode.CreateChildSceneNode().AttachObject(piece4);

Entity piece5 = mgr.CreateEntity("Piece5", "Piece5.mesh");
mgr.RootSceneNode.CreateChildSceneNode().AttachObject(piece5);

Entity piece6 = mgr.CreateEntity("Piece6", "Piece6.mesh");
mgr.RootSceneNode.CreateChildSceneNode().AttachObject(piece6);

Entity piece7 = mgr.CreateEntity("Piece7", "Piece7.mesh");
mgr.RootSceneNode.CreateChildSceneNode().AttachObject(piece7);//*/

cam.Position = new Vector3(0, 0, -20);
cam.LookAt(new Vector3(0,0,0));

root.FrameEnded += new FrameListener.FrameEndedHandler(FrameEnded);
ticks = Environment.TickCount;

Collision col = new Collision(world); //MogreNewt
Body body = new Body(world, col, true); //MogreNewt
//Body bod = new Body(world, col, true);
//bod.AttachToNode(piece1.ParentNode);

//MogreNewt.CollisionPrimitives.ConvexHull colHull = new MogreNewt.CollisionPrimitives.ConvexHull(world, piece1.ParentSceneNode);
// the last param is only for Newton 2, remove it if you use Newton 1.x
//bod.Collision = colHull;

/*MogreNewt.CollisionPrimitives.ConvexHull hull = new MogreNewt.CollisionPrimitives.ConvexHull(world, piece1.ParentSceneNode, 0.0f, 0);
MogreNewt.Body bod = new MogreNewt.Body(world, hull);
bod.AttachNode(piece1.ParentNode);//*/
}

void StartRenderLoop()
{
while (!root.AutoCreatedWindow.IsClosed && root.RenderOneFrame())
Application.DoEvents();

world.Dispose();
root.Dispose();
}

bool FrameEnded(FrameEvent evt)
{
return true;
}
}
}

koirat

26-01-2010 09:44:16


Collision col = new Collision(world); //MogreNewt
Body body = new Body(world, col, true); //MogreNewt


Try using some Collision Primitive. Instead of just Collision <-- What kind of a collision is this, can you define it's shape ?

materialDefender

26-01-2010 11:32:51

Like this?

MogreNewt.CollisionPrimitives.ConvexHull hull = new MogreNewt.CollisionPrimitives.ConvexHull(world, piece1.ParentSceneNode);
Body body = new Body(world, hull, true); //MogreNewt

This will actually compile! :D I don't have time to try actually using it right now, but I'll try it later and then post back.


I've tried to get this to work for a while now. Thank you very much! :D

materialDefender

27-01-2010 01:24:31

Okay, I managed to set up the update function, gravity, inertia, and so on, but I'm having trouble with one thing:

When I turned on the wireframe collision debugger with a convex hull set as the collision type, I got this:

[attachment=0]Convex Hull Issue.jpg[/attachment]
While it is fairly close to the original mesh, I need something exactly like the original mesh - I'm making a 3D puzzle solver.

My question is this: is there any collision type I can set up that uses a copy of the object's mesh? I saw a "UserMeshCollision," but the Newton wiki says that "the mass of the body is ignored in all dynamics calculations" for User Meshes. Can I set the mass myself? Can UserMeshCollision bodies ever be influenced by gravity in Newton?


Thank you!

MD

smiley80

27-01-2010 06:07:22

Looks like a job for compound collision:
http://newtondynamics.com/wiki/index.ph ... s#Compound

materialDefender

29-01-2010 04:58:04

Thank you! I finally got around to trying it today, and compound collision worked quite well - I set up gravity, etc. on each piece and they collided and bounced apart as expected.

Here's a picture of the seven pieces with their collision primitives set up :D (disregard the fact that they're all stuck together, I didn't want to use time pulling 'em apart):

[attachment=0]CompoundCollision.jpg[/attachment]
However, I recently ran into a need that seems unfulfilled in the samples I have.

As I am creating a puzzle solver, I don't need automatic collision (when objects bounce off each other), but instead need to move the pieces by a set amount and then query if they are contacted by any other pieces.

I can move the pieces, but I can't find a method that will return whether a collision is taking place with an object.

I found http://newtondynamics.com/wiki/index.php5?title=NewtonCollisionCollide, but it seems awfully complicated to use. Is there anything else I can use that will just check to see if anything's touching the provided object? If not could you please post or link to an example of how to use MogreNewt.CollisionTool.NewtonCollisionCollide (or some other something like it) for my purpose?

Thank you very much! Sorry I have such specific needs. :oops:

GantZ

29-01-2010 08:42:12

if you just need collision detection, i suggest you to use the collisionupdate() method of your world object rather than the regular update(). you will have to handle all the movement of your object though, (with setpositionorientation) and compute yourself the gravity and the collision (to avoid overlapping of your pieces). but that will give you a precise control over the behavior of your objects.

about MogreNewt::CollisionTool::CollisionCollide. i haven't use it much myself, but by reading the function, you just have to provide the collisions object (yourbody.Collision) , positions and orientation of the objects you want to check for collision. it return you the informations of the collision (if any), like the points where your objects are in contact, the normals of the collision etc..

to check if an object collide with an other, you can also use contactcallback like this (this work with collisionupdate and update) :

mymaterialpair1 = new MaterialPair(m_World, mybodymaterial1, mybodymaterial2);
mymaterialpair1.SetContactCallback(new MyCustomContactCallback());

public class MyCustomContactCallback : ContactCallback
{
public override void UserProcess(ContactJoint contact, float timestep, int threadIndex)
{
object mycustomval = contact.Body0.UserData;
if(mycustomval.ToString() == myenum.value1.ToString()) //here check the value of the body for this contactcallback
//change body property, (velocity, etc...)
}
}


the UserProcess() method of your custom contactcallback class is called whenever two object using mybodymaterial1 and mybodymaterial2 collide.

materialDefender

30-01-2010 02:45:27

Thank you!

Unfortunately, I've managed to get more problems :shock: :

I attempted to use CollisionUpdate(), discovered that it was a Newton 2.0 feature (I had been using the MogreNewt version bundled with the Mogre 148 SDK), and upgraded to the Mogre 165 SDK (which is bundled with MogreNewt 2.0...I think).

After fixing all of the other errors related to the version change, I was given this error:

"The type 'Mogre.Node.Listener' is defined in an assembly that is not referenced. You must add a reference to assembly 'Mogre, Version=1.6.4.0, Culture=neutral, PublicKeyToken=null'."

I tried commenting out the lines it was related to (the debugger), but it appeared again, this time linked to MogreNewt.CollisionPrimitives.Box and other MogreNewt stuff.

Anybody know how to fix this error? I had it earlier with 164, which is what prompted me to switch to 148...but I can't do what I need to with 148... :(


Full info:
The dependencycheck.exe program in the SDK install folder says I don't have .NET Framework version 2.0 sp1 or higher, but I have 3.5 sp1.
I don't have a Newton.dll in my debug folder (I read somewhere it wasn't needed for the newer Mogre versions).
Neither Mogre 1.64 nor Mogre 1.65's bundled MogreNewts work for me, though Mogre 1.48 and the associated MogreNewt work fine.
It reports: "You must add a reference to assembly 'Mogre, Version=1.6.4.0, Culture=neutral, PublicKeyToken=null'," even though I've referenced Mogre 1.65.
I'm running Vista.

Thank you for your time! :D

materialDefender

30-01-2010 23:15:00

Please disregard the previous post - using the Release versions of the Mogre, MogreNewt, etc. libraries has fixed my problem.

Soon I'll try out the stuff that GantZ said...wish me luck!

Pyritie

31-03-2010 18:59:57

if you just need collision detection, i suggest you to use the collisionupdate() method of your world object rather than the regular update(). you will have to handle all the movement of your object though, (with setpositionorientation) and compute yourself the gravity and the collision (to avoid overlapping of your pieces). but that will give you a precise control over the behavior of your objects.

about MogreNewt::CollisionTool::CollisionCollide. i haven't use it much myself, but by reading the function, you just have to provide the collisions object (yourbody.Collision) , positions and orientation of the objects you want to check for collision. it return you the informations of the collision (if any), like the points where your objects are in contact, the normals of the collision etc..

to check if an object collide with an other, you can also use contactcallback like this (this work with collisionupdate and update) :

mymaterialpair1 = new MaterialPair(m_World, mybodymaterial1, mybodymaterial2);
mymaterialpair1.SetContactCallback(new MyCustomContactCallback());

public class MyCustomContactCallback : ContactCallback
{
public override void UserProcess(ContactJoint contact, float timestep, int threadIndex)
{
object mycustomval = contact.Body0.UserData;
if(mycustomval.ToString() == myenum.value1.ToString()) //here check the value of the body for this contactcallback
//change body property, (velocity, etc...)
}
}


the UserProcess() method of your custom contactcallback class is called whenever two object using mybodymaterial1 and mybodymaterial2 collide.


Thanks a lot for this by the way, MogreNewt doesn't have much documentation and is vastly different from OgreNewt in places. So this helps a lot. :D