Terrain Geometry from Tutorials

Gorgool

16-12-2010 16:21:25

http://www.ogre3d.org/tikiwiki/tiki-ind ... eightfield

This code don't want to compile. Error on this string:
NxOgre::ManualHeightField *mhf = OGRE_NEW_T(NxOgre::ManualHeightField, Ogre::MEMCATEGORY_GENERAL)();
"error 'NxOgre::Allocatable<Allocator>::operator new' : function does not take 2 arguments".
Tried to compile with this:
NxOgre::ManualHeightField *mhf =OGRE_NEW NxOgre::ManualHeightField();
Runtime error : Access violation writing location 0x0607c000.

NxOgre Detritus.

Gorgool

21-12-2010 14:23:39

Whould anyone give me the working code how to convert Ogre::Terrain
to heightfield for PhysX simulations?

betajaen

21-12-2010 14:38:12

There is a article somewhere on the wiki that describes it, and gives out code. It's best to use that. I'm considering removing the createTerrain stuff from Critter anyway, as I've never gotten it to work properly.

Gorgool

21-12-2010 16:43:37

The only article i found - the article from my first post in this thread.
And it does not work properly...

shanefarris

21-12-2010 19:58:01

This is what I have. It's based off of the wiki, and it works, so I'm not sure what kind of issues you are having.

void* CPhysicsStrategy_PhysX::AddTerrain(TerrainGroup* terrainGroup)
{
TerrainGroup::TerrainIterator ti = terrainGroup->getTerrainIterator();
while(ti.hasMoreElements())
{
Terrain* t = ti.getNext()->instance;
if(t)
{
u32 size = t->getSize();
f32 worldSize = t->getWorldSize();
f32 minHeight = t->getMinHeight();
f32 maxHeight = t->getMaxHeight();
f32* data = t->getHeightData();
reVector3Df position = t->getPosition();

// Create the manual heightfield
NxOgre::ManualHeightField *mhf = OGRE_NEW_T(NxOgre::ManualHeightField, Ogre::MEMCATEGORY_GENERAL)();
mhf->begin(size, size);
f32 normMin = -32767.0f;
f32 normMax = 32767.0f;

// Sample the data to the manual heightfield
for(u32 x = 0; x < size; ++x)
{
NxOgre::Enums::HeightFieldTesselation tess = NxOgre::Enums::HeightFieldTesselation_NW_SE;
for(int z = size-1; z >= 0; --z)
{
f32 height = data[(size * z) + x];
short sample = (short)(((height - minHeight) / (maxHeight - minHeight)) * (normMax - normMin) + normMin) + 55.0f; // TODO: fix this
mhf->sample(sample, 0, 0, tess);
if(tess == NxOgre::Enums::HeightFieldTesselation_NE_SW)
tess = NxOgre::Enums::HeightFieldTesselation_NW_SE;
else
tess = NxOgre::Enums::HeightFieldTesselation_NE_SW;
}
}

// Create the actual heightfield
NxOgre::HeightField *hf = mhf->end(t->getMaterialName().c_str());
Ogre::Real hf_size = worldSize + (worldSize / size);
Ogre::Real hf_height = (maxHeight - minHeight) / 2.0f;
Ogre::Real hf_pose_x = position.x - (worldSize / 2.0f);
Ogre::Real hf_pose_y = position.y + ((maxHeight + minHeight) / 2.0f);
Ogre::Real hf_pose_z = position.z - (worldSize / 2.0f);

NxOgre::HeightFieldGeometry* hfg = new NxOgre::HeightFieldGeometry(hf, NxOgre::Vec3(hf_size, hf_height, hf_size));
hfg->setLocalPose(NxOgre::Matrix44(NxOgre::Vec3(hf_pose_x, hf_pose_y, hf_pose_z)));
m_Scene->createSceneGeometry(hfg);

// Free memory
OGRE_DELETE_T(mhf, ManualHeightField, Ogre::MEMCATEGORY_GENERAL);
}
}

return NULL;
}

Gorgool

21-12-2010 20:54:56

Thx for reply, but the same thing:

NxOgre::ManualHeightField* mhf = OGRE_NEW_T(NxOgre::ManualHeightField, Ogre::MEMCATEGORY_GENERAL)();

error on this string. Maybe something changed and now ManualHeightField creating some another way...

betajaen

21-12-2010 21:35:17

Just create it on the stack.

They are short lived, so I never use pointers for Descriptions or the Manual classes.

Gorgool

21-12-2010 22:33:39

On the stack, you mean like this:

NxOgre::ManualHeightField mhf;

It does not working, runtime error - Access violation writing...

cdreid

12-01-2011 00:42:36

Has anyone found a solution to this? I had EXACTLY the same results as the original poster. I've tried workarounds but nothing works and im at a loss as to what to do next.

Note : the code we're both using is from the bloodymess tutorials so its likely a break between bloodymess and detritus. Has anyone recoded this function for detritus?

cdreid

12-01-2011 00:47:11

Betajaen you solved this for Buggy_swires here:

https://www.ogre3d.org/addonforums/view ... 65&start=0

Can you post a solution for detritus? I'd try to wade through the swires code and figure out the changes but thats a scary scary thought. Im up for recompiling detritus and adding in the changes.

betajaen

12-01-2011 09:13:22

You can just copy the changed files from BuggySwires/Lemondade into Detritus, it's only three files that were affected and Detritus has them.

cdreid

12-01-2011 20:03:01

Do you remember which in particular? If not i can find them by tracing the functions pretty easily i think.

betajaen

12-01-2011 20:24:29

It's the NxOgreBuffer.h, NxOgreMemoryResource.h, and NxOgreMemoryResource.cpp files.

cdreid

12-01-2011 21:15:45

I love when i guess correctly. Well almost correctly. YOu're officially reaffirmed as The Man. Hopefully some company will jump on Ogre
and nxogre and make all you devs rich.

betajaen

12-01-2011 21:30:36

I was guessing too. But you are correct, I am The Man.

cdreid

15-01-2011 04:07:04

I can NOT get this to work. I tried simply replacing the detritus files with the new ones and , as i secretly suspected, nogo. I know i should plow into them and figure everything out but heck it would probably be easier to learn straight physx.
The wiki code, with a lot of changes, will run under detristus but it throws memory access errors when you actually load the nxogre terrain.

Does Anyone have working code that converts a loaded 1.71 ogre terrain into an nxogre terrain? I realise i could load it from a file etc but as im going to have to have editable terrain etc i need to be able to convert on the fly. If for no other reason than fast/large terrain changes (explosions.. or whatever). If i can get This working i can finally be on to coding my actual game logic .. assuming visual studio isnt feeling evil.

cdreid

15-01-2011 05:05:40

Ignore my last post. As expected (this is the universal law for some of us) i missed a coding error.

Under 1.71 and Destritus use THIS line to create the heightfield
NxOgre::ManualHeightField *mhf;

And delete this one
// OGRE_DELETE_T(mhf, ManualHeightField, Ogre::MEMCATEGORY_GENERAL); <<< DUH!
This causes the data error and VS only traces it to the main function call not to the actual line within the function that causes the problem.

betajaen

15-01-2011 09:37:26

I posted a new commit on Detritus that includes the fixes.

https://github.com/betajaen/nxogre/comm ... b3bdcd0d86

Would anyone like to try it out for me? It did compile okay, but my NxOgre setup is Buggy Swires, which makes it difficult to switch over and test. I don't foresee any problems though.

@cdreid

This is the my approved way of creating Heightfields. It should work for you if you arrange your code to something like this. There is no need to use pointers on the ManualHeightField classes.

NxOgre::ManualHeightField mh;
mh.begin(8,8);
for (size_t x=0;x < 8;x++)
{
for (size_t y=0;y < 8;y++)
{
mh.sample(x + (y * 100));
}
}

NxOgre::HeightField* hf = mh.end();

NxOgre::HeightFieldGeometryDescription hfg_desc(hf);
hfg_desc.mDimensions.set(10,10,10);
hfg_desc.mFlags += NxOgre::ShapeFlags::Visualisation;
mScene->createSceneGeometry(hfg_desc);

cdreid

15-01-2011 11:17:08

I'll test out your new detritus release asap. This silly problem has been driving me nuts i suck at debugging... especially other peoples code. On the pointer.. i switched to a pointer in frustration and suddenly it worked much better. The reason i didnt recode the versions that convert physx to ogre is because i dont really understand the tessalation etc yet so i figured better off spending time trying to get this to work. If i manage to get an efficient, iron clad detritus version written from scratch ill post it and comment the heck out of it. Thanks a lot

cdreid

18-01-2011 23:54:47

Just fyi. The new detritus commit compiled flawlessly not so much as a warning flag. Ive given up on this avenue though as it has just caused too many headaches. Ill either get around to coding an on the fly conversion function that works across all 3 distros or move to another engine. thanks for all the help

cranky

25-01-2011 10:47:58

hi everyone.
i am trying to create terrain collision from heightmap and everything seems to be okay, but it looks smaller than world geometry:


here is my code:

void World::createWorldGeometry( const Ogre::String& heightmap )
{
Ogre::Terrain::ImportData data;
Ogre::Image img;
Ogre::AxisAlignedBox bbox;
Ogre::Vector3 bounds;

img.load( heightmap, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME );

data.terrainSize = img.getWidth();
data.worldSize = img.getWidth();
data.inputImage = &img;

mTerrain->prepare( data );
mTerrain->load();

bbox = mTerrain->getAABB();
bounds = bbox.getMaximum() - bbox.getMinimum();
createWorldCollision( &img, bounds );
}

void World::createWorldCollision( Ogre::Image *img, const Ogre::Vector3& bounds )
{
NxOgre::ManualHeightField mhf;
NxOgre::HeightField *hf;
Ogre::int32 size;
Ogre::int16 height;
NxOgre::Vec3 pos;

size = img->getWidth();

mhf.begin( size, size );
NxOgre::Enums::HeightFieldTesselation tess = NxOgre::Enums::HeightFieldTesselation_NW_SE;

for( int i = 0; i < size; ++i )
{
for( int j = 0; j < size; ++j )
{
height = img->getColourAt( i, j, 0 ).r * 32768;
mhf.sample( height, tess );
if( tess == NxOgre::Enums::HeightFieldTesselation_NE_SW )
{
tess = NxOgre::Enums::HeightFieldTesselation_NW_SE;
}
else
{
tess = NxOgre::Enums::HeightFieldTesselation_NE_SW;
}
}
}

hf = mhf.end();

NxOgre::HeightFieldGeometryDescription desc( hf, bounds );
pos.x = pos.z = -bounds.x / 2.0; pos.y = 0;
mNxScene->createSceneGeometry( desc, NxOgre::Matrix44( pos ) );
}


does anyone have solution?

SniperBinaire

14-04-2011 15:42:52

Well, with the current Detritus version, I've managed to get something that work with me;
Just a waning from the compiler because mhf isn't initialized, but with me it work flawlessly.
Just pass parameters like that :
loadTerrainGeometry(sys0.terrain->getMaterialName(), sys0.terrain->getHeightData(), sys0.terrain->getSize(),sys0.terrain->getWorldSize(), sys0.terrain->getMinHeight(), sys0.terrain->getMaxHeight(), sys0.terrain->getPosition());



And the function itself :
void loadTerrainGeometry(const Ogre::String& name, float* data, Ogre::uint16 size, Ogre::Real worldSize, Ogre::Real minHeight, Ogre::Real maxHeight, const Ogre::Vector3& position)
{
// Create the manual heightfield
NxOgre::ManualHeightField mhf;
mhf.begin(size, size);
Ogre::Real normMin = -32768.0f;
Ogre::Real normMax = 32767.0f;
// Sample the data to the manual heightfield
for(int x = 0; x < size; ++x)
{
NxOgre::Enums::HeightFieldTesselation tess = NxOgre::Enums::HeightFieldTesselation_NW_SE;
for(int z = size-1; z >= 0; --z)
{
Ogre::Real height = data[(size * z) + x];
short sample = (short)(((height - minHeight) / (maxHeight - minHeight)) * (normMax - normMin) + normMin);
mhf.sample(sample, 0, 0, tess);
if(tess == NxOgre::Enums::HeightFieldTesselation_NE_SW)
tess = NxOgre::Enums::HeightFieldTesselation_NW_SE;
else
tess = NxOgre::Enums::HeightFieldTesselation_NE_SW;
}
}
// Create the actual heightfield
NxOgre::HeightField *hf = mhf.end(name.c_str());
Ogre::Real hf_size = worldSize + (worldSize / size);
Ogre::Real hf_height = (maxHeight - minHeight) / 2.0f;
Ogre::Real hf_pose_x = position.x - (worldSize / 2.0f);
Ogre::Real hf_pose_y = position.y + ((maxHeight + minHeight) / 2.0f);
Ogre::Real hf_pose_z = position.z - (worldSize / 2.0f);
#if NxOgreVersionMajor <= 1 && NxOgreVersionMinor <= 5
NxOgre::HeightFieldGeometry* hfg = new NxOgre::HeightFieldGeometry(hf, NxOgre::Vec3(hf_size, hf_height, hf_size));
hfg->setLocalPose(NxOgre::Matrix44(NxOgre::Vec3(hf_pose_x, hf_pose_y, hf_pose_z)));
mScene->createSceneGeometry(hfg);
#else
NxOgre::HeightFieldGeometryDescription desc(hf, NxOgre::Vec3(hf_size, hf_height, hf_size));
mScene->createSceneGeometry(desc, NxOgre::Matrix44(NxOgre::Vec3(hf_pose_x, hf_pose_y, hf_pose_z)));
#endif

}



Hope it can help.