i wonder whether getNormal() produce correct result:
as getNormal() request 2 INT type value, it calculates the normal at the location of a pixel in the heightfield image? not the location between pixels?
but there are 8 other pixels around a pixel, each has different brightness (meaning different heights), how can a pixel decide its normal?
It works bilinearly, which means that it uses the difference in height with 4 neighbouring pixels to calculate the normal vector.
The source is always your friend, so I copied the relevant method for you:
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::get_normal
// Access: Published
// Description: Fetches the terrain normal at (x, y), where the
// input coordinate is specified in pixels. This
// ignores the current LOD level and instead provides
// an accurate number.
// Terrain scale is NOT taken into account! To get
// accurate normals, please divide it by the
// terrain scale and normalize it again, like this:
//
// LVector3f normal (terr.get_normal(x, y));
// normal.set(normal.get_x() / root.get_sx(),
// normal.get_y() / root.get_sy(),
// normal.get_z() / root.get_sz());
// normal.normalize();
////////////////////////////////////////////////////////////////////
LVector3f GeoMipTerrain::
get_normal(int x, int y) {
int nx = x - 1;
int px = x + 1;
int ny = y - 1;
int py = y + 1;
if (nx < 0) nx++;
if (ny < 0) ny++;
if (px >= int(_xsize)) px--;
if (py >= int(_ysize)) py--;
double drx = get_pixel_value(px, y) - get_pixel_value(nx, y);
double dry = get_pixel_value(x, py) - get_pixel_value(x, ny);
LVector3f normal(drx * 0.5, dry * 0.5, 1);
normal.normalize();
return normal;
}