Crate pass over the plane in the example

Chernetcov

30-03-2009 22:17:38

I made program based on SimpleScenes Demo and wiki example (http://www.ogre3d.org/wiki/index.php/First_steps_with_OgreODE and http://www.ogre3d.org/wiki/index.php/OgreOde_Collision_Handling) to understand principes of working OgreOde.
All parameters as in the demo, but crate is falling down on the plane, sink in the plane partically and then float to the surface of the plane as water.
I think I made mistake somewhere in the parameters of the crate or plane, but can't find it

here is my code OgreODE2.h


#include "ExampleApplication.h"
#include "OgreOde_Core.h"
OgreOde::World *mWorld;
OgreOde::Space *mSpace;
OgreOde::StepHandler *mStepper;
OgreOde::InfinitePlaneGeometry *mGround;
OgreOde::Body *mBody;
OgreOde::Geometry *mGeom;
OgreOde::BoxMass mMass;
Ogre::SceneNode *mNode;
Ogre::Entity *mEntity;
class CollisionTestedObject
{
public:
CollisionTestedObject(void);
virtual ~CollisionTestedObject(void);

bool virtual Collide(bool MineIsFirst, OgreOde::Contact *Contact) = 0;
};

class TutorialFrameListener : public ExampleFrameListener
{
protected:
OgreOde::World* mWorld;
OgreOde::StepHandler* mStepper;

public:
TutorialFrameListener(RenderWindow* win, Camera* cam, OgreOde::World* _world,
OgreOde::StepHandler* _stepper): ExampleFrameListener(win, cam), mWorld(_world), mStepper(_stepper)
{ }
bool frameEnded(const FrameEvent& evt);
};


class TutorialApplication : public ExampleApplication , public OgreOde::CollisionListener
{
protected:
public:
TutorialApplication() { }
~TutorialApplication() { }

protected:
void createScene(void);
void createFrameListener(void);
virtual bool collision(OgreOde::Contact* contact);
};


and OgreODE2.cpp


#include "OgreODE2.h"

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"

INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
TutorialApplication app;

try {
app.go();
} catch( Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
MessageBox( NULL, e.what(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
fprintf(stderr, "An exception has occurred: %s\n",
e.what());
#endif
}
return 0;
}

bool TutorialFrameListener::frameEnded(const FrameEvent& evt)
{
Real time = evt.timeSinceLastFrame;
if ( mStepper->step(time) )
mWorld->synchronise();
return ExampleFrameListener::frameEnded(evt);
}

void TutorialApplication::createFrameListener(void)
{
mFrameListener = new TutorialFrameListener(mWindow, mCamera, mWorld, mStepper);
mRoot->addFrameListener(mFrameListener);
}
void TutorialApplication::createScene(void)
{ mCamera->setPosition(13,4.5,0);
mCamera->lookAt(0,0,0);
mCamera->setNearClipDistance(0.5);
mWorld = new OgreOde::World(mSceneMgr);

mWorld->setGravity(Ogre::Vector3(0,-9.80665,0));
mWorld->setCFM(10e-5);
mWorld->setERP(0.8);
mWorld->setAutoSleep(true);
mWorld->setAutoSleepAverageSamplesCount(10);
mWorld->setContactCorrectionVelocity(1.0);
mSpace = mWorld->getDefaultSpace();

mWorld->setCollisionListener(this);
// mWorld->setShowDebugGeometries(!mWorld->getShowDebugGeometries());
// mWorld->setShowDebugContact(!mWorld->getShowDebugContact());

const Ogre::Real _time_step = 0.5;
const Ogre::Real time_scale = Ogre::Real(1.7);
const Ogre::Real max_frame_time = Ogre::Real(1.0 / 4);
mStepper = new OgreOde::StepHandler(mWorld, OgreOde::StepHandler::QuickStep,_time_step, max_frame_time,
time_scale);

mGround = new OgreOde::InfinitePlaneGeometry(Plane(Ogre::Vector3(0,1,0),0), mWorld, mWorld->getDefaultSpace());

int i = 0;
StaticGeometry* s;
s = mSceneMgr->createStaticGeometry("StaticFloor");
s->setRegionDimensions(Ogre::Vector3(160.0, 100.0, 160.0));
// Set the region origin so the center is at 0 world
s->setOrigin(Ogre::Vector3::ZERO);
for (Real z = -80.0;z <= 80.0;z += 20.0)
{
for (Real x = -80.0;x <= 80.0;x += 20.0)
{
String name = String("Ground") + StringConverter::toString(i++);
Entity* entity = mSceneMgr->createEntity(name, "plane.mesh");
entity->setQueryFlags (1<<0);
entity->setUserObject(mGround);
entity->setCastShadows(false);
s->addEntity(entity, Ogre::Vector3(x,0,z));
}
}
s->build();

mEntity = mSceneMgr->createEntity("crate","crate.mesh");
mEntity->setQueryFlags (1<<2);
mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("crate");
mNode->attachObject(mEntity);
mEntity->setCastShadows(true);

mBody = new OgreOde::Body(mWorld);
mNode->attachObject(mBody);
// Vector3 size(10.0,10.0,10.0);
Vector3 size(1.75,1.75,1.75);
OgreOde::BoxMass mMass(5.0,size);
mMass.setDensity(1.0,size);
mGeom = (OgreOde::Geometry*)new OgreOde::BoxGeometry(size, mWorld, mSpace);
mNode->setScale(size.x * 0.1,size.y * 0.1,size.z * 0.1);
mBody->setMass(mMass);

mGeom->setBody(mBody);
mEntity->setUserObject(mGeom); //Quaternion q(, Vector3::UNIT_Z);

mBody->setOrientation(Quaternion(Degree(45),Vector3::UNIT_Y));
mBody->setPosition(Vector3(0,200,-20));
}


bool TutorialApplication::collision(OgreOde::Contact* contact)
{
// Check for collisions between things that are connected and ignore them
OgreOde::Geometry * const g1 = contact->getFirstGeometry();
OgreOde::Geometry * const g2 = contact->getSecondGeometry();

if (g1 && g2)
{
const OgreOde::Body * const b1 = g1->getBody();
const OgreOde::Body * const b2 = g2->getBody();
if (b1 && b2 && OgreOde::Joint::areConnected(b1, b2))
return false;
}

return true;
}


Anoser thing that I notised is that crate is tremble if look at it from small distance.
Can you explain that?

Dino

02-04-2009 19:13:01

mmm.. the first of setDensity method parameter is so big. alter the parameter to 0.05 or erase setDensity method from your code.

Chernetcov

03-04-2009 17:34:31

Dino, Thank for help. Сhanging of setDensity, setMass or size make crate float faster or slowly, but it still sinking in the plane.
I have impression that plane have wrong elasticity, but didn't founded how to set it correctly.
And another strange think that I found is that if the crate falling down on edge it don't push off or turn over one of it's sides - it is stay on edge.
Now I try make separate class for crate and plane as in demo simplescenes. May be it will help me to understand my mistake.

Dear experts, one more question: Am I correctly understand that OgreOde::InfinitePlaneGeometry has infinitely big mass?