back to head

This commit is contained in:
rdb 2008-10-30 11:42:32 +00:00
parent 4b2ca15c43
commit a60a4dd581

View File

@ -1,6 +1,6 @@
// Filename: geoMipTerrain.I
// Created by: pro-rsoft (29jun07)
// Last updated by: pro-rsoft (03mar08)
// Last updated by: pro-rsoft (24sep08)
//
////////////////////////////////////////////////////////////////////
//
@ -13,6 +13,8 @@
//
////////////////////////////////////////////////////////////////////
#include "config_grutil.h"
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::Constructor
// Access: Published
@ -24,9 +26,13 @@ GeoMipTerrain(const string &name) {
_root_flattened = false;
_xsize = 0;
_ysize = 0;
_min_level = 0;
_block_size = 16;
_max_level = 4; // Always log(_block_size) / log(2.0)
_min_level = 0;
_factor = 100.0;
_near = 16.0;
_far = 128.0;
_use_near_far = false;
_has_color_map = false;
PT(PandaNode) tmpnode = new PandaNode("tmp_focal");
_auto_flatten = AFM_off;
@ -58,6 +64,7 @@ INLINE PNMImage &GeoMipTerrain::
heightfield() {
return _heightfield;
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::color_map
// Access: Published
@ -69,6 +76,7 @@ INLINE PNMImage &GeoMipTerrain::
color_map() {
return _color_map;
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::set_bruteforce
// Access: Published
@ -85,6 +93,7 @@ set_bruteforce(bool bf) {
}
_bruteforce = bf;
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::get_bruteforce
// Access: Published
@ -96,6 +105,7 @@ INLINE bool GeoMipTerrain::
get_bruteforce() {
return _bruteforce;
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::set_auto_flatten
// Access: Private
@ -103,12 +113,12 @@ get_bruteforce() {
// flatten_light, flatten_medium, or flatten_strong)
// after each update. This only affects future
// updates, it doesn't flatten the current terrain.
//
////////////////////////////////////////////////////////////////////
INLINE void GeoMipTerrain::
set_auto_flatten(int mode) {
_auto_flatten = mode;
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::set_focal_point
// Access: Published
@ -153,6 +163,7 @@ set_focal_point(NodePath fp) {
_focal_point = fp;
_focal_is_temporary = false;
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::get_focal_point
// Access: Published
@ -193,6 +204,7 @@ INLINE void GeoMipTerrain::
set_min_level(unsigned short minlevel) {
_min_level = minlevel;
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::get_min_level
// Access: Published
@ -205,6 +217,19 @@ INLINE unsigned short GeoMipTerrain::
get_min_level() {
return _min_level;
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::get_max_level
// Access: Published
// Description: Returns the highest level possible for this block
// size. When a block is at this level, it will be
// the worst quality possible.
////////////////////////////////////////////////////////////////////
INLINE unsigned short GeoMipTerrain::
get_max_level() {
return _max_level;
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::get_block_size
// Access: Published
@ -214,6 +239,7 @@ INLINE unsigned short GeoMipTerrain::
get_block_size() {
return _block_size;
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::set_block_size
// Access: Published
@ -239,6 +265,7 @@ set_block_size(unsigned short newbs) {
_max_level = (unsigned short) (log((double) _block_size) / log(2.0));
_is_dirty = true;
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::is_dirty
// Access: Published
@ -253,10 +280,12 @@ INLINE bool GeoMipTerrain::
is_dirty() {
return _is_dirty;
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::set_factor
// Access: Published
// Description: Sets the quality factor at which blocks must be
// Description: DEPRECATED method. Use set_near/far instead.
// Sets the quality factor at which blocks must be
// generated. The higher this level, the better
// quality the terrain will be, but more expensive
// to render. A value of 0 makes the terrain the
@ -265,22 +294,49 @@ is_dirty() {
////////////////////////////////////////////////////////////////////
INLINE void GeoMipTerrain::
set_factor(float factor) {
grutil_cat.debug() << "Using deprecated method set_factor, use set_near and set_far instead!\n";
_use_near_far = false;
_factor = factor;
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::get_factor
// Function: GeoMipTerrain::set_near_far
// Access: Published
// Description: Gets the quality factor at which blocks must be
// generated. The higher this level, the better
// quality the terrain will be, but more expensive
// to render. A value of 0 makes the terrain the
// lowest quality possible, depending on blocksize.
// The default value is 100.
// Description: Sets the near and far LOD distances in one call.
////////////////////////////////////////////////////////////////////
INLINE float GeoMipTerrain::
get_factor() {
return _factor;
INLINE void GeoMipTerrain::
set_near_far(double input_near, double input_far) {
_use_near_far = true;
_near = input_near;
_far = input_far;
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::set_near
// Access: Published
// Description: Sets the near LOD distance, at which the terrain
// will be rendered at highest quality.
// This distance is in the terrain's coordinate space!
////////////////////////////////////////////////////////////////////
INLINE void GeoMipTerrain::
set_near(double input_near) {
_use_near_far = true;
_near = input_near;
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::set_far
// Access: Published
// Description: Sets the far LOD distance, at which the terrain
// will be rendered at lowest quality.
// This distance is in the terrain's coordinate space!
////////////////////////////////////////////////////////////////////
INLINE void GeoMipTerrain::
set_far(double input_far) {
_use_near_far = true;
_far = input_far;
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::get_block_node_path
// Access: Published
@ -334,13 +390,25 @@ lod_decide(unsigned short mx, unsigned short my) {
cx = (cx * _block_size + _block_size / 2) * _root.get_sx();
cy = (cy * _block_size + _block_size / 2) * _root.get_sy();
float d;
if (_factor > 0.0) {
if (_use_near_far) {
d = sqrt(pow(_focal_point.get_x(_root) - cx, 2) +
pow(_focal_point.get_y(_root) - cy, 2)) / _factor;
pow(_focal_point.get_y(_root) - cy, 2));
if (d < _near) {
return 0;
} else if (d > _far) {
return _max_level;
} else {
return (d - _near) / (_far - _near) * _max_level * (1.0 - (_min_level / _max_level)) + _min_level;
}
} else {
d = log((double) _block_size) / log(2.0);
if (_factor > 0.0) {
d = sqrt(pow(_focal_point.get_x(_root) - cx, 2) +
pow(_focal_point.get_y(_root) - cy, 2)) / _factor;
} else {
d = _max_level;
}
return short(floor(d));
}
return short(floor(d));
}
////////////////////////////////////////////////////////////////////
@ -390,6 +458,7 @@ set_heightfield(const Filename &filename, PNMFileType *ftype) {
}
return false;
}
INLINE bool GeoMipTerrain::
set_heightfield(const PNMImage &image) {
// Before we apply anything, validate the size.
@ -404,12 +473,10 @@ set_heightfield(const PNMImage &image) {
}
return false;
}
INLINE bool GeoMipTerrain::
set_heightfield(const Texture *tex) {
grutil_cat.warning() << "Setting a texture as heightfield image is deprecated!\n";
PNMImage image;
tex->store(image);
return set_heightfield(image);
set_heightfield(const string &path) {
return set_heightfield(Filename(path));
}
////////////////////////////////////////////////////////////////////
@ -430,6 +497,7 @@ set_color_map(const Filename &filename, PNMFileType *ftype) {
}
return false;
}
INLINE bool GeoMipTerrain::
set_color_map(const PNMImage &image) {
_color_map.copy_from(image);
@ -437,12 +505,19 @@ set_color_map(const PNMImage &image) {
_has_color_map = true;
return true;
}
INLINE bool GeoMipTerrain::
set_color_map(const Texture *tex) {
tex->store(_color_map);
_is_dirty = true;
return true;
}
INLINE bool GeoMipTerrain::
set_color_map(const string &path) {
return set_color_map(Filename(path));
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::has_color_map
// Access: Published
@ -452,6 +527,7 @@ INLINE bool GeoMipTerrain::
has_color_map() {
return _has_color_map;
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::clear_color_map
// Access: Published
@ -464,6 +540,7 @@ clear_color_map() {
_has_color_map = false;
}
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::get_pixel_value
// Access: Private
@ -475,11 +552,13 @@ INLINE double GeoMipTerrain::
get_pixel_value(int x, int y) {
x = max(min(x,int(_xsize-1)),0);
y = max(min(y,int(_ysize-1)),0);
return double(_heightfield.get_bright(int(x),int(y)));
/* return double(_heightfield.get_red_val(int(x),int(y))
+ _heightfield.get_green_val(int(x),int(y)) * 256
+ _heightfield.get_blue_val(int(x),int(y)) * 65536) / 16777215.0;
*/
if (_heightfield.is_grayscale()) {
return double(_heightfield.get_bright(x, y));
} else {
return double(_heightfield.get_red(x, y))
+ double(_heightfield.get_green(x, y)) / 256.0
+ double(_heightfield.get_blue(x, y)) / 65536.0;
}
}
INLINE double GeoMipTerrain::
get_pixel_value(unsigned short mx, unsigned short my, int x, int y) {
@ -545,6 +624,7 @@ INLINE bool GeoMipTerrain::
is_power_of_two(unsigned int i) {
return !((i - 1) & i);
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::f_part
// Access: Private
@ -559,6 +639,7 @@ INLINE double GeoMipTerrain::
f_part(double i) {
return i - floor(i);
}
////////////////////////////////////////////////////////////////////
// Function: GeoMipTerrain::sfav
// Access: Private