Force function callback problem

josericardo_jr

14-07-2006 15:44:18

Hi people,

I'm making some tests with Ogrenewt and having a problem.
Well, in my code, there's a cylinder and a box acting as a plane for my cylinder. So, in my force function callback I apply some force and it works well until my cyl get's in a position that this function isn't called anymore. I've used the function setAutofreeze to 0 but it don't work.

My code is here.


#include <Ogre.h>
#include <windows.h>
#include <OgreNewt.h>
#include "OgreKeyEvent.h"
#include "OgreEventListeners.h"
#include "OgreStringConverter.h"
#include "OgreException.h"

#include "OgreNoMemoryMacros.h"
#include "CEGUI/CEGUI.h"
#include "OgreMemoryMacros.h"

#include "OISInputManager.h"
#include "OISEvents.h"
#include "OISMouse.h"
#include "OISKeyboard.h"
#include "OISException.h"

#include "OgreCeguiRenderer.h"

#define WIN32_LEAN_AND_MEAN


Ogre::SceneNode *nodeMark = NULL;


static void _CDECL myForce( OgreNewt::Body *me )
{
Ogre::Real mass;
Ogre::Vector3 inertia;

me -> getMassMatrix( mass, inertia );
Ogre::Vector3 forceG( 0, -9.8, 0 );
Ogre::Vector3* forceP = (Ogre::Vector3*) me -> getUserData();

me -> setForce( ((*forceP) + forceG) * mass );
}




class CEGUIEventListener : public Ogre::FrameListener, public Ogre::KeyListener, public Ogre::MouseListener,
public Ogre::MouseMotionListener
{
private:
Ogre::EventProcessor *mEventProcessor;

public:
CEGUIEventListener( Ogre::RenderWindow *win )
{
mEventProcessor = new Ogre::EventProcessor();
mEventProcessor -> initialise( win );
mEventProcessor -> startProcessingEvents();
mEventProcessor -> addKeyListener( this );
mEventProcessor -> addMouseListener( this );
mEventProcessor -> addMouseMotionListener( this );

numObjects = 0;
}

~CEGUIEventListener()
{
mEventProcessor -> stopProcessingEvents();
mEventProcessor -> removeKeyListener( this );
mEventProcessor -> removeMouseListener( this );
mEventProcessor -> removeMouseMotionListener( this );
delete mEventProcessor;

}

virtual void mousePressed(Ogre::MouseEvent *e)
{
}

virtual void mouseEntered (Ogre::MouseEvent *e){}
virtual void mouseExited (Ogre::MouseEvent *e){}
virtual void mouseClicked (Ogre::MouseEvent *e){}
virtual void mouseReleased (Ogre::MouseEvent *e){}

virtual void mouseMoved (Ogre::MouseEvent *e)
{
CEGUI::Renderer *rend = CEGUI::System::getSingleton().getRenderer();
CEGUI::System::getSingleton().injectMouseMove( e -> getRelX() * rend -> getWidth(),
e -> getRelY() * rend -> getHeight() );
e -> consume();
}
virtual void mouseDragged (Ogre::MouseEvent *e){}

virtual void keyClicked (Ogre::KeyEvent *e){}
virtual void keyPressed (Ogre::KeyEvent *e){}
virtual void keyReleased (Ogre::KeyEvent *e){}

bool frameStarted( const Ogre::FrameEvent &evt )
{
return true;
}

bool frameEnded( const Ogre::FrameEvent &evt )
{
static Ogre::String objText = "Total objects traced: ";

Ogre::OverlayElement *totElem = Ogre::OverlayManager::getSingleton().getOverlayElement( "Core/WorstFps" );

totElem -> setCaption( objText + Ogre::StringConverter::toString( numObjects ) );
return true;
}

};



class myEventList : public Ogre::FrameListener, public OIS::KeyListener, public OIS::MouseListener
{
private:
OgreNewt::World *mWorld;
char tm[200];
Ogre::Camera *mCamera;
Ogre::RenderWindow *mWindow;
OIS::Mouse *mMouse;
OIS::Keyboard *mKeyboard;
Ogre::Overlay *mDebugOverlay;
Ogre::Vector2 mousePos;
Ogre::Real timer;

public:
myEventList( Ogre::RenderWindow *win, Ogre::Camera *cam, OgreNewt::World *w, Ogre::SceneManager *sm )
{
mCamera = cam;
mWindow = win;
mWorld = w;
timer = 0.0;

OIS::ParamList pl;
size_t windowHnd = 0;
std::ostringstream windowHndStr;
mWindow -> getCustomAttribute( "HWND", &windowHnd );

windowHndStr << windowHnd;
pl.insert( std::make_pair( std::string("WINDOW"), windowHndStr.str() ) );

OIS::InputManager &im = *OIS::InputManager::createInputSystem( pl );
mKeyboard = static_cast<OIS::Keyboard*>( im.createInputObject( OIS::OISKeyboard, false ) );
mMouse = static_cast<OIS::Mouse*>( im.createInputObject( OIS::OISMouse, false ) );

unsigned int width, height, depth;
int left, top;
mWindow -> getMetrics( width, height, depth, left, top );

const OIS::MouseState &ms = mMouse -> getMouseState();
ms.width = width;
ms.height = height;

mKeyboard -> setEventCallback( this );
mMouse -> setEventCallback( this );

mDebugOverlay = Ogre::OverlayManager::getSingleton().getByName( "Core/DebugOverlay" );
mDebugOverlay -> show();
}

void updateDebugOverlay()
{
static Ogre::String currFPS = "FPS Atual: ";
static Ogre::String posMouse = "Mouse Pos: ";

try
{
Ogre::OverlayElement *guiCur = Ogre::OverlayManager::getSingleton().getOverlayElement( "Core/AverageFps" );
Ogre::OverlayElement *guiMousePos = Ogre::OverlayManager::getSingleton().getOverlayElement( "Core/CurrFps" );

const Ogre::RenderTarget::FrameStats &stats = mWindow -> getStatistics();

guiCur -> setCaption( currFPS + Ogre::StringConverter::toString( stats.lastFPS ) );
guiMousePos -> setCaption( posMouse + "x: " + Ogre::StringConverter::toString( mousePos.x ) + " y: " +
Ogre::StringConverter::toString( mousePos.y ) );
}
catch(...)
{
}

}


virtual bool keyPressed( const OIS::KeyEvent &arg ){ return true; }
virtual bool keyReleased( const OIS::KeyEvent &arg ){ return true; }
virtual bool mouseMoved( const OIS::MouseEvent &arg ){ return true; }
virtual bool mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id ){ return true; }
virtual bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id ){ return true; }

~myEventList()
{
OIS::InputManager *im = OIS::InputManager::getSingletonPtr();

if ( im )
{
im -> destroyInputObject( mKeyboard );
im -> destroyInputObject( mMouse );
im -> destroyInputSystem();
im = 0;
}
}

bool processUnbufferedKeyboard( const Ogre::FrameEvent &evt )
{
if ( mKeyboard -> isKeyDown( OIS::KC_F3 ) )
OgreNewt::Debugger::getSingleton().showLines( mWorld );

if ( mKeyboard -> isKeyDown( OIS::KC_F4 ) )
OgreNewt::Debugger::getSingleton().hideLines();

if ( mKeyboard -> isKeyDown( OIS::KC_ESCAPE ) )
return false;

return true;
}

bool processUnbufferedMouse( const Ogre::FrameEvent &evt )
{
const OIS::MouseState &ms = mMouse -> getMouseState();
mousePos.x = ms.relX;
mousePos.y = ms.relY;

if ( ms.buttonDown( OIS::MB_Left ) )
{
Ogre::Vector3 start, end;
CEGUI::Point mouse = CEGUI::MouseCursor::getSingleton().getPosition();
CEGUI::Renderer *rend = CEGUI::System::getSingleton().getRenderer();

Ogre::Real mx, my;
mx = mouse.d_x / rend -> getWidth();
my = mouse.d_y / rend -> getHeight();

Ogre::Ray camRay = mCamera -> getCameraToViewportRay( mx, my );
start = camRay.getOrigin();
end = camRay.getPoint( 500.0 );

OgreNewt::BasicRaycast *ray = new OgreNewt::BasicRaycast( mWorld, start, end );
OgreNewt::BasicRaycast::BasicRaycastInfo info = ray -> getFirstHit();

if (info.mBody )
{
if ( info.mBody -> getType() == 1 )
{
//if ( currNode == NULL )
//{

Ogre::Node *parent = nodeMark -> getParent();
if ( parent == NULL )
{
info.mBody -> getOgreNode() -> addChild( nodeMark );
nodeMark -> setVisible( true );
}
else
{
if ( parent == info.mBody -> getOgreNode() )
{
Ogre::Vector3* force;
force = (Ogre::Vector3*)info.mBody -> getUserData();
(*force) = nodeMark -> getOrientation() * Ogre::Vector3( 500, 0, 500 );
parent -> removeChild( nodeMark );
nodeMark -> setVisible( false );
}
else
{
parent -> removeChild( nodeMark );
info.mBody -> getOgreNode() -> addChild( nodeMark );
}
}
}
}
delete ray;
ray = NULL;
}

Ogre::Node *parent = nodeMark -> getParent();

if ( ms.buttonDown( OIS::MB_Right ) )
{
if ( parent != NULL )
{
parent -> removeChild( nodeMark );
nodeMark -> setVisible( false );
}
}
return true;
}



virtual bool frameStarted( const Ogre::FrameEvent &evt )
{
mKeyboard -> capture();
mMouse -> capture();
timer -= evt.timeSinceLastFrame;

if ( !processUnbufferedKeyboard( evt ) ) return false;

if ( timer < 0 )
{
processUnbufferedMouse( evt );
timer = 0.1;
}

return true;
}

virtual bool frameEnded( const Ogre::FrameEvent &evt )
{
updateDebugOverlay();

nodeMark -> yaw( Ogre::Radian( Ogre::Degree( -100 * evt.timeSinceLastFrame ) ) );

return true;
}
};


class OgreTests
{
private:
OgreNewt::World *mWorld;
Ogre::FrameListener *newton;
Ogre::Root *mRoot;
Ogre::Camera *mCamera;
Ogre::SceneManager *mSceneMgr;
Ogre::RenderWindow *mWindow;
bool startedOK;
CEGUI::OgreCEGUIRenderer *mGuiRenderer;
OgreNewt::MaterialID *matBox;
OgreNewt::MaterialPair *pairBoxDef;

public:
OgreTests() {
mRoot = new Ogre::Root();

setupResources();

if ( mRoot -> showConfigDialog() )
{
mWindow = mRoot -> initialise( true );
startedOK = true;

mSceneMgr = mRoot -> createSceneManager( Ogre::ST_GENERIC, "ExampleSM" );

mCamera = mSceneMgr -> createCamera( "PlayerCam" );
mCamera -> setPosition( -355.0, 95.0, 0.84 );
mCamera -> setOrientation( Ogre::Quaternion( 0.70, -0.15, -0.68, -0.14 ) );
mCamera -> setNearClipDistance( 5.0 );

// Create Viewport
Ogre::Viewport *vp = mWindow -> addViewport( mCamera );
vp -> setBackgroundColour( Ogre::ColourValue::Black );

mCamera -> setAspectRatio(
Ogre::Real( vp -> getActualWidth() ) / Ogre::Real( vp -> getActualHeight() ) );

Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
}
else
{
startedOK = false;
}

mWorld = new OgreNewt::World();
}

~OgreTests(){
delete mWorld;
OgreNewt::Debugger::getSingleton().deInit();

CEGUI::System *sys = CEGUI::System::getSingletonPtr();
delete sys;
delete mGuiRenderer;
delete mRoot;
}

void go()
{
createScene();
createFrameListener();
mRoot -> startRendering();
}

protected:

void setupResources()
{
Ogre::ConfigFile cf;
cf.load("resources.cfg");

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

Ogre::String secName, typeName, archName;
while (seci.hasMoreElements())
{
secName = seci.peekNextKey();
Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
Ogre::ConfigFile::SettingsMultiMap::iterator i;
for (i = settings->begin(); i != settings->end(); ++i)
{
typeName = i->first;
archName = i->second;
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
archName, typeName, secName);
}
}
}


void createScene(void)
{
mGuiRenderer = new CEGUI::OgreCEGUIRenderer( mWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 3000, mSceneMgr );
new CEGUI::System( mGuiRenderer );

try
{
CEGUI::Logger::getSingleton().setLoggingLevel( CEGUI::LoggingLevel::Insane );

CEGUI::SchemeManager::getSingleton().loadScheme( (CEGUI::utf8*) "WindowsLook.scheme" );
CEGUI::System::getSingleton().setDefaultMouseCursor( (CEGUI::utf8*) "WindowsLook", (CEGUI::utf8*) "MouseArrow" );
CEGUI::System::getSingleton().setDefaultFont( (CEGUI::utf8*) "Commonwealth-10" );

CEGUI::Window *sheet = CEGUI::WindowManager::getSingleton().createWindow( (CEGUI::utf8*) "DefaultWindow", (CEGUI::utf8*) "root_wnd" );
CEGUI::System::getSingleton().setGUISheet( sheet );
}
catch( CEGUI::Exception )
{
}


Ogre::Entity *tableSideA = mSceneMgr -> createEntity( "tableSideA", "SideA.mesh" );
Ogre::Entity *tableSideB = mSceneMgr -> createEntity( "tableSideB", "SideB.mesh" );
Ogre::Entity *button = mSceneMgr -> createEntity( "button", "Button.mesh" );
Ogre::Entity *mark = mSceneMgr -> createEntity( "mark", "Mark.mesh" );

Ogre::SceneNode *nodeTableSideA = mSceneMgr -> getRootSceneNode() -> createChildSceneNode();
Ogre::SceneNode *nodeTableSideB = mSceneMgr -> getRootSceneNode() -> createChildSceneNode();
Ogre::SceneNode *nodeButton = mSceneMgr -> getRootSceneNode() -> createChildSceneNode();
nodeMark = mSceneMgr -> createSceneNode();

nodeTableSideA -> attachObject( tableSideA );
nodeTableSideB -> attachObject( tableSideB );
nodeButton -> attachObject( button );
nodeMark -> attachObject( mark );
nodeMark -> setVisible( false );


OgreNewt::Collision *col = new OgreNewt::CollisionPrimitives::Box( mWorld, Ogre::Vector3( 500, 10, 500 ) );
OgreNewt::Body *bdy = new OgreNewt::Body( mWorld, col );
bdy -> setMassMatrix( 0, Ogre::Vector3::ZERO );
bdy -> setPositionOrientation( Ogre::Vector3::ZERO, Ogre::Quaternion::IDENTITY );
delete col;


OgreNewt::Collision *col2 = new OgreNewt::CollisionPrimitives::Cylinder( mWorld, 6.0, 2.0,
Ogre::Quaternion( Ogre::Radian( Ogre::Degree( 90.0 ) ), Ogre::Vector3::UNIT_Z ),
Ogre::Vector3( 0, 1.0, 0.0 ));
OgreNewt::Body *bd = new OgreNewt::Body( mWorld, col2, 1 );
bd -> setPositionOrientation( Ogre::Vector3( -80.0, 20.0, 0.0 ), Ogre::Quaternion::IDENTITY );//Ogre::Quaternion( Ogre::Radian( Ogre::Degree( -90.0 ) ), Ogre::Vector3::UNIT_Z ) );
bd -> setUserData( new Ogre::Vector3( -10, 0, 0 ) );
Ogre::Vector3 inertia = OgreNewt::MomentOfInertia::CalcCylinderSolid( 10, 6, 2 );
bd -> setMassMatrix( 1, inertia );
bd -> attachToNode( nodeButton );
bd -> setCustomForceAndTorqueCallback( myForce );
bd -> setAutoFreeze( 0 );
delete col2;

}

void createFrameListener()
{
myEventList *evt = new myEventList( mWindow, mCamera, mWorld, mSceneMgr );
mRoot -> addFrameListener( evt );

newton = new OgreNewt::BasicFrameListener( mWindow, mSceneMgr, mWorld, 60 );
mRoot -> addFrameListener( newton );

CEGUIEventListener *list = new CEGUIEventListener( mWindow );
mRoot -> addFrameListener( list );
}


};


INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
{
// Create application object
OgreTests app;



try {
app.go();
} catch( Ogre::Exception& e ) {

MessageBox( NULL, (LPCWSTR)e.getFullDescription().c_str(), (LPCWSTR)"An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
}

return 0;
}


Any suggestion?

Thanks a lot!!!

Ricardo

HexiDave

14-07-2006 19:26:33

You might be having your objects outside the World bounds - try this after you create the World:

Vector3 size = Vector3(1000,1000,1000);
mWorld->setWorldSize(-size,size);


That should increase the bounds to 2000x2000x2000.

josericardo_jr

16-07-2006 13:18:45

Hi HexiDave,

Thanks a lot!!

This solve my problem. :D

Ricardo