[Bleeding] help with variable scene controller

CHICO

13-05-2008 20:19:05

I'm trying to integrate NxOgre into a simulator that I'm modifying. I want to use my own time controller because the simulator has a variable timestep length and, most of the time, it is run with graphics turned off. I still want the ability to use NxOgre for visualization for demo purposes.

Here is what I have so far:

"SimulationPhysics.h"


namespace Ogre
{
class Root;
class RenderSystem;
class RenderWindow;
class SceneManager;
class Camera;
class Viewport;
class Light;
};

namespace NxOgre
{
class World;
class Scene;
class Body;
};

class MyTimeController;

/// NxOgre interface class
class SimulationPhysics
{
protected:
Ogre::Root *root; ///< OGRE starting point
Ogre::RenderSystem *renderSystem; ///< OGRE rendering system
Ogre::RenderWindow *window; ///< OGRE rendering window
Ogre::SceneManager *sceneManager; ///< Used for managing all objects in the scene (like the camera)
Ogre::Camera *camera; ///< Visualization camera
Ogre::Viewport *viewport; ///< Viewport for the camera
Ogre::Light *light; ///< Light source

void initGraphics(); ///< Initialize OGRE for NxOgre physics visualization
void initControls(); ///< Initialize OIS controls for NxOgre physics visualization
void initScene(); ///< Initialize OGRE scene for NxOgre physics visualization
void start(); ///< Start the NxOgre physics simulation

public:
NxOgre::World *world; ///< Pointer to physics world information
NxOgre::Scene *scene; ///< Physics scene information
NxOgre::Body *testBody;
MyTimeController *time; ///< Physics time controller

SimulationPhysics(); ///< Basic constructor
SimulationPhysics(MyTimeController *tc);///< Constructor with time controller
~SimulationPhysics(); ///< Destructor
};




"SimulationPhysics.cpp"


#include "Ogre.h"
#include "NxOgre.h"
#include "MyTimeController.h"
#include "SimulationPhysics.h"
#include "CakeOgre.h"

/// Basic constructor
/// Input:
/// void
/// Output:
/// void
SimulationPhysics::SimulationPhysics()
{
// Initialize OGRE for NxOgre physics visualization
initGraphics();
// Initialize OIS controls for NxOgre physics visualization
initControls();
// Initialize OGRE scene for NxOgre physics visualization
initScene();
// Start the NxOgre physics simulation
start();
}

/// Constructor with time controller
/// Input:
/// tc
/// Output:
/// void
SimulationPhysics::SimulationPhysics(MyTimeController *tc)
{
//Set TimeController
time = tc;

// Initialize OGRE for NxOgre physics visualization
initGraphics();
// Initialize OIS controls for NxOgre physics visualization
initControls();
// Initialize OGRE scene for NxOgre physics visualization
initScene();
// Start the NxOgre physics simulation
start();
}

/// Basic destructor
/// Input:
/// void
/// Output:
/// void
SimulationPhysics::~SimulationPhysics()
{
if(world) delete world;
}

/// Initialize OGRE for NxOgre physics visualization
/// Input:
/// void
/// Output:
/// void
void SimulationPhysics::initGraphics()
{
//Init Root
root = new Ogre::Root("","","ogre.log");

//Load different plugins if in debug mode
#ifdef _DEBUG
root->loadPlugin("RenderSystem_GL_d");
root->loadPlugin("RenderSystem_Direct3D9_d");
root->loadPlugin("Plugin_ParticleFX_d");
root->loadPlugin("Plugin_CgProgramManager_d");
#else
root->loadPlugin("RenderSystem_GL");
root->loadPlugin("RenderSystem_Direct3D9");
root->loadPlugin("Plugin_ParticleFX");
root->loadPlugin("Plugin_CgProgramManager");
#endif

//Allocate resource manager
Ogre::ResourceGroupManager* rgm = Ogre::ResourceGroupManager::getSingletonPtr();
Ogre::String resourceLocation = "media/";

//This tends to get messed up alot. Print directory info.
{
char temp[500];
GetCurrentDirectory(500,temp);
std::cout << "Looking for media at:" << temp << resourceLocation << std::endl;
}

//Add resources
rgm->addResourceLocation(resourceLocation + "cake.zip", "Zip");
rgm->addResourceLocation(resourceLocation + "meshes", "FileSystem");
rgm->addResourceLocation(resourceLocation + "materials", "FileSystem");
rgm->addResourceLocation(resourceLocation + "images", "FileSystem");
rgm->addResourceLocation(resourceLocation + "gui", "FileSystem");
rgm->addResourceLocation(resourceLocation + "other", "FileSystem");

//Locate and set rendering system. It prefers Direct3D9.
Ogre::RenderSystemList* renderSystems = root->getAvailableRenderers();
renderSystem = 0;
for (Ogre::RenderSystemList::iterator it = renderSystems->begin(); it != renderSystems->end(); it++)
{
renderSystem = *it;
if (renderSystem->getName() == "Direct3D9 Rendering Subsystem") break;
}
if (renderSystem == 0) std::cout << "Cannot locate Rendering Subsystem" << std::endl;
root->setRenderSystem(renderSystem);

//Configure the rendering system
renderSystem->setConfigOption("Full Screen", "No");
renderSystem->setConfigOption("VSync", "No");
std::stringstream strVideoMode;
strVideoMode << 1024 << " x " << 768 << " @ " << 32 << "-bit colour";
renderSystem->setConfigOption("Video Mode", strVideoMode.str());

//Create the visualization window
window = root->initialise(true, "SIM");
Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(1);
Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(Ogre::TFO_ANISOTROPIC);
Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(8);
Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

return;
}

/// Initialize OGRE for NxOgre physics visualization
/// Input:
/// void
/// Output:
/// void
void SimulationPhysics::initControls()
{
//Find the window
size_t window_handle;
window->getCustomAttribute("WINDOW", &window_handle);
std::ostringstream window_handle_string;
window_handle_string << window_handle;

//FIXME disable controls for now
//OIS::ParamList ois_params;
//ois_params.insert(std::make_pair(std::string("WINDOW"), window_handle_string.str()));
//mInputManager = InputManager::createInputSystem(ois_params);
//mKeyboard = static_cast<Keyboard*>(mInputManager->createInputObject( OISKeyboard, false ));
//mMouse = static_cast<Mouse*>(mInputManager->createInputObject( OISMouse, false));

return;
}

/// Initialize the scene NxOgre physics visualization
/// Input:
/// void
/// Output:
/// void
void SimulationPhysics::initScene()
{
//sceneManager creation
sceneManager = root->createSceneManager(Ogre::ST_GENERIC, "SIM");

//Create camera
camera = sceneManager->createCamera("Camera");
//Create viewport and associate with window
viewport = window->addViewport(camera);
viewport->setBackgroundColour(Ogre::ColourValue::Black);

//Set Camera options
camera->setAspectRatio(Ogre::Real(viewport->getActualWidth()) / Ogre::Real(viewport->getActualHeight()));
camera->setPosition(12,12,12);
camera->lookAt(0,1,0);
camera->setNearClipDistance(0.05f);

//Create light and set
sceneManager->setAmbientLight(Ogre::ColourValue(0.8,0.8,0.8));
light = sceneManager->createLight("Light");
light->setType(Ogre::Light::LT_SPOTLIGHT);
light->setPosition(50,20,50);
light->setSpotlightRange(Ogre::Degree(30), Ogre::Degree(50));
Ogre::Vector3 dir(-light->getPosition());
dir.normalise();
light->setDirection(dir);
light->setDiffuseColour(0.35, 0.35, 0.35);
light->setSpecularColour(0.9, 0.9, 0.9);

//Set shadows
sceneManager->setShadowTechnique(Ogre::SHADOWTYPE_TEXTURE_MODULATIVE);
Ogre::ShadowCameraSetupPtr shadows(new Ogre::LiSPSMShadowCameraSetup());
sceneManager->setShadowTexturePixelFormat(Ogre::PF_L8);
sceneManager->setShadowTextureCasterMaterial(Ogre::StringUtil::BLANK);
sceneManager->setShadowTextureReceiverMaterial(Ogre::StringUtil::BLANK);
sceneManager->setShadowTextureSelfShadow(false);
sceneManager->setShadowColour(Ogre::ColourValue(0.6, 0.6, 0.6));
sceneManager->setShadowTextureSize(2048);
sceneManager->setShadowFarDistance(72);
sceneManager->setShadowCameraSetup(shadows);

return;
}

/// Start the NxOgre physics
/// Input:
/// void
/// Output:
/// void
void SimulationPhysics::start()
{
//Create World and main scene
NxOgre::PhysXParams params;
params.mTimeController = NxOgre::PhysXParams::TC_PTR;
params.mCustomTimeControllerPtr = time;
world = new NxOgre::World(params);

//attach PhysX driver to time controller
time->physXDriver = world->getPhysXDriver();

//Create physics scene
scene = world->createScene("SIM","renderer: ogre, gravity: no, floor: no, controller: variable");

//Add test object to the scene
testBody = scene->createBody("Boo; cube.1m.mesh", new Cube(1), Vector3(0.5f, 0.5f, 0.5f), ActorParams("Mass: 10"));
time->testBody = testBody;
}



"MyTimeController.h"


#include "NxOgreTimeController.h"

namespace NxOgre
{
class PhysXDriver;
class Body;
};

///Time controller class. Used to control physics simulation.
class MyTimeController : public NxOgre::TimeController
{
public:
double currentTime; ///< Current simulation time
double timeStep; ///< Length of the timestep
NxOgre::PhysXDriver *physXDriver; ///< Stores the pointer to the physics simulator
NxOgre::Body *testBody;

MyTimeController(); ///< Basic constructor
MyTimeController(double ts); ///< Constructor with timestep specified
MyTimeController(NxOgre::PhysXDriver *driver,double ts);///< Constructor to use with physics simulator
~MyTimeController(); ///< Basic destructor

bool nextTimeStep(); ///< Advance clock
};



"MyTimeController.cpp"


#include "NxOgreTimeController.h"
#include "NxOgrePhysXDriver.h"
#include "NxOgreBody.h"
#include "NxVec3.h"
#include "MyTimeController.h"


/// Basic constructor
/// Input:
/// void
/// Output:
/// void
MyTimeController::MyTimeController()
: currentTime(0)
, timeStep(0)
, physXDriver(0)
{}

/// Conmstructor with timestep initialization
/// Input:
/// ts: timestep length (seconds)
/// Output:
/// void
MyTimeController::MyTimeController(double ts)
: currentTime(0)
, timeStep(ts)
, physXDriver(0)
{}

/// Conmstructor with timestep initialization
/// Input:
/// ts: timestep length (seconds)
/// driver: PhysX driver
/// Output:
/// void
MyTimeController::MyTimeController(NxOgre::PhysXDriver *driver, double ts)
: currentTime(0)
, timeStep(ts)
, physXDriver(driver)
{}

/// Basic destructor
/// Input:
/// void
/// Output:
/// void
MyTimeController::~MyTimeController()
{}

/// Advance the clock one timestep
/// Input:
/// void
/// Output:
/// void
bool MyTimeController::nextTimeStep()
{
currentTime += timeStep;

testBody->moveTowards(NxVec3(0.5f*currentTime, 0.5f*currentTime, .5f*currentTime));
physXDriver->simulate(timeStep);
physXDriver->render(timeStep);
return true;
}



The problem that I'm having is that this line hangs when MyTimeController::nextTimeStep() runs (timeStep = 1.0/60.0):


physXDriver->simulate(timeStep);



I've run it in the debugger, and its getting stuck at the loop at line 115 of NxOgreSceneController:


while (!mNxScene->fetchResults(NX_RIGID_BODY_FINISHED,false))
;


Sorry for the long post. I would appreciate any and all help on how to proceed. Thanks.

betajaen

13-05-2008 20:22:52

It may be a bug with the VariableSceneController. Have you tried the accumulator with your code? If that works then the loop is causing the hanging.

CHICO

13-05-2008 20:31:28

It may be a bug with the VariableSceneController. Have you tried the accumulator with your code? If that works then the loop is causing the hanging.

No, I haven't tried that yet. I'll give it a go and post how it turns out.

CHICO

14-05-2008 23:10:32

It may be a bug with the VariableSceneController. Have you tried the accumulator with your code? If that works then the loop is causing the hanging.

No, I haven't tried that yet. I'll give it a go and post how it turns out.


Well, I tried using the accumulator, and it now hangs within the fetchResults() call on line 251 of NxOgreSceneController.cpp:

mNxScene->fetchResults(NX_RIGID_BODY_FINISHED, true);


I've run it in the PhysX debugger and this is what it looks like when my application hangs (I've added some more objects to the scene):


Whats weird is that it looks like its setting up the scene fine. Also, cake still works as intended, so I don't think I have a corrupted installation. You think there's maybe an issue with how I'm setting up my Scene or World parameters?

betajaen

15-05-2008 00:44:59

Very strange. The only concern I have is that the "time" variable may be uninitialized or the deltaTime injected is a weird number.

And this number:

namespace NxOgre
{
class PhysXDriver;
class Body;
};


Forward declaration is okay, but I would include NxOgre.h just in-case. If worse comes to worst, you can not use the TimeController, and just use simulate/render directly. Just set mTimeController to TC_NONE.