New Near/Far system, and speed optimizations
This commit is contained in:
parent
464802e722
commit
9f5c9886c4
|
|
@ -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
|
||||
|
|
@ -236,8 +262,10 @@ set_block_size(unsigned short newbs) {
|
|||
}
|
||||
}
|
||||
}
|
||||
_max_level = (unsigned short) (log(float(_block_size)) / log(2.0));
|
||||
_is_dirty = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeoMipTerrain::is_dirty
|
||||
// Access: Published
|
||||
|
|
@ -252,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
|
||||
|
|
@ -264,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 near, double far) {
|
||||
_use_near_far = true;
|
||||
_near = near;
|
||||
_far = 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 near) {
|
||||
_use_near_far = true;
|
||||
_near = 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 far) {
|
||||
_use_near_far = true;
|
||||
_far = far;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeoMipTerrain::get_block_node_path
|
||||
// Access: Published
|
||||
|
|
@ -333,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(float(_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));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -414,6 +483,7 @@ set_heightfield(const Texture *tex) {
|
|||
_ysize = _heightfield.get_y_size();
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeoMipTerrain::set_color_map
|
||||
// Access: Published
|
||||
|
|
@ -445,6 +515,7 @@ set_color_map(const Texture *tex) {
|
|||
_is_dirty = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeoMipTerrain::has_color_map
|
||||
// Access: Published
|
||||
|
|
@ -454,6 +525,7 @@ INLINE bool GeoMipTerrain::
|
|||
has_color_map() {
|
||||
return _has_color_map;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeoMipTerrain::clear_color_map
|
||||
// Access: Published
|
||||
|
|
@ -466,6 +538,7 @@ clear_color_map() {
|
|||
_has_color_map = false;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeoMipTerrain::get_pixel_value
|
||||
// Access: Private
|
||||
|
|
@ -547,6 +620,7 @@ INLINE bool GeoMipTerrain::
|
|||
is_power_of_two(unsigned int i) {
|
||||
return !((i - 1) & i);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeoMipTerrain::f_part
|
||||
// Access: Private
|
||||
|
|
@ -561,6 +635,7 @@ INLINE double GeoMipTerrain::
|
|||
f_part(double i) {
|
||||
return i - floor(i);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeoMipTerrain::sfav
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Filename: geoMipTerrain.cxx
|
||||
// Created by: pro-rsoft (29jun07)
|
||||
// Last updated by: pro-rsoft (08mar08)
|
||||
// Last updated by: pro-rsoft (20sep08)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -67,7 +67,7 @@ generate_block(unsigned short mx,
|
|||
|
||||
// Create vertex data and writers
|
||||
PT(GeomVertexData) vdata = new GeomVertexData(_root.get_name(),
|
||||
GeomVertexFormat::register_format(format), Geom::UH_static);
|
||||
GeomVertexFormat::register_format(format), Geom::UH_stream);
|
||||
GeomVertexWriter cwriter;
|
||||
if (_has_color_map) {
|
||||
cwriter=GeomVertexWriter(vdata, "color" );
|
||||
|
|
@ -75,7 +75,7 @@ generate_block(unsigned short mx,
|
|||
GeomVertexWriter vwriter (vdata, "vertex" );
|
||||
GeomVertexWriter twriter (vdata, "texcoord");
|
||||
GeomVertexWriter nwriter (vdata, "normal" );
|
||||
PT(GeomTriangles) prim = new GeomTriangles(Geom::UH_static);
|
||||
PT(GeomTriangles) prim = new GeomTriangles(Geom::UH_stream);
|
||||
|
||||
if (_bruteforce) {
|
||||
// LOD Level when rendering bruteforce is always 0 (no lod)
|
||||
|
|
@ -83,8 +83,7 @@ generate_block(unsigned short mx,
|
|||
}
|
||||
|
||||
// Do some calculations with the level
|
||||
level = min(short(max(_min_level, level)), short(log(float(_block_size))
|
||||
/ log(2.0)));
|
||||
level = min(short(max(_min_level, level)), short(_max_level));
|
||||
unsigned short reallevel = level;
|
||||
level = int(pow(2.0, int(level)));
|
||||
|
||||
|
|
@ -505,7 +504,7 @@ calc_levels() {
|
|||
tvector.push_back(0);
|
||||
} else {
|
||||
tvector.push_back(min(short(max(_min_level, lod_decide(mx, my))),
|
||||
short(log(float(_block_size)) / log(2.0))));
|
||||
short(_max_level)));
|
||||
}
|
||||
}
|
||||
_levels.push_back(tvector); //push the new row of levels into the 2d vector
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Filename: geoMipTerrain.h
|
||||
// Created by: pro-rsoft (29jun07)
|
||||
// Last updated by: pro-rsoft (03mar08)
|
||||
// Last updated by: pro-rsoft (20sep08)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
@ -62,7 +62,7 @@ PUBLISHED:
|
|||
int x,int y);
|
||||
INLINE void set_bruteforce(bool bf);
|
||||
INLINE bool get_bruteforce();
|
||||
|
||||
|
||||
// The flatten mode specifies whether the terrain nodes are flattened
|
||||
// together after each terrain update.
|
||||
enum AutoFlattenMode {
|
||||
|
|
@ -75,9 +75,9 @@ PUBLISHED:
|
|||
// FM_strong: the terrain is flattened using flatten_strong.
|
||||
AFM_strong = 3,
|
||||
};
|
||||
|
||||
|
||||
INLINE void set_auto_flatten(int mode);
|
||||
|
||||
|
||||
// The focal point is the point at which the terrain will have the
|
||||
// lowest level of detail (highest quality). Parts farther away
|
||||
// from the focal point will hae a higher level of detail. The
|
||||
|
|
@ -90,14 +90,17 @@ PUBLISHED:
|
|||
INLINE void set_focal_point(NodePath fnp);
|
||||
INLINE NodePath get_focal_point() const;
|
||||
INLINE NodePath get_root() const;
|
||||
|
||||
|
||||
INLINE void set_block_size(unsigned short newbs);
|
||||
INLINE unsigned short get_block_size();
|
||||
INLINE unsigned short get_max_level();
|
||||
INLINE void set_min_level(unsigned short minlevel);
|
||||
INLINE unsigned short get_min_level();
|
||||
INLINE unsigned short get_block_size();
|
||||
INLINE void set_block_size(unsigned short newbs);
|
||||
INLINE bool is_dirty();
|
||||
INLINE float get_factor();
|
||||
INLINE void set_factor(float factor);
|
||||
INLINE void set_factor(float factor);
|
||||
INLINE void set_near_far(double near, double far);
|
||||
INLINE void set_near(double near);
|
||||
INLINE void set_far(double far);
|
||||
INLINE const NodePath get_block_node_path(unsigned short mx,
|
||||
unsigned short my);
|
||||
INLINE LVecBase2f get_block_from_pos(double x, double y);
|
||||
|
|
@ -106,8 +109,7 @@ PUBLISHED:
|
|||
bool update();
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
NodePath generate_block(unsigned short mx, unsigned short my, unsigned short level);
|
||||
bool update_block(unsigned short mx, unsigned short my,
|
||||
signed short level = -1, bool forced = false);
|
||||
|
|
@ -124,7 +126,7 @@ private:
|
|||
INLINE double get_pixel_value(int x, int y);
|
||||
INLINE double get_pixel_value(unsigned short mx, unsigned short my, int x, int y);
|
||||
INLINE unsigned short lod_decide(unsigned short mx, unsigned short my);
|
||||
|
||||
|
||||
NodePath _root;
|
||||
int _auto_flatten;
|
||||
bool _root_flattened;
|
||||
|
|
@ -135,7 +137,11 @@ private:
|
|||
unsigned int _xsize;
|
||||
unsigned int _ysize;
|
||||
float _factor;
|
||||
double _near;
|
||||
double _far;
|
||||
bool _use_near_far; // False to use the _factor, True to use the _near and _far values.
|
||||
unsigned short _block_size;
|
||||
unsigned short _max_level; // Highest level possible for this block size
|
||||
bool _bruteforce;
|
||||
NodePath _focal_point;
|
||||
bool _focal_is_temporary;
|
||||
|
|
|
|||
Loading…
Reference in New Issue