using NewtonCreateHeightFieldCollision

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

using NewtonCreateHeightFieldCollision

Postby noals » Tue Sep 18, 2012 12:40 am

hi,

(edit : im using core 300), i have my terrain created with irrlicht so if i understand well, i just need to make a "collision layer" with newton so my terrain show with irrlicht and it is solid in the NewtonWorld with NewtonCreateHeightFieldCollision.

//i init newton at the begining of my main with irrlicht initialization
Code: Select all
   NewtonWorld*nWorld=NewtonCreate();


//i put this code after having created my terrain
Code: Select all
   NewtonCollision* nTerrainCol =       NewtonCreateHeightFieldCollision(nWorld,102400,33,0,0,"heightmap/F18.bmp",1.0f,1.0f);
   //NewtonBody* nTerrain=NewtonCreateDynamicBody(nWorld, nTerrainCol,0);
   NewtonDestroyCollision(nTerrainCol);


//close newton after my device->drop()
Code: Select all
   NewtonDestroy(nWorld);


1/ then what ? im pretty sure i miss lot of things and i read tutos and codes but i have difficulties making the difference between stuffs usefull to newton to work and other stuffs.

2/ i guess i dont need to createbody since irrlicht do it, right ? i think my only problem with irrlicht will be updating position of the stuff rendered with irrlicht and the newton CollisionStuff at the same time but its maybe too soon to think about it lol.

3/
unsigned short* elevationMap - the actual elevation map as 16-bit integer array.

Creates a height field collision with the specified elevation map and attributes.

what is an elevation map ? i dont understand the purpose of it.

4/ i use a bitmap 256x256 and irrlicht multiply that i think so :
core::vector3df(400.0f,33.0f,300.0f), //scale 256x400=102400 256x300=76800 height to define

is it right to put 102400 as value for newton ?

5/ i saw in the forum that some user use it like NewtonCreateHeightFieldCollision(nWorld,"filename",0) but i dont get it anyway, it just made me think about another question, in the demo you use raw, does newton recognize the .bmp format ?
and do i need to save my file as 16bits ? i think i read something about it in the tuto.

thx.
noals
 
Posts: 32
Joined: Mon Sep 03, 2012 7:59 am

Re: using NewtonCreateHeightFieldCollision

Postby JoeJ » Wed Sep 26, 2012 3:15 pm

Did you notice, that, when clicking on -> NewtonCreateHeightFieldCollision <- you get to wiki-page answering all yor questions? ;)
Looking there i see that the function takes 16bit short int values from RAM, no filename.
I'd try:

short int *heightmap = new short int [256*256];
// convert your bmp to this data... for (each pixel n) heightmap[n] = pixel[n] * 256

NewtonCreateHeightFieldCollision (newtonWorld,
256, 256, 0, heightmap, 0,
400.0f, // maybe 400 * 256 or 400 / 256 - depending on irrlicht specs
33); // maximum height

Note: Cells must be square! You could try to nonuniformly scale the collision, but i'd change rendering instead (Square cells are faster and look better):

core::vector3df(400.0f,33.0f,400.0f)


On your side i'd start with boxes and other primitives first.
It's easier to verify that graphics and physics match up.
You can use a falling box than to see if terrain collides as it should.
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: using NewtonCreateHeightFieldCollision

Postby noals » Thu Sep 27, 2012 7:00 pm

Did you notice, that, when clicking on -> NewtonCreateHeightFieldCollision <- you get to wiki-page answering all yor questions?

yes, its just that i didnt really understood.

Note: Cells must be square!

ok, its because of the map i did ( http://hpics.li/409ce70 ), i based my scaling on it kinda imagining how big i would have wanted the world, but thats not important right now, i will change my scaling.

short int *heightmap = new short int [256*256];
// convert your bmp to this data... for (each pixel n) heightmap[n] = pixel[n] * 256

i will search about that, i dont know how to do it, maybe i can find it in some tutos since i know what im looking for now. lol
i think i can get the file and convert it with irrlicht fonctions, then to c++ like you did for newton but i need to figure out how.

thx for your answer, i will post again later if i get it to work or not anyway.

edit :
i think i can get the file and convert it with irrlicht fonctions

Looking there i see that the function takes 16bit short int values from RAM, no filename.

my bad... will check the irrlicht API for fonction that can return that.
noals
 
Posts: 32
Joined: Mon Sep 03, 2012 7:59 am

Re: using NewtonCreateHeightFieldCollision

Postby JoeJ » Fri Sep 28, 2012 9:10 am

I don't think Irrlicht does that conversation for you, but it's very easy.
I guess you use a grayscale image with 256 * 256 pixels;
Each pixel is a byte with values from 0 to 255.
You load the image with Irrlicht, so look in Irrlicht for a function that returns a pointer to the pixeldata.

// something like:
int imgWidth = 256;
img = Irrlicht::LoadBmp ("blah.bmp");
char *bytes = img.GetDataPointer();

Then you convert the pixels to 2-byte-numbers (values from 0 to 256*256-1) newton wants:

unsigned short *heightmap16bit = new unsigned short [imgWidth*imgWidth];
for (int i=0; i<imgWidth*imgWidth ; i++) heightmap16bit[i] = bytes[i] * 256;


However, there's lots that can go wrong: The data may be rotated, flipped, translated and scaled differently compared to what Irrlicht renders.
Have fun with trial and error...
If you don't get correct results fast, using a big box for ground is easier and you can check how newton and irrlicht match up.
After that works, replacing box with heightfield is the better way to get going.

I assume you soon will discover problems like: How can i render a object at it's physical position / rotation,
and how can i create a physical object where i see its shape.
This is the one and only thing you need to learn now, if there ar doubts about it, forget anything else until you get used to that.
hightfields and characters come later ;)
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: using NewtonCreateHeightFieldCollision

Postby noals » Sat Sep 29, 2012 2:55 am

my terrain is done with that in irrlicht
Code: Select all
scene::ITerrainSceneNode*terrain=smgr->addTerrainSceneNode(
      "heightmap/F18.bmp",      //heightmap
      0,                     //parent node
      -1,                     //node id
      core::vector3df(0.0f,0.0f,0.0f),   //position
      core::vector3df(0.0f,0.0f,0.0f),   //rotation
      core::vector3df(400.0f,33.0f,300.0f),   //scale  256x400=102400 256x300=76800 height to define
      video::SColor(255,255,255,255),      //vertex color
      5,                     //maxLOD
      scene::ETPS_17,            //patch size
      3);                     //smooth factor

in the irrlicht API, i think i need getHeight(x,y) right ?
http://irrlicht.sourceforge.net/docu/cl ... _node.html
so i come up with something like that yesterday.
Code: Select all
u32 terrainX;
u32 terrainY;
u32 heightmapData; // or u32 heightmapDate[256*256]


for(terrainX=1;terrainX<257;terrainX++)
   {
      for(terrainY=0;terrainY<257;terrainY++)
      {
         for(u32* tab=1;tab<256*256;tab++)
         {
            heightmapData[tab]=terrain->getHeight(terrainX,terrainY);
         }
      }
   }

but i stopped because i wasnt initialise the int pointer or something well so my code is wrong anyway. (not a little btw lol)
in the tuto on the newton wiki, infos was took from the meshbuffer, indices and verticles so i kinda got confused about the info i need but since i saw that the getHeight was working by pixel i choosen that. i know my code is wrong but is it actualy the info i need ?

I assume you soon will discover problems like: How can i render a object at it's physical position / rotation,
and how can i create a physical object where i see its shape.

for that i think i will try to create a class or something so my position and rotation would synch/be the same in the main loop for the graphic and the physics. i just hope i wont have too much scaling problems.

This is the one and only thing you need to learn now, if there ar doubts about it, forget anything else until you get used to that.
hightfields and characters come later ;)

thats what i wanted to do next, having my ground and then trying box and stuff. in another post i put a demo with a plane ground but i put back my test heightmap with relief in my current projet for later use so thats why i want to do my ground first so it is ready for any test with boxes and stuff.
noals
 
Posts: 32
Joined: Mon Sep 03, 2012 7:59 am

Re: using NewtonCreateHeightFieldCollision

Postby JoeJ » Sat Sep 29, 2012 6:27 am

First i'll comment what you've done wrong:
Code: Select all
u32 terrainX;
u32 terrainY;
u32 heightmapData; // or u32 heightmapDate[256*256]       // this is a 'big' amount of data, you need to allocate the memory for it at runtime


for(terrainX=1;terrainX<257;terrainX++) // from 0 to 255!
   {
      for(terrainY=0;terrainY<257;terrainY++) // from 0 to 255 too
      {
         for(u32* tab=1;tab<256*256;tab++) // this loop is nonsense - not needed - think about it, terrible mistake you made :)
         {
            heightmapData[tab]=terrain->getHeight(terrainX,terrainY);
         }
      }
   }




And here the fixed version:



Code: Select all
u32 terrainX;
u32 terrainY;
unsigned short *heightmapData = new unsigned short [256*256]; // allocate memory at runtime
// if (heightmapData == 0) return 0; // this would check if allocation was successful


for(terrainX=0;terrainX<256;terrainX++) // starting from 0 makes proprammers life easy
   {
      for(terrainY=0;terrainY<256;terrainY++)
      {
            u32 irrHeight = terrain->getHeight (terrainX,terrainY);
            unsigned short newtonHeight = unsigned short (irrHeight>>16); // if irrlicht uses full 32 bits, this divides the value by 256*256, so it fits into 16 bit
           // unsigned short newtonHeight = unsigned short (irrHeight<<8); // if irrlicht uses 8 bits like bmp file, this multuplies the value by 256, so it fits into 16 bit
            heightmapData[terrainX + terrainY*256] = newtonHeight;
           // heightmapData[(255-terrainX) + terrainY*256] = newtonHeight; // an example if flipping at xaxis is needed
         
      }
   }



now it should work, if getHeight returns what we assume.
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: using NewtonCreateHeightFieldCollision

Postby noals » Sun Sep 30, 2012 4:13 am

i didnt know about the new so i checked my c++ book, so we allocate memory for our heightmapData that will contain the 256*256 values of our bmp heightmap. (u16 is unsigned short 16-bits in irrlicht)
Code: Select all
u16 *heightmapData= new u16 [256*256]; // allocate memory at runtime


then we need to retrieve the 256*256 values representing each pixel on the heightmap so we use its X Y pixel coordinates for this purpose.
Code: Select all
for(terrainX=0;terrainX<256;terrainX++)
   {
      for(terrainY=0;terrainY<256;terrainY++)
      {

at this point, i understand and then come troubles.

we use irrlicht fonction getHeight to "Get height of a point of the terrain." depending on coordinates and then we have to stock each values in our heightmapData that is an unsigned short 16-bit.
Code: Select all
heightmapData [terrainX + terrainY*256] = terrain->getHeight (terrainX,terrainY);

isnt that right ?

i have this message from vc++
unsigned short* heigtmapData
Error: argument of type "unsigned short *" is incompatible with parameter of type "const float *"

"unsigned short" or "u16", i tryed few stuff but its the same result.
noals
 
Posts: 32
Joined: Mon Sep 03, 2012 7:59 am

Re: using NewtonCreateHeightFieldCollision

Postby JoeJ » Sun Sep 30, 2012 5:28 am

... so terrain->getHeight (terrainX,terrainY) does not behave like i assumed.
You'd need to post the declaration of that function to make me able to help - i don't know irrlicht, this is newton forum.
I don't know if it returns integer or floating point number,
and i don't know if it takes integer or floating point numbers as input parameter.
It would make more sense, that all values are floats, but then you'd need to set each number in relation.

It seems you don't really know the differences between signed or unsigned char, int, short and float numbers,
or you don't know how to convert between them?
With that background whether newton nor irrlicht forum is the right place to ask for help, it would be a beginners forum.
Your problems come from missing basic knowledge, not from missing experience to work with that libs.

I think you make the following mistake:
You use finished graphics and physics engine, get something to work very quickly and get the impression you make progress.
But that is not true - you learned using irrlicht a little, but you learned nothing about programming.
Did you ever made a pong clone, pacman, or a rotationg cube in OpenGL / DirectX?
If not, you really need to do simple things first!
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: using NewtonCreateHeightFieldCollision

Postby noals » Sun Sep 30, 2012 7:23 am

thats why i put this link before
http://irrlicht.sourceforge.net/docu/cl ... _node.html
it is the ITerrainSceneNode Class Reference from irrlicht API, which make my terrain, the list isnt a long one, i though you took a look since it also show the other functions i could use. thats also why i wrote :
in the tuto on the newton wiki, infos was took from the meshbuffer, indices and verticles so i kinda got confused about the info i need but since i saw that the getHeight was working by pixel i choosen that. i know my code is wrong but is it actualy the info i need ?
i should have said "by point" but you got the idea.

getHeight return float, i though it was a problem when i readed the error but i didnt said it since im still not sure about the info i need in this elevation map... plus we need an unsigned short 16-bits through it ask for a const float so it dont make sense to me, it just get me more confused.

with my lack of programming skills i was able to get started with irrlicht that i find easy, recently i updated my code to the new irrlicht release and cleaned it since my project isnt from yesterday, i should be able to make a custom gameplay as i want easely with it, i also chose raknet for network handling, i tryed a tuto, it compile and work without any problem and so i chosen newton for physic because i think it fits my need but i have difficulties to get started with it because it is very low level API so yes, i sure lack some knowledge in programing but i dont really want to enter the debate about why every noob in the world should program a pong before trying something else, you are free to help me or not, i think im at the right place.
noals
 
Posts: 32
Joined: Mon Sep 03, 2012 7:59 am

Re: using NewtonCreateHeightFieldCollision

Postby JoeJ » Sun Sep 30, 2012 8:57 am

Ok... everyone should go the way he likes to.
I've missed the Link, clears something out but i can't be sure -
such cases are easy to solve with trial and error, but you need to do this yourself.

What i know now is: Input and output are all floating point numbers (f32 must be float).
Let's look at the return value first, as it gives you compile error.

// all code is in inner loop...

f32 height = terrain->getHeight (?, ?); // we get this from irrlicht

problem: We don't know how high is the highest possible point.
You set the dimensions with this vector somehow: core::vector3df(400.0f,33.0f,400.0f)
... so, maybe, max height = 33.0f?
We proceed:

height /= 33.0f; // now this value is between 0 and 1
height *= 256*256-1; // if height == 1, we get the highest possible number for an unsigned short (16 bit) number;
unsigned short newtonHeight = (unsigned short) height; // convert the float to a short integer number
heightmapData[terrainX + terrainY*256] = newtonHeight; // we're done with that pixel


But there is second problem, we don't know what coordinates we need to give.
Again i can only guess:

float coordX = (float(terrainX)/256.0f) * 400.0f; // convert to float, set in range 0...1, multiply with your scaling
float coordY = (float(terrainY)/256.0f) * 400.0f;

f32 height = terrain->getHeight (coordX , coordY); // now we have coordinates we can try

... maybe this works, with luck. For now try to avoid any translation or rotation in the node, as that could change everything.
I don't think so, but at least you see what i see mean with conversation and relation.

Keep in mind it may be much easier to google for a bmp-loader-function.
Then you have native acess to the pixel values itself, if irrlicht hides them from you.
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: using NewtonCreateHeightFieldCollision

Postby noals » Sun Sep 30, 2012 9:01 pm

so from what you wrote, i need to put in this elevationMap array each int values between 0 and 65 535 while each values represent the bitmap's pixel color knowing that black is 0 and white is 1 so 0 = 0 and 1 = 65535.

sorry i usualy take some time to understand "simple" stuff but when i got it, thats actualy how i made progress in programmation.

Keep in mind it may be much easier to google for a bmp-loader-function.
Then you have native acess to the pixel values itself, if irrlicht hides them from you.

yeah it seem so, i will ask confirmation in the irrlicht forum but seeing some wrapper, i guess using an external bitmap library would be a good idea.

thx.
i will post again later if i get it to work or not.

edit : i asked on irrlicht but deleted my post, i will try easyBMP.
http://easybmp.sourceforge.net/
noals
 
Posts: 32
Joined: Mon Sep 03, 2012 7:59 am

Re: using NewtonCreateHeightFieldCollision

Postby JoeJ » Mon Oct 01, 2012 9:56 am

noals wrote:so from what you wrote, i need to put in this elevationMap array each int values between 0 and 65 535 while each values represent the bitmap's pixel color knowing that black is 0 and white is 1 so 0 = 0 and 1 = 65535.


Yes, exactly.

I remember now, when i started doing stuff like that and didn't know any image format specs,
i saved the image as RAW data in Photoshop - that would save exactly 256*256 bytes for a grayscale at that size,
So you would not need any bmp loader and simply multiply each byte by 256.
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: using NewtonCreateHeightFieldCollision

Postby noals » Mon Oct 01, 2012 9:57 pm

i knew about this raw format but i didnt know i was able to make it with toshop.
in the sdk tutorial, it is used like that kinda :
Code: Select all
NewtonCollision* shape=CreateHeightFieldCollision (world, "h2.raw", 0);

but its still from core 200 i think, how would you use it with core 300 ?
you still need something to load .raw right ?

easyBMP seem cool, i will try it anyway.
noals
 
Posts: 32
Joined: Mon Sep 03, 2012 7:59 am

Re: using NewtonCreateHeightFieldCollision

Postby noals » Tue Oct 02, 2012 12:19 am

well, im still stuck with the error message again, im wondering if i use my heightmapData well in NewtonCreateHeightFieldCollision or if this NewtonCreateHeightFieldCollision do actualy need an unsigned short 16-bits array, dunno i dont understand why i have this error.
unsigned short* heigtmapData
Error: argument of type "unsigned short *" is incompatible with parameter of type "const float *"


is there someone who actualy have this core 300 fonction to work and could provide an exemple ?


here is my code now, easyBMP use RGB so i use red since the three colors have the same values when greyish.

Code: Select all
BMP heightmap; //bmp image
u32 heightmapX;
u32 heightmapY;
unsigned short *heightmapData= new unsigned short [256*256]; // allocate memory at runtime

//load the heightmap
   heightmap.ReadFromFile("heightmap/F18");
   //heightmapData
   for(heightmapX=0;heightmapX<256;heightmapX++)
   {
      for(heightmapY=0;heightmapY<256;heightmapY++)
      {
         RGBApixel pixelTemp = heightmap.GetPixel(heightmapX,heightmapY);
                        heightmapData [heightmapX + heightmapY*256] = pixelTemp.Red*256;
      }
   }

   //Newton
   NewtonCollision* nTerrainCol = NewtonCreateHeightFieldCollision(
      nWorld,         //world pointer
      256,         //width
      256,            //height
      0,            //diagonal cut
      heightmapData,      //unsigned short* elevationMap - the actual elevation map as 16-bit integer array from ram
      0,
      400.0f,         //calcul one cell, check irrlicht scaling
      33.0f);         //maximum height
   //NewtonBody* nTerrain=NewtonCreateDynamicBody(nWorld, nTerrainCol,0);
   //NewtonDestroyCollision(nTerrainCol);



random idea of the day : when combat happen an explosion could change the color of the heightmap pixel to render a hole in the terrain ! lol copyright 2012 noals

edit : i found the answer on the net, i just need to understand it now lol. the function is expecting the array and i give it a pointer or something like that. i dont understand it fully because the memory allocation confuse me but i should be able to figure it out somehow. i will post again later.
noals
 
Posts: 32
Joined: Mon Sep 03, 2012 7:59 am

Re: using NewtonCreateHeightFieldCollision

Postby JoeJ » Tue Oct 02, 2012 7:20 am

Ah, i see now, newton has changed, but wiki was not updated.

If you use Visual C, you can detedt such cases by right clicking on the function name and chose "Go To Definition".
Then newton.h shows up:

Code: Select all
NEWTON_API NewtonCollision* NewtonCreateHeightFieldCollision (const NewtonWorld* const newtonWorld, int width, int height, int gridsDiagonals,
                                                  const dFloat* const elevationMap, const char* const attributeMap,  dFloat horizontalScale, int shapeID);


You see, const dFloat* const elevationMap has changed, it requests now a pointer to a float array.

Change:
Code: Select all
unsigned short *heightmapData= new float [256*256]; // allocate memory at runtime
...
heightmapData [heightmapX + heightmapY*256] = float(pixelTemp.Red)/255.0f; // 0.0 ... 1.0


...then it should compile.
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Next

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 513 guests

cron