Simple method for implementing terrain collision?

Started by
23 comments, last by Norman Barrows 7 years, 4 months ago
png or jpeg or other lossy formats

png is a lossless format. Its image data is literally just Huffman encoding with some optional shuffling to make the encoding more efficient. Assuming its image format qualities work for you, it's a 100% perfectly fine format to use for essentially any purpose.

The problem with PNGs is that they only support basic 8-bit-depth RGB with non-premultiplied-alpha, more or less. A lot of higher-end content requires HDR or more capable colorspaces or such.

EDIT: PNG also supports 16-bit depth it turns out.

Sean Middleditch – Game Systems Engineer – Join my team!

Advertisement
But how can I be sure that I use grayscale and not rgb

Grayscale doesn't exist in PNG, I think. At least I always find it as a RGB image, with 256 colours, where each colour is a RGB triple (x, x, xi), ie all the same value.

Now if you have a paletted image, the usual approach is that colour i = RGB(i, i, i). That makes the index value equal to the color component value, and you can use the palette index as value in the greyscale.

As for knowing what you got, read the image library documentation, it normally has query functions to ask about the type of image that it loaded. It should also explain how the image array that you have is laid out. I expect single bytes if you have a paletted image, but check. For a non-paletted image, a 3-byte data type doesn't exist in C/C++, different libraries take different solutions. Some switch to a 4-byte type, others stay with single byte values, and put each channel (each colour component) in a different byte.

Edit: Some modern image libraries always convert to full RGB, as that's what a GPU needs.

And I heard somewhere that the human vision is not linear

Yep, read about human perception of rgb colours.

how do I regulate the height? Because 255.0f above the ground is too much.

Scale the range to what you need to have.

Can I somehow read the height map as 24 bit? If I can, what should I read, R, G or B?

What does that mean, 24bit often means 8bit R, 8bit G, 8bit B, or is a single channel (one colour component) 24 bit?

Alberth, I use this website: http://terrain.party/

What it does is that it allows me to download the heightmap of every place on the planet I want. And it stores it as a 16-bit png 1081x1081 res grayscale image because this is the best that the satellites can do. And using Blender, I can recreate the whole surface as a 3d model only by using the heightmap, it's super cool.

And the way I see it, 8-bit means 255 different options.

So if the png is 16bit, then it stores 65 535 different values of gray.

This means that in order to read one number, I need to parse 2 bytes. Should I worry about big-endian stuff or something like that?

From what I've read and tried, DeviL doesn't work with 16bit grayscale pngs, that's why I need to convert it, for example, to 32bit, but I don't know what happens under the hood when 16 bit grayscale gets converted to 32bit rgba.

There are programs that do this, but what's the logic of that. It seems to me that I will lose precision from 65535 to 255, right?

I'm doing something very wrong, because it doesn't work, I get wrong values and my character moves like this: /\/\/\/\/\/\/\/\/\/.

And the way I see it, 8-bit means 255 different options. So if the png is 16bit, then it stores 65 535 different values of gray.

That sounds correct, except that the first value you can store is 0 rather than 1, so it's 256 and 65536 different values.

This means that in order to read one number, I need to parse 2 bytes. Should I worry about big-endian stuff or something like that?

I would assume the PNG format has covered that, unless you want to write a PNG decoder yourself. If you load such an image with a library 16bit PNG support, you'll also run into that problem.

There are programs that do this, but what's the logic of that. It seems to me that I will lose precision from 65535 to 255, right?

That sounds likely as generic conversion program.

The question is, is that bad?

I'm doing something very wrong, because it doesn't work, I get wrong values and my character moves like this: /\/\/\/\/\/\/\/\/\/.

Your character is just jumpy :D

I can agree it doesn't look right, but that's about all I can conclude.

You have a long chain of things that you do to make the character aware of its height, and the problem is at least in one of the links of the chain. Question is, which one.

At a somewhat higher level, there are 3 parts.

- The satellite image converted to heightmap, loaded by DeviL, where you loose a factor 200 precision (probably)

- Code that derives the height from the loaded image

- Code that plot the character at the right height.

Any of this code can be wrong. Likely I missed a few steps.

There is also the other option, namely all code does what it is supposed to do, but you didn't realize some of the effects that it has. In other words, the code is ok, your ideas need to change. I name this option "computer outsmarts designer". It's a fun phase, where you get confronted with weird effects that are totally correct, but unexpected.

Before you can conclude the latter though, you need to proof the problem is not in the former chain of code. The usual process for that is called debugging, and it's an art in itself.

So far you have established that the end result is not as desired/expected, but is it wrong in the sense that the code is not doing what it is supposed to do?

Can you get the value that the code reading the height map is producing?

Also, can you get the height of your character?

These should match according to the conversion you implemented. In this way you can check the code that computes the height is doing its job

It will tell you Z=<some value> for your character. If you look at the screen, is the character drawn at the height that you expect? Maybe you want to add obejcts in the world with a known height so you have a reference.

This can tell you whether the drawing code draws things where they are supposed to be drawn.

If this all works, the chain from the image to the plotted height is good, so the problem is perhaps earlier. My next step would be to use a heightmap with known properties that I prepared myself. For example, flat, but one ridge, or some other known pattern.

Load the image, see how the program reacts. Does it do what you think it should do? ( Edit: "should do" in the sense the code does how it is programmed!)

If so, the problem is clearly somewhere in the conversion and/or loading of the satellite image. If it is not, it's time to think hard why a self-prepared image doesn't do what you want it to do.

Can you get the value that the code reading the height map is producing? Also, can you get the height of your character? These should match according to the conversion you implemented. In this way you can check the code that computes the height is doing its job

Yes, the mistake was here. The height data was totally wrong. And I found out the fault was in DevIL (and my fault too, for using that forgotten lib) But basically, devil lib doesn't know how to handle 8-bit and 16-bit images, and it tries to convert it to 32 bit, but in my case, something goes wrong and I end up with 8-bit totally wrong grayscale image.

What I did is to open the image with Paint and export it as 32 bit .png and then I just read the R values, because they are all the same. And now the heightmap works perfectly.

Thanks a lot man, again. I missed that Heureka moment because you kind of debugged it for me. But it's still kind of cool. I even made a gif.

[attachment=34209:heightmapgif.gif]

I thought the Heureka moment was when you see it's actually doing what you thought it should do :D

I mostly just showed you the kind of reasoning that goes behind finding the cause of a problem, hopefully you can apply that a next time.

Image looks great :)

Grayscale doesn't exist in PNG, I think.

PNG supports grayscale at several bit depths and both with and without alpha.

Sean Middleditch – Game Systems Engineer – Join my team!

Alberth, I use this website: http://terrain.party/ What it does is that it allows me to download the heightmap of every place on the planet I want. And it stores it as a 16-bit png 1081x1081 res grayscale image because this is the best that the satellites can do. And using Blender, I can recreate the whole surface as a 3d model only by using the heightmap, it's super cool.

dude i need that for AIRSHIPS!

ok, now i'm REALLY interested! <g>

try a dump or convert and see what they mean by "greyscale". odds are its the same value for r,g,and b. so you have a 16 bit value, and you can read any channel, r.g or b. on the website, they probably supply a scale factor too that scales the 64K values to real altitudes, as well as the number of real-world meters between pixels.

worst comes to worst you look up the spec for 16 bit png, and write some code that reads a png and extracts the required data into a simple 2d array of bytes, words, etc, as the case may be. then write it out as a bin file. custom file formats designed for the game in question are almost always the most efficient way to go.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

I even made a gif.

sweet!

is that your own code rendering the imported satellite heightmap data?

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

odds are its the same value for r,g,and b

Got the 16bit from the website, converted it to 32bit with Paint, and r, g, b are the same, yes.

is that your own code rendering the imported satellite heightmap data?

Yes, but it's not hard at all. I even posted it here somewhere. But I use a library to load the image. When you export the data from the website, you will get 4-5 images in an archive, choose the one with the name "merged". Others would maybe have some problems with the height values.

This topic is closed to new replies.

Advertisement