OgreNewt - PLSM2 Wiki Tutorial problem

Syphius

14-06-2006 23:27:31

Hello,

I Tried to implement the wiki tutorial : http://www.ogre3d.org/wiki/index.php/Us ... ith_Newton

But it's not working for me, Object fall through the Terrain :(.

So Does Anyone have a piece of code that work for this tutorial or something similar?

Please Help ! :'(

Syphius

HexiDave

14-06-2006 23:48:44

I just re-implemented it today, I'll try to gut the code and post it here (think I did before...)

In the mean-time, your world is probably too small. Add this after you create your world:

mWorld->setWorldSize(AxisAlignedBox(-100000,-100000,-100000,100000,100000,100000));

Set the world size to whatever you need, but it really doesn't effect speed from what I can tell, just calculates all physics objects moving through that space. Also, while it may chew up your CPU cycles, hit F3 (if you're using OgreNewt's built-in framelistener) to see if you even have any TreeCollisions loaded on your terrain. If you're not seeing a blinding amount of white lines across your terrain, your code is borked.

HexiDave

15-06-2006 04:18:15

Ok, in advance - this may be too big for the forum so I may just host the files somewhere if this becomes too much (or post a revised PLSM2/OgreNewt Wiki) -

Here's the primary file - mine is broken into headers/c++ files, but this is all one deal:

//Ogre
#include "Ogre.h"
#include "OgreConfigFile.h"
#include "OgreKeyEvent.h"
#include "OgreEventListeners.h"
#include "OgreStringConverter.h"
#include "OgreException.h"
#include "OgrePrerequisites.h"

//PLSM2
#include "OgrePagingLandScapeOptions.h"
#include "OgrePagingLandScapeCamera.h"
#include "OgrePagingLandScapeData2DManager.h"
#include "OgrePagingLandScapeRenderableManager.h"
#include "OgrePagingLandScapeTextureCoordinatesManager.h"
#include "OgrePagingLandScapeRenderable.h"
#include "OgrePagingLandScapeTextureManager.h"
#include "OgrePagingLandScapeTexture.h"
#include "OgrePagingLandScapePageManager.h"
#include "OgrePagingLandScapeTile.h"
#include "OgrePagingLandScapeTileInfo.h"
#include "OgrePagingLandScapeTileManager.h"
#include "OgrePagingLandScapeRenderable.h"
#include "OgrePagingLandScapeRenderableManager.h"
#include "OgrePagingLandScapeRaySceneQuery.h"
#include "OgrePagingLandScapeCamera.h"

#include "OgrePagingLandScapeListenerManager.h"

#include "OgrePagingLandScapeSceneManager.h"

#include "OgrePagingLandScapeHorizon.h"

using namespace Ogre;
using namespace std;
#include <OgreNewt.h>

class PhysicsManager
{
public:
PhysicsManager();
~PhysicsManager();

OgreNewt::World* getWorld();
void deleteTileBodies(const String& tileData);
OgreNewt::Body* getTileBodies(const String& tileData);
void loadTerrainGeometry(PagingLandScapeTile* tile, Vector3* vertices, int numVertices, IndexData* indexData);


protected:
OgreNewt::World *mWorld;
map<String,OgreNewt::Body*> tileBodies;


private:
};

PhysicsManager::PhysicsManager(){
mWorld = new OgreNewt::World();
mWorld->setWorldSize(AxisAlignedBox(-100000,-100000,-100000,100000,100000,100000));

}

PhysicsManager::~PhysicsManager(){
mWorld = 0;
delete mWorld;

}

OgreNewt::World* PhysicsManager::getWorld(){
return mWorld;
}

void PhysicsManager::deleteTileBodies(const String& tileData){
tileBodies[tileData] = NULL;
}

OgreNewt::Body* PhysicsManager::getTileBodies(const String& tileData){
return tileBodies[tileData];
}

void PhysicsManager::loadTerrainGeometry(PagingLandScapeTile* tile, Vector3* vertices, int numVertices, IndexData* indexData)
{

PagingLandScapeTileInfo *blah = tile->getInfo();
String tileData = "page"+StringConverter::toString(blah->mPageX) +"-" + StringConverter::toString(blah->mPageZ) +"-tile"+StringConverter::toString(blah->mTileX)+"-"+StringConverter::toString(blah->mTileZ);


if(tileBodies[tileData]==NULL)
{

OgreNewt::TreeCollisionSerializer* serializer=new OgreNewt::TreeCollisionSerializer();
OgreNewt::CollisionPrimitives::TreeCollision* collision;


if(!ResourceGroupManager::getSingleton().resourceExists("General",tileData + ".collision")){

collision = new OgreNewt::CollisionPrimitives::TreeCollision(mWorld,numVertices,vertices,indexData,false);
serializer->exportTreeCollision(collision,"coldata//" + tileData + ".collision");

}else{
collision=new OgreNewt::CollisionPrimitives::TreeCollision(mWorld);
DataStreamPtr ptr = ResourceGroupManager::getSingleton().openResource(tileData + ".collision");
serializer->importTreeCollision(ptr,collision);
}



OgreNewt::Body* body=new OgreNewt::Body(mWorld,collision);
SceneNode* newBody = tile->getSceneNode()->createChildSceneNode(tileData);
body->attachToNode(newBody);

tileBodies[tileData]=body;

delete collision;

}

}


class TerrainManager
{
public:
TerrainManager(PagingLandScapeSceneManager* sceneMgr, PhysicsManager* physManager);
~TerrainManager();



void tileUnloaded(PagingLandscapeEvent* event);
void tileLoaded(PagingLandscapeEvent* event);

Camera* mCamera;
//SceneManager* mSceneMgr;

protected:
PhysicsManager* physMgr;
PagingLandscapeDelegate* loadTileDelegate;
PagingLandscapeDelegate* unloadTileDelegate;
PagingLandScapeSceneManager* mSceneMgr;

private:
};




TerrainManager::TerrainManager(PagingLandScapeSceneManager* sceneMgr, PhysicsManager* physManager){

mSceneMgr = sceneMgr;
physMgr = physManager;

loadTileDelegate=new PagingLandscapeDelegate();
unloadTileDelegate=new PagingLandscapeDelegate();
loadTileDelegate->bind(this,&TerrainManager::tileLoaded);
unloadTileDelegate->bind(this,&TerrainManager::tileUnloaded);
mSceneMgr->setOption("addLoadTileListener",loadTileDelegate);
mSceneMgr->setOption("addUnloadTileListener",unloadTileDelegate);

mSceneMgr->setOption ("LoadNow", mCamera);

}

TerrainManager::~TerrainManager(){

}


void TerrainManager::tileLoaded(PagingLandscapeEvent* event)
{

//recover PLSM2's tile object
int pageX=event->mPagex;
int pageZ=event->mPagez;

PagingLandScapePage* page=mSceneMgr->getPageManager()->getPage(pageX, pageZ);
int tileX=event->mTilex;
int tileZ=event->mTilez;
PagingLandScapeTile* tile=page->getTile(tileX, tileZ);

//ask reference to geometry to PLSM2
vector<void*> params;
int renderLevel=0;
params.push_back(&pageX);
params.push_back(&pageZ);
params.push_back(&tileX);
params.push_back(&tileZ);
params.push_back(&renderLevel);
mSceneMgr->getOption("PageGetTileVertexData_2",&params);

//recover data at the end of the vector and send it to our physics class for the next step
int* numVtx=((int*)params[5]);
Vector3* vertices=((Vector3*)params[6]);
IndexData* indexData=((IndexData*)params[7]);

physMgr->loadTerrainGeometry(tile,vertices,*numVtx,indexData);

//cleanup
delete[] vertices;
delete numVtx;

}

void TerrainManager::tileUnloaded(PagingLandscapeEvent* event){

//recover PLSM2's tile object
int pageX=event->mPagex;
int pageZ=event->mPagez;

PagingLandScapePage* page= mSceneMgr->getPageManager()->getPage(pageX, pageZ);

int tileX=event->mTilex;
int tileZ=event->mTilez;
PagingLandScapeTile* tile=page->getTile(tileX, tileZ);




String tileData = "page"+StringConverter::toString(pageX) +"-" + StringConverter::toString(pageZ) +"-tile"+StringConverter::toString(tileX)+"-"+StringConverter::toString(tileZ);


tile->getSceneNode()->removeAndDestroyAllChildren();
OgreNewt::Body *body = physMgr->getTileBodies(tileData);

delete body;
physMgr->deleteTileBodies(tileData);


}


Note - almost everything there is in the Wiki except the changes I made to the collision-data loader. Now, for setting this up you're going to need to change your SceneManagers to PagingLandScapeSceneManagers like this:

//SceneManager* mSceneMgr; // old
PagingLandScapeSceneManager* mSceneMgr; // new


And you'll need to initialize the mSceneMgr like this:
mSceneMgr = (PagingLandScapeSceneManager*)mRoot->createSceneManager("PagingLandScapeSceneManager", "PLSM2SMInstance");

Then you'll need to have somewhere:
PhysicsManager* physMgr;
TerrainManager* terrainMgr;


I start the PhysicsManager first, and then the TerrainManager:

physMgr = new PhysicsManager();
terrainMgr = new TerrainManager(mSceneMgr, physMgr);


I start my PhysManager at the start of the application and the TerrainManager at the FrameListener's construction.

Next, in your resources.cfg, under the General section (if you're going exactly by my setup) you'll add:

FileSystem=./coldata

Then create a new folder in the directory you're running your program from called "coldata" - that should just about do it!

If you get any linker errors, you'll need to add "Plugin_PagingLandScapeSceneManager2.lib" to your linker input.

Now, whenever a tile loads, it goes to LOD 0 and constructs a TreeCollision surface out of it unless it finds one already made (from a previous use) in the "coldata" folder. If it creates a new one, it saves it to the folder for fast loading next time. Note: these files are about 500KB per tile on my machine, so if you have a massive landscape, you're going to be chewing up space quick.

Let me know if there are errors - it's quite possible since I just hacked together a page of includes (pretty much everything, just in case) and all my class data into one file and tossed instructions. If this is something people really need and have problems with, I'll make it into a "plug-in" class or something.

Good luck!

wybbzcwj

15-06-2006 09:25:18

one possible reason

if U use Newton 1.53,because it change the treecollision method,PLSM2 may produce wrong field,inverse the order of vertex can solve this

Syphius

15-06-2006 11:42:20

Hello And thanks for reply!

I tried your code HexiDave, but it doesn't work for me :'(.
What version of PLSM2 you use? the CVS one?

And I have the version 1.53 of newton, so I tried to inverse the oder of the vertices like this :


Vector3* vertices2 = new Vector3[*numVtx];
for(int i=*numVtx-1,j=0;i>-1;i--,j++){
vertices2[j] = vertices[i];
}

but it doesn't work! :'(

I can post my code, maybe you could help me more :) :


#include ".\OgreNewtonApplication.h"
#include ".\OgreNewtonFrameListener.h"
#include <OgrePagingLandScapePageManager.h>
#include <OgrePagingLandScapeSceneManager.h>
#include <OgrePagingLandScapeRenderable.h>
#include <OgrePagingLandScapePage.h>
#include <OgrePagingLandScapeTile.h>
#include <OgreNewt.h>


PLSM2Manager::PLSM2Manager(SceneManager* sceneManager,OgreNewt::World* World):m_sceneManager(sceneManager),m_World(World){
PagingLandscapeDelegate * loadTileDelegate=new PagingLandscapeDelegate();
loadTileDelegate->bind(this,&PLSM2Manager::tileLoaded);
m_sceneManager->setOption("addLoadTileListener",loadTileDelegate);
PagingLandscapeDelegate * unloadTileDelegate=new PagingLandscapeDelegate();
unloadTileDelegate->bind(this,&PLSM2Manager::tileUnloaded);
m_sceneManager->setOption("addUnloadTileListener",unloadTileDelegate);
}
void PLSM2Manager::tileUnloaded(PagingLandscapeEvent* e){
//recover PLSM2's tile object
int pageX=e->mPagex;
int pageZ=e->mPagez;

PagingLandScapePage* page= ((PagingLandScapeSceneManager*)m_sceneManager)->getPageManager()->getPage(pageX, pageZ);

int tileX=e->mTilex;
int tileZ=e->mTilez;
PagingLandScapeTile* tile=page->getTile(tileX, tileZ);

String tileData = "page"+StringConverter::toString(pageX) +"-" + StringConverter::toString(pageZ) +"-tile"+StringConverter::toString(tileX)+"-"+StringConverter::toString(tileZ);

tile->getSceneNode()->removeAndDestroyAllChildren();
OgreNewt::Body *body = tilesBodies[tileData];

delete body;
tilesBodies[tileData]=NULL;
}
void PLSM2Manager::tileLoaded(PagingLandscapeEvent* e){
//recover PLSM2's tile object
int pageX=e->mPagex;
int pageZ=e->mPagez;

PagingLandScapePage* page=((PagingLandScapeSceneManager*)m_sceneManager)->getPageManager()->getPage(pageX, pageZ);
int tileX=e->mTilex;
int tileZ=e->mTilez;
PagingLandScapeTile* tile=page->getTile(tileX, tileZ);

//ask reference to geometry to PLSM2
std::vector<void*> params;
int renderLevel=0;
params.push_back(&pageX);
params.push_back(&pageZ);
params.push_back(&tileX);
params.push_back(&tileZ);
params.push_back(&renderLevel);
m_sceneManager->getOption("PageGetTileVertexData_2",&params);

//recover data at the end of the vector and send it to our physics class for the next step
int* numVtx=((int*)params[5]);
Vector3* vertices=((Vector3*)params[6]);
IndexData* indexData=((IndexData*)params[7]);

loadTerrainGeometry(tile,vertices,*numVtx,indexData);

//cleanup
delete[] vertices;
delete numVtx;
}
void PLSM2Manager::loadTerrainGeometry(PagingLandScapeTile* tile, Vector3* vertices, int numVertices, IndexData* indexData){
PagingLandScapeTileInfo *blah = tile->getInfo();
String tileData = "page"+StringConverter::toString(blah->pageX) +"-" + StringConverter::toString(blah->pageZ) +"-tile"+StringConverter::toString(blah->tileX)+"-"+StringConverter::toString(blah->tileZ);


if(tilesBodies[tileData]==NULL)
{

OgreNewt::TreeCollisionSerializer* serializer=new OgreNewt::TreeCollisionSerializer();
OgreNewt::CollisionPrimitives::TreeCollision* collision;


if(!ResourceGroupManager::getSingleton().resourceExists("General",tileData + ".collision")){

collision = new OgreNewt::CollisionPrimitives::TreeCollision(m_World,numVertices,vertices,indexData,false);
serializer->exportTreeCollision(collision,"coldata//" + tileData + ".collision");

}else{
collision=new OgreNewt::CollisionPrimitives::TreeCollision(m_World);
DataStreamPtr ptr = ResourceGroupManager::getSingleton().openResource(tileData + ".collision");
serializer->importTreeCollision(ptr,collision);
}



OgreNewt::Body* body=new OgreNewt::Body(m_World,collision);
SceneNode* newBody = tile->getSceneNode()->createChildSceneNode(tileData);
body->attachToNode(newBody);

tilesBodies[tileData]=body;

delete collision;

}
}
OgreNewtonApplication::OgreNewtonApplication(void)
{
m_World = new OgreNewt::World();
m_World->setWorldSize(AxisAlignedBox(-100000,-100000,-100000,100000,100000,100000));
//m_World->setWorldSize(Ogre::Vector3 (-1.0e10f, -1.0e10f, -1.0e10f),Ogre::Vector3(1.0e10f, 1.0e10f, 1.0e10f));
}

OgreNewtonApplication::~OgreNewtonApplication(void)
{
delete m_World;
// de-initialize the debugger.
OgreNewt::Debugger::getSingleton().deInit();
}

void OgreNewtonApplication::chooseSceneManager(){
mSceneMgr = mRoot->createSceneManager("PagingLandScapeSceneManager", "PagingLandScapeDemo" );
mSceneMgr->setWorldGeometry( Ogre::String("paginglandscape2.cfg") );

}

void OgreNewtonApplication::createScene()
{

// sky box.
mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");

// shadows on.
mSceneMgr->setShadowTechnique( Ogre::SHADOWTYPE_STENCIL_MODULATIVE );

Ogre::Vector3 size(10.0,1.0,10.0);
Ogre::SceneNode* node ;
Ogre::Entity* ent;
OgreNewt::Collision* col ;

//floorbody->attachToNode( node );
//floorbody->setPositionOrientation( Ogre::Vector3(0,-5,0),Ogre::Quaternion::IDENTITY );
delete col;
// BOX BODY
// standard 1x1x1 cube.
size = Ogre::Vector3( 1, 1, 1 );
node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
ent = mSceneMgr->createEntity("box_body", "box.mesh" );
node->attachObject( ent );
node->setScale( size );

// rigid body.
col = new OgreNewt::CollisionPrimitives::Box( m_World, size );
OgreNewt::Body * bod = new OgreNewt::Body( m_World, col );
bod->attachToNode( node );

// initial position
bod->setPositionOrientation( Ogre::Vector3(1000,350,-2),Ogre::Quaternion::IDENTITY );
delete col;

Ogre::Real mass = 10.0;
Ogre::Vector3 inertia = OgreNewt::MomentOfInertia::CalcBoxSolid( mass, size );
bod->setMassMatrix( mass, inertia );
bod->setStandardForceCallback();
mCamera->setPosition( Ogre::Vector3( 1000, 350, 100) );
}

void OgreNewtonApplication::createFrameListener()
{
plsm2Manager = new PLSM2Manager(mSceneMgr,m_World);
mFrameListener = new ExampleFrameListener( mWindow, mCamera );
mRoot->addFrameListener(mFrameListener);

mNewtonListener = new OgreNewt::BasicFrameListener( mWindow, mSceneMgr, m_World, 120 );
mRoot->addFrameListener(mNewtonListener);
}


Do I made a mistake? :(

Please help :'( :'(

Syphius

Syphius

15-06-2006 14:30:51

I tried the cvs version of PLSM2 but it doesn't work :(

Please Help :'(

wybbzcwj

15-06-2006 14:57:35

hi, Syphius

my English is poor,so I better explain my mean a little more

Newton before 1.53, the ground triangle produced by treecollision is 2-side,but in 1.53,it changed to 1-side triangle ,what worse ,my ground triangle produced by my PLSM2 is upside down,so I change the order of my ground triangle,now all ok

I duuno if U meet the same problem



what I done is change the OgreNewt's "OgreNewt_CollisionPrimitives.cpp"

something like this:

"
poly_verts[0] = vertices[*curIndex]; curIndex++;
poly_verts[2] = vertices[*curIndex]; curIndex++;
poly_verts[1] = vertices[*curIndex]; curIndex++;
"
change to

"
poly_verts[0] = vertices[*curIndex]; curIndex++;
poly_verts[1] = vertices[*curIndex]; curIndex++;
poly_verts[2] = vertices[*curIndex]; curIndex++;
"

enenenenen

Syphius

15-06-2006 15:29:40

wybbzcwj you are a GENIUS !!! It's working now! :)

Thank you very much!

Thank you HexiDave too :)