MogreNewt for Newton 2.0

Beauty

07-08-2008 16:05:30

Hi,

a new version of the Newton engine is in development.
Did somebody start to update the sources of MogreNewt?

I started to do, but it's not easy for me. There are several changes to do and I don't know much about C++.
As a help I also can look to walabers OgreNewt updates.

Well, if someone else want to update MogreNewt for use with Newton 2.0, we could work together.
Maybe Bekas or Marioko?

Greetings
Beauty

Bekas

08-08-2008 22:06:55

I would wait until it's officially released, but if you really want to use it and want some help, try posting specific questions about the issues you are running into.

Beauty

12-08-2008 14:28:04

Yes, waiting for the official release is a good way to reduce work.

But for my project (simulation of a sonar sensor) I need the new collision system. This can be used completely independent of the physics. Also it is possible to use it without callback function.

So I just need a few methods. The rest I commented out if there is was an error. Not nice for everybody, but good enough to me :wink:

Beauty

12-08-2008 14:55:00

In this post I write update notes.
This can help people who want to update MogreNewt.


-----------------------------------


MogreNewt uses NewtonBodyActivationState.
In Newton 2 this is not available.

The definition is commented in hewton.h file of Newton 2 SDK.
// typedef void (*NewtonBodyActivationState) (const NewtonBody* body, unsigned state);
So reactivate the line (the easy way) or change the code of method Body::_ctor(...) in file NewtonBodyActivationState.cpp.

Reason for commenting out:
In is a funtion call now since force and torque are always called even for inative bodies
- function NewtonBodyGetSleepingState is changed to NewtonBodyGetSleepState


-----------------------------------


The MogreNewt code of MogreNewt::CollisionPrimitives::ConvexHull in file OgreNewt_Body.cpp should be extended.
:arrow: This also can be done for the current MogreNewt sources (related to Newton 1.53).

Problem 1:
Only the first attached entity will be handled.
Better: add vertices of all attached entities

Problem 2:
If the entity is a ManualObject there comes an exception.
This should be fixed.

Beauty

12-08-2008 16:07:05

The method NewtonBodyForEachPolygonDo is removed and we should use the new method NewtonCollisionForEachPolygonDo.
But there are more parameters now ...

This problem is solved.
Here is the modified code to use the debugLines.


The discussion was in [u]this Newton forum thread[/u]




OgreNewt_Debugger.h:

void _CDECL Debugger_newtonPerPoly( void* userData, int vertexCount, const float* faceVertec, int id );
//OLD void _CDECL Debugger_newtonPerPoly( const NewtonBody* body, int vertexCount, const float* faceVertec, int id );

// void _CDECL Debugger_newtonPerBody( const NewtonBody* body );
//// removed




OgreNewt_Debugger.cpp:

void Debugger::ShowLines( MogreNewt::World^ world )
{
m_debugnode->detachAllObjects();
m_debugger_debuglines->clear();

// make the new lines.

//OLD NewtonWorldForEachBodyDo(world->NewtonWorld, Debugger_newtonPerBody); // World, IteratorCallback

//NEW_BEGIN of moved code (from Debugger_newtonPerBody)
for (const NewtonBody* body = NewtonWorldGetFirstBody (world->NewtonWorld);
body;
body = NewtonWorldGetNextBody (world->NewtonWorld, body))
{

//OLD int state = NewtonBodyGetSleepingState(body);
int state = NewtonBodyGetSleepState(body);

// We choose the color depending on the state of the body.
if (state == 1)
m_debugger_debuglines->begin("__OgreNewt__Debugger__Green__",
Ogre::RenderOperation::OT_LINE_LIST );
else
m_debugger_debuglines->begin("__OgreNewt__Debugger__Red__",
Ogre::RenderOperation::OT_LINE_LIST );

//MOD NewtonBodyForEachPolygonDo( body, Debugger_newtonPerPoly );

//-- NEW CODE - Begin (Newton 2) --

//Mogre::Matrix4 matrix;
float matrix[4][4];
NewtonCollision* collision;

NewtonBodyGetMatrix (body, &matrix[0][0]);
collision = NewtonBodyGetCollision(body);

NewtonCollisionForEachPolygonDo (collision, &matrix[0][0], Debugger_newtonPerPoly, NULL);
// the last parameter can be any userData want to pass
//-- NEW CODE - End (Newton 2) --


m_debugger_debuglines->end();
} // for
//NEW_END of moved code (from Debugger_newtonPerBody)

m_debugnode->attachObject(m_debugger_debuglines);
}


// ...


void _CDECL Debugger_newtonPerPoly( void* userData, int vertexCount, const float* faceVertec, int id )
//OLD void _CDECL Debugger_newtonPerPoly( const NewtonBody* body, int vertexCount, const float* faceVertec, int id )
{
Ogre::Vector3 p0, p1;

int i= vertexCount - 1;
p0 = Ogre::Vector3( faceVertec[(i*3) + 0], faceVertec[(i*3) + 1], faceVertec[(i*3) + 2] );

for (i=0;i<vertexCount;i++)
{
p1 = Ogre::Vector3( faceVertec[(i*3) + 0], faceVertec[(i*3) + 1], faceVertec[(i*3) + 2] );

m_debugger_debuglines->position( p0 );
m_debugger_debuglines->position( p1 );

p0 = p1;
}
}


// ...


// void _CDECL Debugger_newtonPerBody( const NewtonBody* body )
//// this function is commented out
//// --> now the code is integrated to Debugger::ShowLines

Beauty

13-08-2008 13:33:12

Next problem related to parameters.

I integrated the new methods NewtonWorldGetFirstBody, NewtonWorldGetNextBody and NewtonCollisionUpdate.
The compiler told no error, but I'm not shure, if my code is right.

1. In the old code of MogreNewt some parameters are const others not.
(e.g. in old members body is const and world not)

2. In old members I saw var types of Newton (e.g. NewtonBody).
In other members I saw var types of MogreNewt (e.g. MogreNewt::World).
Now I don't know, if I choosed the right one.

3. Also I'm confused of using ^ and *.
Did I use the right pointer symbols?
(Sorry for my bad C++ knowledge)


This is my added code:

update:
Removed Collision::CollisionUpdate( MogreNewt::World^ world ) and added World::CollisionUpdate() instead
Added Body::GetFirstContactJoint and Body::GetNextContactJoint


header file:
// class Body
::NewtonBody* Body::GetFirstBody( MogreNewt::World^ world );
::NewtonBody* Body::GetNextBody( MogreNewt::World^ world, const ::NewtonBody* currentBody );

::NewtonJoint* Body::GetFirstContactJoint(const ::NewtonBody* body);
::NewtonJoint* Body::GetNextContactJoint (const ::NewtonBody* body, const ::NewtonJoint* contactJoint);

// class World
//! update the bodies that have change position in the multigrid (without updating the physics world)
/*!
CollisionUpdate is useful for using the Newton collision detection independent of Newton physic.
So the internally state will be updated when body positions did change by MogreNewt.Body.SetPositionOrientation().
Bodies/Collisions moved by SetPositionOrientation() maybe will not give a contact feedback.
*/
void CollisionUpdate();


source file:
// class Body
NewtonBody* Body::GetFirstBody( MogreNewt::World^ world )
{
return NewtonWorldGetFirstBody(world->NewtonWorld);
}

NewtonBody* Body::GetNextBody( MogreNewt::World^ world, const ::NewtonBody* currentBody )
{
return NewtonWorldGetNextBody( world->NewtonWorld, currentBody);
}

NewtonJoint* Body::GetFirstContactJoint(const ::NewtonBody* body)
{
return NewtonBodyGetFirstContactJoint( body);
}

NewtonJoint* Body::GetNextContactJoint (const ::NewtonBody* body, const ::NewtonJoint* contactJoint)
{
return NewtonBodyGetNextContactJoint ( body, contactJoint);
}

// class World
void World::CollisionUpdate()
{
NewtonCollisionUpdate( m_world );
}

ProfesorX

13-08-2008 19:14:14

1-2) Ask Walaber about this, i think he has a version of OgreNewt For Newton 2.0, and make your port in base to this. Remember that MogreNewt is a port of OgreNewt, it's not the same, but must be the base so both wil be compatibles.

3) Yes, ^ and * are both pointers, this is exclusive of C++.NET, but the difference (in managed C++) is that * is for unmanaged pointers and ^ is for managed (garbage-collected) pointers.

So, try to use managed pointers (^) whenever possible.

Edit: Something i forgot, i suggest you to read about managed C++/CLI, there are some diferences from normal C++, also, if you need to use unmanaged pointers, remember that you need to free them manually.

A link from wikipedia recommended to read:

http://en.wikipedia.org/wiki/C%2B%2B/CLI

Beauty

13-08-2008 21:15:45

Thanks for the answer :)

Right, Walaber made an update of OgreNewt. I even got his sources for Newton 2.0. Not all things are implemented, but good to remember me -- tomorrow I'll look, if these functions are still used. But it's a little pitty that Walaber don't know C# (if I remember right).

For the pointers - this is a good explanation. Now I remember that I read that some pointers are wilful unmanaged to speed up callback functions.

Some days ago from my library I got the book C++/CLI in action. I didn't know if MogreNewt is CLI. Now I know it's a good thing to read a little bit about.

For my problem with NewtonCollisionForEachPolygonDo I got help by the author of Newton in [u]this Newton forum thread[/u]. When it's solved I'll post the code here.

But now I should go to bed. I'm tired and drunken :oops:

Mephs

13-08-2008 22:54:33

Thanks for the answer :)

Right, Walaber made an update of OgreNewt. I even got his sources for Newton 2.0. Not all things are implemented, but good to remember me -- tomorrow I'll look, if these functions are still used. But it's a little pitty that Walaber don't know C# (if I remember right).

For the pointers - this is a good explanation. Now I remember that I read that some pointers are wilful unmanaged to speed up callback functions.

Some days ago from my library I got the book C++/CLI in action. I didn't know if MogreNewt is CLI. Now I know it's a good thing to read a little bit about.

For my problem with NewtonCollisionForEachPolygonDo I got help by the author of Newton in [u]this Newton forum thread[/u]. When it's solved I'll post the code here.

But now I should go to bed. I'm tired and drunken :oops:


If you know C++, you know C# kind of, at least I haven't seen any glaring differences in the two from ++ to #, just simpler syntax.

Beauty

15-08-2008 15:10:34

Next problem.

I want to add the new functions NewtonJointGetBody0 and NewtonJointGetBody1 as property of Joint class to Mogre.
The compiler produced no error, but I don't know if this is right.
Because NewtonJointGetBody0 returns a pointer to a NewtonBody. Better would be to return a type of Mogre::Body class.
How to do?
Also I don't know it the pointer symbol is right.
Maybe I should use ^, but often in the sources * is used.

On the other side -- would it be a big performance increase if a Body type will be returned? I think then a new Body instance will be created for each call of this property. This would be not good for performance, if NewtonJointGetBody0 is called very often (e.g. at collision detection without callback).

// declared in header file of JOINT class
property ::NewtonBody* GetBody0
{
::NewtonBody* get() { return NewtonJointGetBody0(m_joint); }
}
property ::NewtonBody* GetBody1
{
::NewtonBody* get() { return NewtonJointGetBody1(m_joint); }
}


Just as little note the definition of NewtonBody:
//! get a pointer to the NewtonBody object
/*!
this is the NewtonBody used by the Newton SDK. in most cases you shouldn't need to access this.
*/
property ::NewtonBody* NewtonBody { ::NewtonBody* get() { return m_body; } }

Bekas

15-08-2008 16:32:58

Better would be to return a type of Mogre::Body class.
How to do?

Here's what MogreNewt currently does:

When you create a new Mogre::Body:

....
m_nativeInfo = new BodyNativeInfo( this );
NewtonBodySetUserData( m_body, m_nativeInfo );
....


Later, when a NewtonBody* -> Mogre::Body conversion is needed:
int ContactCallback::ContactBegin( const NewtonMaterial* material, const ::NewtonBody* body0, const NewtonBody* body1 )
{
m_material = (NewtonMaterial*)material;

//save the bodies...
m_body0 = static_cast<BodyNativeInfo*>( NewtonBodyGetUserData( body0 ) )->managedBody;
m_body1 = static_cast<BodyNativeInfo*>( NewtonBodyGetUserData( body1 ) )->managedBody;

return UserBegin();
}

m_body0 and m_body1 are of Mogre::Body^ type.

Bekas

15-08-2008 16:38:37

And you should return a Mogre::Body^.

When you refer to a type like a C# class (declared using "ref class" in C++/CLI), you use '^'.
You don't use '^' only for types like a C# struct (declared using "value class" in C++/CLI).

Beauty

15-08-2008 17:58:56

Thanks for the help !!

So I think my [u]code above[/u] for Body::GetFirstBody etc. is not usable.
They return types of NewtonBody* and NewtonJoint*. This I have to convert into Mogre types like you shown.

Now I got an idea.
m_body0 and m_body1 are declared in Joint class.
So I can store the result of NewtonJointGetBody0 in m_body0 and return this when Joint::GetBody0 ist called.

Well, we will see. I'm not at home for 10 days now. When I'm back I will continue.

Beauty

25-08-2008 12:30:46

I updated the code. It seems to be working.

property ::MogreNewt::Body^ GetBody0
{
::MogreNewt::Body^ get()
{
return static_cast<BodyNativeInfo*>(
NewtonBodyGetUserData( NewtonJointGetBody0(m_joint) )
)->managedBody;
}
}
// and the same for GetBody1


In the past I could compile the modified code of MogreNewt.
One day the compiler asked for the newton.lib. After adding the needed link path I still can't compile it any more.

There are errors like this:
Linking...
1>OgreNewt_World.obj : error LNK2020: Not solved token (06000016) MogreNewt.World::get_TimeStep.

The string get_TimeStep (a function?) is nowhere inside the MogreNewt project. Only in MogreNewt.dll and OgreNewt_xxx.lib files I find the string. In the NewtonSDK directory I found nothing.
I do not know much about C++ internals and I am going despaired :cry:

Beauty

25-08-2008 13:08:58

In the past I modified the MogreNewt code and I could compile it.
(at this time the compiler didn't ask for newton.lib)
I have a backup of this working source and header files.
Now I replaced all current files with the old ones, but the token errors are still there.

I suppose there was something getting wrong with my project data.
Maybe include / linker directories? I was thinging about and tried different entries, but nothing helps.
It's bad that i only made backups of the source / header files and not of the full project.

Bekas

25-08-2008 13:27:07

The string get_TimeStep (a function?) is nowhere inside the MogreNewt project. Only in MogreNewt.dll and OgreNewt_xxx.lib files I find the string. In the NewtonSDK directory I found nothing.
It's the property TimeStep (properties have get/set methods).
Inside OgreNewt_World.h there's:
property Mogre::Real TimeStep
{
Mogre::Real get();
}

and in OgreNewt_World.cpp:
Mogre::Real World::TimeStep::get()
{
float ret = 0.0f;

ret = NewtonGetTimeStep( m_world );

return (Mogre::Real)ret;
}

Try changing "Mogre::Real" -> "float" and see what happens.

If it doesn't work, temporarily comment it out to at least get it compiled.

Beauty

25-08-2008 14:02:15

good to know that get_ means the get property of TimeStep.

I commented out the code in the cpp file, because it created some strange errors with newton.dll (version 2).
(I suppose that I don't need this function for my application)

In the header file I didn't commented it out. (in the past the compiler didn't shout about)

Now I removed the property in the header file and this token error is gone (-:
I will see if I can stop the other errors, too.

Beauty

15-09-2008 15:21:54

Bekas helped me with the errors. Now it works fine :)


Today I got an error I had not before. It seems to be a rar error.

A System.AccessViolationException (tried to access protected memory).
The source is the MogreNewt wrapper library. The is no inner exception.

Body body = new MogreNewt.Body(nWorld, colHull);
colOb.body.SetMassMatrix(...);
colOb.body.UserData = ...;
colOb.body.SetPositionOrientation(...); // <-- EXCEPTION HERE


The newton related code I didn't change for a longer time. All parameters are defined.
(I know, this is not much information)

Is it an error of MogreNewt / Newton or maybe I made a mistake?
Any ideas?


UPDATE:
At an other run the application hanged up.
No exception, but when I broke it in Visual Studio I saw the deadlock in this line.

drr00t

25-09-2008 14:17:34

Hi,

Anybody see this wrapper, what you about port this to Mogre???

http://www.codeplex.com/ngd4xna/

Beauty

25-09-2008 19:09:53

An interesting wrapper. I think it's similar to MogreNewt. Maybe it can be used together with Mogre. A port is not needed if the Ngd4Xna class can be included to the project (like MogreNewt).
It's main target is Microsoft's XNA gaming library. How difficult or easy it is to get work with Mogre I don't know.
Also there is no Ogre related documentation or tutorial.

I have a beta release of Newton 2.0. After many problems Bekas helped me. The collision detection runs now. Not all sub classes are included, but I think the main problems are solved. When Newton 2.0 is out I suppose that Bekas (or somebody else) would update MogreNewt. Until then we have to wait.

Beauty

25-03-2009 16:44:02

GantZ made a complete update of MogreNewt for 2.0.
More informations here: viewtopic.php?f=8&t=9193


(Just as an info for people who found this thread by search function. This thread here is outdated now.)