mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
Overhauled T-Junction and border-decision math, added border stitching
This commit is contained in:
parent
92927fd25f
commit
d5af6f1cce
@ -1,6 +1,5 @@
|
||||
// Filename: geoMipTerrain.I
|
||||
// Created by: pro-rsoft (29jun07)
|
||||
// Last updated by: pro-rsoft (30oct08)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@ -40,6 +39,7 @@ GeoMipTerrain(const string &name) {
|
||||
_focal_is_temporary = true;
|
||||
_is_dirty = true;
|
||||
_bruteforce = false;
|
||||
_stitching = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -420,45 +420,6 @@ lod_decide(unsigned short mx, unsigned short my) {
|
||||
// If the heightmap is not a power of two plus one,
|
||||
// it is scaled up using a gaussian filter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeoMipTerrain::
|
||||
set_heightfield(const Filename &filename, PNMFileType *ftype) {
|
||||
// First, we need to load the header to determine the size and format.
|
||||
PNMImageHeader imgheader;
|
||||
if (imgheader.read_header(filename, ftype)) {
|
||||
// Copy over the header to the heightfield image.
|
||||
_heightfield.copy_header_from(imgheader);
|
||||
|
||||
if(!is_power_of_two(imgheader.get_x_size() - 1) || !is_power_of_two(imgheader.get_y_size() - 1)) {
|
||||
// Calculate the nearest power-of-two-plus-one size.
|
||||
unsigned int reqx, reqy;
|
||||
reqx = max(3, (int) pow(2.0, ceil(log((double) max(2, imgheader.get_x_size() - 1)) / log(2.0))) + 1);
|
||||
reqy = max(3, (int) pow(2.0, ceil(log((double) max(2, imgheader.get_y_size() - 1)) / log(2.0))) + 1);
|
||||
|
||||
// If it's not a valid size, tell PNMImage to resize it.
|
||||
if (reqx != imgheader.get_x_size() || reqy != imgheader.get_y_size()) {
|
||||
grutil_cat.warning() << "Rescaling heightfield image " << filename << " to "
|
||||
<< reqx << " by " << reqy << " pixels\n";
|
||||
_heightfield.set_read_size(reqx, reqy);
|
||||
}
|
||||
}
|
||||
|
||||
// Read the real image now
|
||||
if (!_heightfield.read(filename, ftype)) {
|
||||
_heightfield.clear_read_size();
|
||||
grutil_cat.error() << "Failed to read heightfield image " << filename << "!\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
_is_dirty = true;
|
||||
_xsize = _heightfield.get_x_size();
|
||||
_ysize = _heightfield.get_y_size();
|
||||
return true;
|
||||
} else {
|
||||
grutil_cat.error() << "Failed to load heightfield image " << filename << "!\n";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
INLINE bool GeoMipTerrain::
|
||||
set_heightfield(const PNMImage &image) {
|
||||
// Before we apply anything, validate the size.
|
||||
@ -541,6 +502,37 @@ clear_color_map() {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeoMipTerrain::set_border_stitching
|
||||
// Access: Published
|
||||
// Description: If this value is true, the LOD level at the
|
||||
// borders of the terrain will be 0. This is useful
|
||||
// if you have multiple terrains attached and you
|
||||
// want to stitch them together, to fix seams.
|
||||
// This setting also has effect when bruteforce is
|
||||
// enabled, although in that case you are probably
|
||||
// better off with setting the minlevels to the same
|
||||
// value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeoMipTerrain::
|
||||
set_border_stitching(bool stitching) {
|
||||
if (stitching && !_stitching) {
|
||||
_is_dirty = true;
|
||||
}
|
||||
_stitching = stitching;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeoMipTerrain::get_stitching
|
||||
// Access: Published
|
||||
// Description: Returns the current stitching setting. False by
|
||||
// default, unless set_stitching has been set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeoMipTerrain::
|
||||
get_border_stitching() {
|
||||
return _stitching;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeoMipTerrain::get_pixel_value
|
||||
// Access: Private
|
||||
@ -587,33 +579,6 @@ get_normal(unsigned short mx, unsigned short my, int x, int y) {
|
||||
(my * _block_size + y));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeoMipTerrain::int2str
|
||||
// Access: Private
|
||||
// Description: Converts the given int to a std::string.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE std::string GeoMipTerrain::
|
||||
int_to_str(int i) {
|
||||
std::stringstream ss;
|
||||
std::string str;
|
||||
ss << i;
|
||||
ss >> str;
|
||||
return str;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeoMipTerrain::str2int
|
||||
// Access: Private
|
||||
// Description: Converts the given std::string to an int.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeoMipTerrain::
|
||||
str_to_int(std::string str) {
|
||||
std::istringstream strin(str);
|
||||
int i;
|
||||
strin >> i;
|
||||
return i;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeoMipTerrain::is_power_of_two
|
||||
// Access: Private
|
||||
|
@ -1,6 +1,5 @@
|
||||
// Filename: geoMipTerrain.cxx
|
||||
// Created by: pro-rsoft (29jun07)
|
||||
// Last updated by: pro-rsoft (17jan09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@ -82,17 +81,24 @@ generate_block(unsigned short mx,
|
||||
|
||||
if (_bruteforce) {
|
||||
// LOD Level when rendering bruteforce is always 0 (no lod)
|
||||
// Unless a minlevel is set- this is handled later.
|
||||
level = 0;
|
||||
}
|
||||
|
||||
// Do some calculations with the level
|
||||
level = min(short(max(_min_level, level)), short(_max_level));
|
||||
level = min(max(_min_level, level), _max_level);
|
||||
unsigned short reallevel = level;
|
||||
level = int(pow(2.0, int(level)));
|
||||
|
||||
// Stores the max and min heights.
|
||||
float minh = 1.0f;
|
||||
float maxh = 0.0f;
|
||||
// Neighbor levels and junctions
|
||||
unsigned short lnlevel = get_neighbor_level(mx, my, -1, 0);
|
||||
unsigned short rnlevel = get_neighbor_level(mx, my, 1, 0);
|
||||
unsigned short bnlevel = get_neighbor_level(mx, my, 0, -1);
|
||||
unsigned short tnlevel = get_neighbor_level(mx, my, 0, 1);
|
||||
bool ljunction = (lnlevel != reallevel);
|
||||
bool rjunction = (rnlevel != reallevel);
|
||||
bool bjunction = (bnlevel != reallevel);
|
||||
bool tjunction = (tnlevel != reallevel);
|
||||
|
||||
// Confusing note:
|
||||
// the variable level contains not the actual level as described
|
||||
@ -101,49 +107,43 @@ generate_block(unsigned short mx,
|
||||
|
||||
// This is the number of vertices at the certain level.
|
||||
unsigned short lowblocksize = _block_size / level + 1;
|
||||
|
||||
srand(time(NULL));
|
||||
for (int x = 0; x <= _block_size; x++) {
|
||||
for (int y = 0; y <= _block_size; y++) {
|
||||
if ((x % level) == 0 && (y % level) == 0) {
|
||||
if (_has_color_map) {
|
||||
LVecBase4d color = _color_map.get_xel_a(int((mx * _block_size + x)
|
||||
/ double(_xsize) * _color_map.get_x_size()),
|
||||
int((my * _block_size + y)
|
||||
/ double(_ysize) * _color_map.get_y_size()));
|
||||
cwriter.add_data4f(color.get_x(), color.get_y(),
|
||||
color.get_z(), color.get_w());
|
||||
//LVecBase4d color = _color_map.get_xel_a(int((mx * _block_size + x)
|
||||
/// double(_xsize) * _color_map.get_x_size()),
|
||||
// int((my * _block_size + y)
|
||||
// / double(_ysize) * _color_map.get_y_size()));
|
||||
//cwriter.add_data4f(LCAST(float, color));
|
||||
|
||||
cwriter.add_data4f(rand() / float(RAND_MAX), rand() / float(RAND_MAX), rand() / float(RAND_MAX), 1);
|
||||
}
|
||||
float pval = get_pixel_value(mx, my, x, y);
|
||||
if (pval < minh) minh = pval;
|
||||
if (pval > maxh) maxh = pval;
|
||||
vwriter.add_data3f(x - 0.5 * _block_size, y - 0.5 * _block_size, pval);
|
||||
twriter.add_data2f((mx * _block_size + x) / double(_xsize - 1),
|
||||
(my * _block_size + y) / double(_ysize - 1));
|
||||
nwriter.add_data3f(get_normal(mx, my, x, y));
|
||||
if (x > 0 && y > 0) {
|
||||
//left border
|
||||
if (!_bruteforce && x == level && mx > 0 && _levels[mx - 1][my] > reallevel) {
|
||||
// Left border
|
||||
if (x == level && ljunction) {
|
||||
if (y > level && y < _block_size) {
|
||||
prim->add_vertex(min(max(sfav(y / level, _levels[mx - 1][my], reallevel), 0), lowblocksize - 1));
|
||||
prim->add_vertex(min(max(sfav(y / level, lnlevel, reallevel), 0), lowblocksize - 1));
|
||||
prim->add_vertex(vcounter - 1);
|
||||
prim->add_vertex(vcounter);
|
||||
prim->close_primitive();
|
||||
}
|
||||
if (f_part((y / level) / float(pow(2.0, int(_levels[mx - 1][my] - reallevel)))) == 0.5) {
|
||||
prim->add_vertex(min(max(sfav(y / level + 1, _levels[mx - 1][my], reallevel), 0), lowblocksize - 1));
|
||||
prim->add_vertex(min(max(sfav(y / level - 1, _levels[mx - 1][my], reallevel), 0), lowblocksize - 1));
|
||||
if (f_part((y / level) / float(pow(2.0, int(lnlevel - reallevel)))) == 0.5) {
|
||||
prim->add_vertex(min(max(sfav(y / level + 1, lnlevel, reallevel), 0), lowblocksize - 1));
|
||||
prim->add_vertex(min(max(sfav(y / level - 1, lnlevel, reallevel), 0), lowblocksize - 1));
|
||||
prim->add_vertex(vcounter);
|
||||
prim->close_primitive();
|
||||
}
|
||||
} else if (_bruteforce ||
|
||||
(!(y == level && x > level && x < _block_size && my > 0
|
||||
&& _levels[mx][my - 1] > reallevel) &&
|
||||
!(x == _block_size && mx < (_xsize - 1) / (_block_size) - 1
|
||||
&& _levels[mx + 1][my] > reallevel) &&
|
||||
!(x == _block_size && y > level && y < _block_size && mx < (_xsize - 1) / (_block_size) - 1
|
||||
&& _levels[mx + 1][my] > reallevel) &&
|
||||
!(y == _block_size && x > level && x < _block_size && my < (_ysize - 1) / (_block_size) - 1
|
||||
&& _levels[mx][my + 1] > reallevel))) {
|
||||
} else if (
|
||||
(!(bjunction && y == level && x > level && x < _block_size) &&
|
||||
!(rjunction && x == _block_size) &&
|
||||
!(tjunction && y == _block_size && x > level && x < _block_size))) {
|
||||
if ((x <= center && y <= center) || (x > center && y > center)) {
|
||||
if (x > center) {
|
||||
prim->add_vertex(vcounter - lowblocksize - 1);
|
||||
@ -167,36 +167,39 @@ generate_block(unsigned short mx,
|
||||
}
|
||||
prim->close_primitive();
|
||||
}
|
||||
//right border
|
||||
if (!_bruteforce && x == _block_size - level && mx < (_xsize - 1) / (_block_size) - 1 && _levels[mx + 1][my] > reallevel) {
|
||||
if (y > level && y < _block_size - level + 1) {
|
||||
prim->add_vertex(lowblocksize * (lowblocksize - 1) + min(max(sfav(y / level, _levels[mx + 1][my], reallevel), 0), lowblocksize - 1));
|
||||
// Right border
|
||||
if (x == _block_size - level && rjunction) {
|
||||
if (y > level && y < _block_size) {
|
||||
prim->add_vertex(lowblocksize * (lowblocksize - 1) + min(max(sfav(y / level, rnlevel, reallevel), 0), lowblocksize - 1));
|
||||
prim->add_vertex(vcounter);
|
||||
prim->add_vertex(vcounter - 1);
|
||||
prim->close_primitive();
|
||||
}
|
||||
if (f_part((y / level)/float(pow(2.0, int(_levels[mx + 1][my]-reallevel)))) == 0.5) {
|
||||
prim->add_vertex(lowblocksize * (lowblocksize - 1) + min(max(sfav(y / level - 1, _levels[mx + 1][my], reallevel), 0), lowblocksize - 1));
|
||||
prim->add_vertex(lowblocksize * (lowblocksize - 1) + min(max(sfav(y / level + 1, _levels[mx + 1][my], reallevel), 0), lowblocksize - 1));
|
||||
if (f_part((y / level) / float(pow(2.0, int(rnlevel - reallevel)))) == 0.5) {
|
||||
prim->add_vertex(lowblocksize * (lowblocksize - 1) + min(max(sfav(y / level - 1, rnlevel, reallevel), 0), lowblocksize - 1));
|
||||
prim->add_vertex(lowblocksize * (lowblocksize - 1) + min(max(sfav(y / level + 1, rnlevel, reallevel), 0), lowblocksize - 1));
|
||||
prim->add_vertex(vcounter);
|
||||
prim->close_primitive();
|
||||
}
|
||||
}
|
||||
//bottom border
|
||||
if (!_bruteforce && y == level && my > 0 && _levels[mx][my - 1] > reallevel) {
|
||||
// Bottom border
|
||||
if (y == level && bjunction) {
|
||||
if (x > level && x < _block_size) {
|
||||
prim->add_vertex(vcounter);
|
||||
prim->add_vertex(vcounter - lowblocksize);
|
||||
prim->add_vertex(min(max(sfav(x / level, _levels[mx][my - 1], reallevel), 0), lowblocksize - 1) * lowblocksize);
|
||||
prim->add_vertex(min(max(sfav(x / level, bnlevel, reallevel), 0), lowblocksize - 1) * lowblocksize);
|
||||
prim->close_primitive();
|
||||
}
|
||||
if (f_part((x / level)/float(pow(2.0, int(_levels[mx][my - 1]-reallevel)))) == 0.5) {
|
||||
prim->add_vertex(min(max(sfav(x / level - 1, _levels[mx][my - 1], reallevel), 0), lowblocksize - 1) * lowblocksize);
|
||||
prim->add_vertex(min(max(sfav(x / level + 1, _levels[mx][my - 1], reallevel), 0), lowblocksize - 1) * lowblocksize);
|
||||
if (f_part((x / level) / float(pow(2.0, int(bnlevel - reallevel)))) == 0.5) {
|
||||
prim->add_vertex(min(max(sfav(x / level - 1, bnlevel, reallevel), 0), lowblocksize - 1) * lowblocksize);
|
||||
prim->add_vertex(min(max(sfav(x / level + 1, bnlevel, reallevel), 0), lowblocksize - 1) * lowblocksize);
|
||||
prim->add_vertex(vcounter);
|
||||
prim->close_primitive();
|
||||
}
|
||||
} else if (_bruteforce || (!(x == level && y > level && y < _block_size && mx > 0 && _levels[mx - 1][my] > reallevel) && !(x == _block_size && y > level && y < _block_size && mx < (_xsize - 1) / (_block_size) - 1 && _levels[mx + 1][my] > reallevel) && !(x == _block_size && y > level && y < _block_size && mx < (_xsize - 1) / (_block_size) - 1 && _levels[mx + 1][my] > reallevel) && !(y == _block_size && my < (_ysize - 1) / (_block_size) - 1 && _levels[mx][my + 1] > reallevel))) {
|
||||
} else if (
|
||||
(!(ljunction && x == level && y > level && y < _block_size) &&
|
||||
!(tjunction && y == _block_size) &&
|
||||
!(rjunction && x == _block_size && y > level && y < _block_size))) {
|
||||
if ((x <= center && y <= center) || (x > center && y > center)) {
|
||||
if (y > center) {
|
||||
prim->add_vertex(vcounter);
|
||||
@ -220,17 +223,17 @@ generate_block(unsigned short mx,
|
||||
}
|
||||
prim->close_primitive();
|
||||
}
|
||||
//top border
|
||||
if (!_bruteforce && y == _block_size - level && my < (_xsize - 1) / (_block_size) - 1 && _levels[mx][my + 1] > reallevel) {
|
||||
if (x > level && x < _block_size - level + 1) {
|
||||
prim->add_vertex(min(max(sfav(x / level, _levels[mx][my + 1], reallevel), 0), lowblocksize - 1) * lowblocksize + lowblocksize - 1);
|
||||
// Top border
|
||||
if (y == _block_size - level && tjunction) {
|
||||
if (x > level && x < _block_size) {
|
||||
prim->add_vertex(min(max(sfav(x / level, tnlevel, reallevel), 0), lowblocksize - 1) * lowblocksize + lowblocksize - 1);
|
||||
prim->add_vertex(vcounter - lowblocksize);
|
||||
prim->add_vertex(vcounter);
|
||||
prim->close_primitive();
|
||||
}
|
||||
if (f_part((x / level)/float(pow(2.0, int(_levels[mx][my + 1]-reallevel)))) == 0.5) {
|
||||
prim->add_vertex(min(max(sfav(x / level + 1, _levels[mx][my + 1], reallevel), 0), lowblocksize - 1) * lowblocksize + lowblocksize - 1);
|
||||
prim->add_vertex(min(max(sfav(x / level - 1, _levels[mx][my + 1], reallevel), 0), lowblocksize - 1) * lowblocksize + lowblocksize - 1);
|
||||
if (f_part((x / level) / float(pow(2.0, int(tnlevel - reallevel)))) == 0.5) {
|
||||
prim->add_vertex(min(max(sfav(x / level + 1, tnlevel, reallevel), 0), lowblocksize - 1) * lowblocksize + lowblocksize - 1);
|
||||
prim->add_vertex(min(max(sfav(x / level - 1, tnlevel, reallevel), 0), lowblocksize - 1) * lowblocksize + lowblocksize - 1);
|
||||
prim->add_vertex(vcounter);
|
||||
prim->close_primitive();
|
||||
}
|
||||
@ -245,7 +248,9 @@ generate_block(unsigned short mx,
|
||||
geom->add_primitive(prim);
|
||||
geom->set_bounds_type(BoundingVolume::BT_box);
|
||||
|
||||
PT(GeomNode) node = new GeomNode("gmm" + int_to_str(mx) + "x" + int_to_str(my));
|
||||
ostringstream sname;
|
||||
sname << "gmm" << mx << "x" << my;
|
||||
PT(GeomNode) node = new GeomNode(sname.str());
|
||||
node->add_geom(geom);
|
||||
node->set_bounds_type(BoundingVolume::BT_box);
|
||||
_old_levels.at(mx).at(my) = reallevel;
|
||||
@ -381,7 +386,7 @@ generate() {
|
||||
_root_flattened = false;
|
||||
for (unsigned int mx = 0; mx < (_xsize - 1) / _block_size; mx++) {
|
||||
_old_levels[mx].resize(int((_ysize - 1) / _block_size));
|
||||
pvector<NodePath> tvector; //create temporary row
|
||||
pvector<NodePath> tvector; // Create temporary row
|
||||
for (unsigned int my = 0; my < (_ysize - 1) / _block_size; my++) {
|
||||
if (_bruteforce) {
|
||||
tvector.push_back(_root.attach_new_node(generate_block(mx, my, 0)));
|
||||
@ -390,7 +395,7 @@ generate() {
|
||||
}
|
||||
tvector[my].set_pos((mx + 0.5) * _block_size, (my + 0.5) * _block_size, 0);
|
||||
}
|
||||
_blocks.push_back(tvector); //push the new row of NodePaths into the 2d vect
|
||||
_blocks.push_back(tvector); // Push the new row of NodePaths into the 2d vect
|
||||
tvector.clear();
|
||||
}
|
||||
auto_flatten();
|
||||
@ -600,3 +605,77 @@ update_block(unsigned short mx, unsigned short my,
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeoMipTerrain::set_heightfield
|
||||
// Access: Published
|
||||
// Description: Loads the specified heightmap image file into
|
||||
// the heightfield. Returns true if succeeded, or
|
||||
// false if an error has occured.
|
||||
// If the heightmap is not a power of two plus one,
|
||||
// it is scaled up using a gaussian filter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeoMipTerrain::
|
||||
set_heightfield(const Filename &filename, PNMFileType *ftype) {
|
||||
// First, we need to load the header to determine the size and format.
|
||||
PNMImageHeader imgheader;
|
||||
if (imgheader.read_header(filename, ftype)) {
|
||||
// Copy over the header to the heightfield image.
|
||||
_heightfield.copy_header_from(imgheader);
|
||||
|
||||
if(!is_power_of_two(imgheader.get_x_size() - 1) || !is_power_of_two(imgheader.get_y_size() - 1)) {
|
||||
// Calculate the nearest power-of-two-plus-one size.
|
||||
unsigned int reqx, reqy;
|
||||
reqx = max(3, (int) pow(2.0, ceil(log((double) max(2, imgheader.get_x_size() - 1)) / log(2.0))) + 1);
|
||||
reqy = max(3, (int) pow(2.0, ceil(log((double) max(2, imgheader.get_y_size() - 1)) / log(2.0))) + 1);
|
||||
|
||||
// If it's not a valid size, tell PNMImage to resize it.
|
||||
if (reqx != imgheader.get_x_size() || reqy != imgheader.get_y_size()) {
|
||||
grutil_cat.warning() << "Rescaling heightfield image " << filename << " to "
|
||||
<< reqx << " by " << reqy << " pixels\n";
|
||||
_heightfield.set_read_size(reqx, reqy);
|
||||
}
|
||||
}
|
||||
|
||||
// Read the real image now
|
||||
if (!_heightfield.read(filename, ftype)) {
|
||||
_heightfield.clear_read_size();
|
||||
grutil_cat.error() << "Failed to read heightfield image " << filename << "!\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
_is_dirty = true;
|
||||
_xsize = _heightfield.get_x_size();
|
||||
_ysize = _heightfield.get_y_size();
|
||||
return true;
|
||||
} else {
|
||||
grutil_cat.error() << "Failed to load heightfield image " << filename << "!\n";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeoMipTerrain::get_neighbor_level
|
||||
// Access: Private
|
||||
// Description: Helper function for generate().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
unsigned short GeoMipTerrain::
|
||||
get_neighbor_level(unsigned short mx, unsigned short my, short dmx, short dmy) {
|
||||
// If we're across the terrain border, check if we want stitching.
|
||||
// If not, return the same level as this one - it won't have to make junctions.
|
||||
if (mx + dmx < 0 || mx + dmx >= (_xsize - 1) / _block_size ||
|
||||
my + dmy < 0 || my + dmy >= (_ysize - 1) / _block_size) {
|
||||
return (_stitching) ? _max_level : min(max(_min_level, _levels[mx][my]), _max_level);
|
||||
}
|
||||
// If we're rendering bruteforce, the level must be the same as this one.
|
||||
if (_bruteforce) {
|
||||
return min(max(_min_level, _levels[mx][my]), _max_level);
|
||||
}
|
||||
// Only if the level is higher than the current.
|
||||
// Otherwise, the junctions will be made for the other chunk.
|
||||
if (_levels[mx + dmx][my + dmy] > _levels[mx][my]) {
|
||||
return min(max(_min_level, _levels[mx + dmx][my + dmy]), _max_level);
|
||||
} else {
|
||||
return min(max(_min_level, _levels[mx][my]), _max_level);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
// Filename: geoMipTerrain.h
|
||||
// Created by: pro-rsoft (29jun07)
|
||||
// Last updated by: pro-rsoft (25sep08)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@ -44,8 +43,7 @@ PUBLISHED:
|
||||
INLINE ~GeoMipTerrain();
|
||||
|
||||
INLINE PNMImage &heightfield();
|
||||
INLINE bool set_heightfield(const Filename &filename,
|
||||
PNMFileType *type = NULL);
|
||||
bool set_heightfield(const Filename &filename, PNMFileType *type = NULL);
|
||||
INLINE bool set_heightfield(const PNMImage &image);
|
||||
INLINE bool set_heightfield(const string &path);
|
||||
INLINE PNMImage &color_map();
|
||||
@ -104,6 +102,8 @@ PUBLISHED:
|
||||
INLINE const NodePath get_block_node_path(unsigned short mx,
|
||||
unsigned short my);
|
||||
INLINE LVecBase2f get_block_from_pos(double x, double y);
|
||||
INLINE void set_border_stitching(bool stitching);
|
||||
INLINE bool get_border_stitching();
|
||||
|
||||
PNMImage make_slope_image();
|
||||
void generate();
|
||||
@ -118,8 +118,6 @@ private:
|
||||
void auto_flatten();
|
||||
bool root_flattened();
|
||||
|
||||
INLINE std::string int_to_str(int i);
|
||||
INLINE int str_to_int(std::string str);
|
||||
INLINE bool is_power_of_two(unsigned int i);
|
||||
INLINE float f_part(float i);
|
||||
INLINE double f_part(double i);
|
||||
@ -127,6 +125,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);
|
||||
unsigned short get_neighbor_level(unsigned short mx, unsigned short my, short dmx, short dmy);
|
||||
|
||||
NodePath _root;
|
||||
int _auto_flatten;
|
||||
@ -147,6 +146,7 @@ private:
|
||||
NodePath _focal_point;
|
||||
bool _focal_is_temporary;
|
||||
unsigned short _min_level;
|
||||
bool _stitching;
|
||||
pvector<pvector<NodePath> > _blocks;
|
||||
pvector<pvector<unsigned short> > _levels;
|
||||
pvector<pvector<unsigned short> > _old_levels;
|
||||
|
Loading…
x
Reference in New Issue
Block a user