Why is OgreOde::World a singleton?

Dirso

01-01-2007 20:15:45

Hi,

That's basicly my question. How to work with serveral game levels if I can't change the scene manager? Anyone has done anything like that before?

Thanks a lot and Happy New Year!
Dirso

luis

02-01-2007 08:17:18

you should delete just game objects (or hide them) on each level if you need, my advice is not create/delete World, scenemanager, etc (for each level) instead, build everything once at the begining making your own World deriving from OgreOde::World, put all your game objects in a container (i.e. std::map) and when you dont need them anymore, just iterate through the container hiding them or deleting.
See Ogre demo: BSP collision.

Anyway in the next version of OgreOde, World is not singleton anymore.

Dirso

02-01-2007 23:45:39

Hi,

Could you help me a little bit with the code? I have this error on my PlayState class - and thats where I use the OgreOde::World

PlayState.cpp#include "Ogre.h"
#include "OgreKeyEvent.h"

#include "PlayState.h"
#include "MainMenuState.h"

using namespace Ogre;

PlayState PlayState::mPlayState;

void PlayState::enter()
{
mRoot = Root::getSingletonPtr();

//init
_track = 0;

mSceneMgr = mRoot->createSceneManager(ST_GENERIC);

// Create the camera for player one
mCamera[0] = mSceneMgr->createCamera("PlayerCam");
mCamera[0]->setPosition(Vector3(125,-14,8));
mCamera[0]->lookAt(mCamera[0]->getPosition() + Vector3(0,0,1));
mCamera[0]->setNearClipDistance( 1 );
mCamera[0]->setFarClipDistance( 1000 );
/*
// should I create the camera for the second player?
if(_idHumanPlayers[1] >= 0)
{
// Create the camera for player one
mCamera[1] = mSceneMgr->createCamera("PlayerCam2");
mCamera[1]->setPosition(Vector3(125 - DIF_SIDE_GRID,-14,8));
mCamera[1]->lookAt(mCamera[0]->getPosition() + Vector3(0,0,1));
mCamera[1]->setNearClipDistance( 1 );
mCamera[1]->setFarClipDistance( 1000 );
//adcionar os dois viewports
}
else*/
{
mViewport = mRoot->getAutoCreatedWindow()->addViewport(mCamera[0]);
mCamera[1] = 0;
}

// Set ambient light
mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
mSceneMgr->setSkyBox(true,_skyFile);

// Create a light
Light* l = mSceneMgr->createLight("MainLight");

// Accept default settings: point light, white diffuse, just set position
// NB I could attach the light to a SceneNode if I wanted it to move automatically with
// other objects, but I don't
l->setPosition(20,800,50);
l->setSpecularColour(1,0.9,0);

l->setCastShadows(true);

mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE);
mSceneMgr->setShadowColour(ColourValue(0.5,0.5,0.5));

_world = new OgreOde::World(mSceneMgr);

_world->setGravity(Vector3(0,-9.80665,0));
_world->setCFM(10e-5);
_world->setERP(0.8);
_world->setAutoSleep(true);
_world->setContactCorrectionVelocity(1.0);

// Create something that will step the world automatically
_world->setCollisionListener(this);

SceneNode *track_node = mSceneMgr->getRootSceneNode()->createChildSceneNode("track");
Entity *track_mesh = mSceneMgr->createEntity("track",_trackFile + ".mesh");
track_node->attachObject(track_mesh);

OgreOde::EntityInformer ei(track_mesh);
_track = ei.createStaticTriangleMesh(_world->getDefaultSpace());

_stepper = new OgreOde::ForwardFixedInterpolatedQuickStepper (_time_step);

_stepper->setAutomatic(OgreOde::Stepper::AutoMode_PostFrame, mRoot);

Root::getSingleton().setFrameSmoothingPeriod(5.0f);

// create all cars
// Move the vehicle
Vector3 v_pos = mCamera[0]->getPosition() + (mCamera[0]->getDirection() * 15.0);
Vector3 v_pos2 = v_pos;
v_pos2.x -= DIF_SIDE_GRID;
v_pos2.z -= DIF_1_2_GRID;

Vector3 v_pos3;
// start the vehicle
for ( int i = 0; i < _numOfCars; i++)
{
v_pos3 = (i%2)?v_pos2:v_pos;
_vehiclePlayer[i] = new VehiclePlayer();
v_pos3.y = -15.015;
_vehiclePlayer[i]->InitVehicle(v_pos3, _carNames[i] + ".ogreode",
_carNames[i],_vpt[i], (i == _idHumanPlayers[0])?mCamera[0]:0);
if(i%2)
{
v_pos2.z -= DIF_PARS_GRID;
v_pos.z -= DIF_PARS_GRID;
}
// start its variables
//_vehiclePlayer[i]->_lt.StartLapCounter(_ckPoint.getCheckPointCount());
}
// set 2 human controls
if(_idHumanPlayers[1])
{
_vehiclePlayer[_idHumanPlayers[1]]->SetKeyCmd(Ogre::KC_NUMPAD8, Ogre::KC_NUMPAD2,
Ogre::KC_NUMPAD4, Ogre::KC_NUMPAD6);
}

// this line is dangerous
// remove it when the game is running
_canMove = true;

mRoot->startRendering();
}

void PlayState::exit()
{
delete _stepper;
delete _track;
//delete _world;

mSceneMgr->clearScene();
mSceneMgr->destroyAllCameras();
mRoot->getAutoCreatedWindow()->removeAllViewports();

std::cout << "PlayState exit\n";
}

void PlayState::pause()
{
std::cout << "PlayState pause\n";
}

void PlayState::resume()
{
mViewport->setBackgroundColour(ColourValue(0.0, 0.0, 1.0));

std::cout << "PlayState resume\n";
}

bool PlayState::frameStarted(GameManager* game, const FrameEvent& evt)
{
Ogre::InputReader* id = InputManager::getSingletonPtr()->getInputDevice();

id->capture();

Real time = evt.timeSinceLastFrame;
game->mTimeUntilNextToggle -= time;

if (game->mTimeUntilNextToggle <= 0)
{
if(id->isKeyDown(KC_ESCAPE))
{
// at this point a menu should be displayed
game->mTimeUntilNextToggle = TIMETONEXTTOGGLE;
game->changeState(MainMenuState::getInstance());
return true;
}

}

if(!_stepper->isPaused())
{
// update all cars
int nHumans = 0;
for (int i = 0; i < _numOfCars; i++)
{
if(_vehiclePlayer[i]->getVPT() == VehiclePlayer::VPT_Human)
{
if ((nHumans < game->getNumJoySticks()) && game->g_joys[nHumans]
&& (_idHumanPlayers[nHumans] == i))
{
game->g_joys[i]->capture();
const OIS::JoyStickState &joy = game->g_joys[i]->getJoyStickState();
Real steering = 0.0, rBreak = 0.0, rThrottle = 0.0;
int abx = joy.mAxes[0].abX, aby = joy.mAxes[0].abY;
if (abx < -2500)
{
//steering = -1.0;
if (abx < -16000)
{
steering = -1.0;
}
else
{
steering = -0.5;
}
}
else if (abx > 2500)
{
if (abx > 16000)
{
steering = 1.0;
}
else
{
steering = 0.5;
}
}
if (aby < -2500)
{
rThrottle = 1.0;
}
else if (aby > 2500)
{
rBreak = -1.0;
}
if(_canMove)
{
_vehiclePlayer[i]->ProcessKeyboard(steering, rBreak, rThrottle, time);
}
}
else
{
if(_canMove)
{
_vehiclePlayer[i]->ProcessKeyboard(id, time);
}
}
_vehiclePlayer[i]->UpdateCameraPos();
nHumans++;
}
}
}

return true;
}

bool PlayState::frameEnded(GameManager* game, const FrameEvent& evt)
{
return true;
}

bool PlayState::collision(OgreOde::Contact* contact)
{
if(!OgreOde_Prefab::Vehicle::handleTyreCollision(contact))
{
contact->setBouncyness(0.0);
contact->setCoulombFriction(18.0);
}
return true;
}

void PlayState::resetPlayers()
{
// reset players
for(int i = 0; i < NUM_OF_CARS_MAX; i++)
{
_vpt[i] = VehiclePlayer::VPT_Undef;
}
for(int i = 0; i < NUM_OF_HUMANS; i++)
{
_idHumanPlayers[i] = -1;
}
_numOfCars = 0;
_numHumanPlayers = 0;
}


void PlayState::setGame(String trackFile, String skyFile)
{
// scene
_trackFile = trackFile;
_skyFile = skyFile;
}

void PlayState::AddVehicle(VehiclePlayer::VehiclePlayerType vpt, String sCarName)
{
_vpt[_numOfCars] = vpt;
_carNames[_numOfCars] = sCarName;
if(vpt == VehiclePlayer::VPT_Human)
{
_idHumanPlayers[_numHumanPlayers++] = _numOfCars;
}
_numOfCars++;
}


PlayState.h#ifndef PlayState_H
#define PlayState_H

#include "Ogre.h"

#include "OgreOde_Core.h"
#include "OgreOde_Prefab.h"

#include "GameState.h"
#include "VehiclePlayer.h"

class PlayState : public GameState, public OgreOde::CollisionListener
{
public:

void enter();
void exit();

void pause();
void resume();

bool frameStarted(GameManager* game, const Ogre::FrameEvent& evt);
bool frameEnded(GameManager* game, const Ogre::FrameEvent& evt);

// set running variables
void setGame(String trackFile, String skyFile);
void AddVehicle(VehiclePlayer::VehiclePlayerType vpt, String sCarName);

static PlayState* getInstance() { return &mPlayState; }
protected:

PlayState()
{
_time_step = TIME_STEP;
_trackFile = "racingcircuit";
_skyFile = "GranTurismOgre/Skybox";
_canMove = false;
_world = 0;

resetPlayers();
}

~PlayState() { }

bool collision(OgreOde::Contact* contact);

void resetPlayers();

Ogre::Root *mRoot;
Ogre::SceneManager* mSceneMgr;
Ogre::Viewport* mViewport, *mViewportP2;
Ogre::Camera* mCamera[3];

OgreOde::World *_world;
VehiclePlayer *_vehiclePlayer[NUM_OF_CARS_MAX];
OgreOde::TriangleMeshGeometry *_track;
OgreOde::Stepper *_stepper;

OgreOde_Prefab::OgreOdeDotLoader dotOgreOdeLoader;

Real _time_step;

// real set variables
int _numOfCars, _numHumanPlayers;
VehiclePlayer::VehiclePlayerType _vpt[NUM_OF_CARS_MAX];
String _carNames[NUM_OF_CARS_MAX];
int _idHumanPlayers[NUM_OF_HUMANS];
String _trackFile, _skyFile;
bool _canMove;

private:
static PlayState mPlayState;
};

#endif


The error is in the "exit()" function

Thanks a lot,
Dirso

luis

03-01-2007 12:35:12

Could you help me a little bit with the code? I have this error on my PlayState class

what is the error ?

i asume you have an error deleting the world.....
first in every exit() i would put something like..


if( pointer )
{
delete pointer;
pointer = 0;
}


to avoid deleting twice.
I'm not sure, but gamestate calls exit when you change from one state to another and when you shutdown (or in ~GameStateManager()).
if you still have an error, try moving world deletion to the end of GameStateManager::start......

may be this question should be in Main forum...
i hope this helps ;)