Landscape, Model or Heightmap?

Started by Kaiidyn, February 04, 2011, 09:53:27 PM

Previous topic - Next topic

Kaiidyn

What is better to use for a landscape/terrain with hills etc,
an 3D model (3ds?) or an Heightmap texture..

I have been screwing around with heightmaps for a bit now, attempting to make a nice (easy to use (HARD TO MAKE;o) class for it.
but is it really worth the effort.. ? or could I better use a model for terrain.. (looking at resource usage for mobile devices)

I'd rather use heightmaps, but what I cant figure out is a nice way to read the file..
As the one in the wiki (i posted) has like 3 for loops that needs to loop through the x*y size of the image.
and that consumes a whole lot of time..
I am trying to get a 256x256 heightmap image to load.. but it takes about 4 minutes just to loop through the for's..
Anyone know of a better way to handle heightmaps?

Or maybe a proper way to use a model with collision detection (get y from specific x/z on the object)..

Kind regards,
Kaiidyn..
Clean code is simple and direct. Clean code reads like well-written prose. Clean code never obscures the designer's intent but rather is full of crisp abstractions and straightforward lines of control. - Grady Booch

EgonOlsen

You can use terragen to create model and heightmap (if you need the heightmap for collisions)...any maybe use VIZup (as described by paulscode in the wiki) to reduce the terrains polygon count. I wouldn't head for creating the model from the heightmap directly on the phone. If you want to do this, do it in an offline process on the desktop and use the serialized version on the phone. I really recommend to use serialized objects on the phone instead of loading the models in "real" file formats or creating them at runtime.

Kaiidyn

How do i get the pixel data from an texture in jpct desktop version?
Clean code is simple and direct. Clean code reads like well-written prose. Clean code never obscures the designer's intent but rather is full of crisp abstractions and straightforward lines of control. - Grady Booch

EgonOlsen

You can abuse the ITextureEffect for this.

Kaiidyn

hmm, cant seem to figure it out,
got an example by any chance ?
Clean code is simple and direct. Clean code reads like well-written prose. Clean code never obscures the designer's intent but rather is full of crisp abstractions and straightforward lines of control. - Grady Booch

EgonOlsen

Just implement that interface, assign your implementation to the texture in question and call applyEffect() on it once. That will call apply() in your implementation. There, you simply copy the data from src to dest AND into your own structure...and voila, you have access to the texture's pixel data.

Kaiidyn

Clean code is simple and direct. Clean code reads like well-written prose. Clean code never obscures the designer's intent but rather is full of crisp abstractions and straightforward lines of control. - Grady Booch

EgonOlsen

Can't post code ATM, but you simply implement that interface. That impl can be assigned to a texture. You then call applyEffect on that texture. That will call your apply implementation. In that one, you copy the src array to dest and in addition into your own structure. Then access this structure for getting the pixel data. It's really simple, just give it a try and you'll see...

Kaiidyn

Ok, I got the pixel data now... I think..

I got a 256x256 image, so the length should be 256*256=65536, however it is 65792...
What else is in there?

Also, the pixel data in int[] is a number eg. 11053224.... what is it, and how can I 'transform' it into something I need for heightmaps?
Clean code is simple and direct. Clean code reads like well-written prose. Clean code never obscures the designer's intent but rather is full of crisp abstractions and straightforward lines of control. - Grady Booch

EgonOlsen

The array contains the last line doubled. You can ignore this, it's for historical reasons only. jPCT-AE doesn't need this additional line...maybe i should remove it.

The data is the pixel in (A)RGB format. You can extract the colors like so

int r=(color>>16)&0xff;
int g=(color>>8)&0xff;
int b=color&0xff;

Kaiidyn

#10
yay, got it working....
exporting as ser file works too, except for the fact that it becomes a 16mb file O.o
is there a possibility script-wise, to reduce the polygons? as 65536 is kind of A LOT.


edit: resized my heightmap manually to 128x128, but that still leaves me with a 4mb file... personally I think that is too large..
Clean code is simple and direct. Clean code reads like well-written prose. Clean code never obscures the designer's intent but rather is full of crisp abstractions and straightforward lines of control. - Grady Booch

EgonOlsen

Just zip it and load it from a zipped input stream. These ser-files compress pretty well.

Kaiidyn

lol wow, the zipped file became like 1.7mb :o
however.. using ZipInputStream on android takes forever to extract the 18mb file, and ran out of memory..
so I manually resized the heightmap to 128 and the ser file became 4mb, zip file now is only 644.2kb but still loading takes a while.
or I am doing something wrong..

ByteArrayOutputStream terr = new ByteArrayOutputStream();
ByteArrayOutputStream terrTexture = new ByteArrayOutputStream();

try {
ZipInputStream zip = new ZipInputStream(res.openRawResource(R.raw.terrain));
ZipEntry ze = null;
   
while ((ze = zip.getNextEntry()) != null) {
if(ze.getName().equals("terrain.ser")){
for (int c = zip.read(); c != -1; c = zip.read()) {
terr.write(c);
}
zip.closeEntry();
}
if(ze.getName().equals("texture.png")){
for (int c = zip.read(); c != -1; c = zip.read()) {
terrTexture.write(c);
}
zip.closeEntry();
}
}
   
} catch (IOException e) {
e.printStackTrace();
}
tm.addTexture("terrainTexture", new Texture(new ByteArrayInputStream(terrTexture.toByteArray()), false));
Object3D terrain = Loader.loadSerializedObject(new ByteArrayInputStream(terr.toByteArray()));
terrain.setTexture("terrainTexture");
terrain.build();
world.addObject(terrain);
Clean code is simple and direct. Clean code reads like well-written prose. Clean code never obscures the designer's intent but rather is full of crisp abstractions and straightforward lines of control. - Grady Booch

EgonOlsen

Don't unzip yourself. Just do something like:


ZipInputStream zis = new ZipInputStream(ress.openRawResource(R.raw.terrain));
try {
zis.getNextEntry();
} catch (IOException e) {
throw new RuntimeException(e);
}
terrain = Loader.loadSerializedObject(zis);

Kaiidyn

*testing it*
Wow, that was like.... instant :o
thanks. :)
Clean code is simple and direct. Clean code reads like well-written prose. Clean code never obscures the designer's intent but rather is full of crisp abstractions and straightforward lines of control. - Grady Booch