15 #include "config_grutil.h"
22 INLINE GeoMipTerrain::
23 GeoMipTerrain(
const string &name) {
25 _root_flattened =
false;
34 _use_near_far =
false;
35 _has_color_map =
false;
37 _auto_flatten = AFM_off;
39 _focal_is_temporary = true;
91 if (bf ==
true && _bruteforce ==
false) {
119 _auto_flatten = mode;
133 INLINE
void GeoMipTerrain::
134 set_focal_point(
double x,
double y) {
135 if (!_focal_is_temporary) {
139 _focal_point.
set_pos(_root, x, y, 0);
140 _focal_is_temporary =
true;
142 INLINE
void GeoMipTerrain::
143 set_focal_point(
const LPoint2d &fp) {
144 set_focal_point(fp.get_x(), fp.get_y());
146 INLINE
void GeoMipTerrain::
147 set_focal_point(
const LPoint2f &fp) {
148 set_focal_point(
double(fp.get_x()),
double(fp.get_y()));
150 INLINE
void GeoMipTerrain::
151 set_focal_point(
const LPoint3d &fp) {
152 set_focal_point(fp.get_x(), fp.get_y());
154 INLINE
void GeoMipTerrain::
155 set_focal_point(
const LPoint3f &fp) {
156 set_focal_point(
double(fp.get_x()),
double(fp.get_y()));
158 INLINE
void GeoMipTerrain::
160 if (_focal_is_temporary) {
164 _focal_is_temporary =
false;
205 _min_level = minlevel;
251 if (is_power_of_two(newbs)) {
254 if (is_power_of_two(newbs - 1)) {
255 _block_size = newbs - 1;
257 if (is_power_of_two(newbs + 1)) {
258 _block_size = newbs + 1;
260 _block_size = (
unsigned short) pow(2.0,
261 floor(log((
double) newbs) / log(2.0) + 0.5));
265 _max_level = (
unsigned short) (log((
double) _block_size) / log(2.0));
297 grutil_cat.debug() <<
"Using deprecated method set_factor, use set_near and set_far instead!\n";
298 _use_near_far =
false;
309 _use_near_far =
true;
323 _use_near_far =
true;
336 _use_near_far =
true;
370 return _auto_flatten;
390 return _blocks[mx][my];
411 if (x > _xsize - 1) x = _xsize - 1;
412 if (y > _ysize - 1) y = _ysize - 1;
413 x = floor(x / _block_size);
414 y = floor(y / _block_size);
422 INLINE
unsigned short GeoMipTerrain::
423 lod_decide(
unsigned short mx,
unsigned short my) {
426 cx = (cx * _block_size + _block_size / 2) * _root.get_sx();
427 cy = (cy * _block_size + _block_size / 2) * _root.get_sy();
430 d = sqrt(pow(_focal_point.get_x(_root) - cx, 2) +
431 pow(_focal_point.get_y(_root) - cy, 2));
434 }
else if (d > _far) {
437 return (
unsigned short)((d - _near) / (_far - _near) * _max_level * (1.0 - (_min_level / _max_level)) + _min_level);
441 d = sqrt(pow(_focal_point.get_x(_root) - cx, 2) +
442 pow(_focal_point.get_y(_root) - cy, 2)) / _factor;
446 return short(floor(d));
464 <<
"Heightfield image is specified to have sRGB color space!\n"
465 "Panda applies gamma correction, which will probably cause "
466 "it to produce incorrect results.\n";
470 if (is_power_of_two(image.
get_x_size() - 1) &&
472 _heightfield = image;
479 <<
"Specified image does not have a power-of-two-plus-one size!\n";
495 if (_color_map.
read(filename, ftype)) {
497 _has_color_map =
true;
507 _has_color_map =
true;
513 tex->
store(_color_map);
530 return _has_color_map;
540 if (_has_color_map) {
542 _has_color_map =
false;
560 if (stitching && !_stitching) {
563 _stitching = stitching;
584 INLINE
double GeoMipTerrain::
585 get_pixel_value(
int x,
int y) {
586 x = max(min(x,
int(_xsize-1)),0);
587 y = max(min(y,
int(_ysize-1)),0);
591 return double(_heightfield.
get_red(x, y))
592 +
double(_heightfield.
get_green(x, y)) / 256.0
593 +
double(_heightfield.
get_blue(x, y)) / 65536.0;
596 INLINE
double GeoMipTerrain::
597 get_pixel_value(
unsigned short mx,
unsigned short my,
int x,
int y) {
598 nassertr_always(mx < (_xsize - 1) / _block_size,
false);
599 nassertr_always(my < (_ysize - 1) / _block_size,
false);
600 return get_pixel_value(mx * _block_size + x, (_ysize - 1) -
601 (my * _block_size + y));
616 get_normal(
unsigned short mx,
unsigned short my,
int x,
int y) {
617 nassertr_always(mx < (_xsize - 1) / _block_size,
false);
618 nassertr_always(my < (_ysize - 1) / _block_size,
false);
619 return get_normal(mx * _block_size + x, (_ysize - 1) -
620 (my * _block_size + y));
629 INLINE
bool GeoMipTerrain::
630 is_power_of_two(
unsigned int i) {
631 return !((i - 1) & i);
640 INLINE
float GeoMipTerrain::
644 INLINE
double GeoMipTerrain::
655 INLINE
int GeoMipTerrain::
656 sfav(
int n,
int powlevel,
int mypowlevel) {
658 t /= pow(2.0, powlevel - mypowlevel);
659 t = double(
int(t > 0.0 ? t + 0.5 : t - 0.5));
660 t *= pow(2.0, powlevel - mypowlevel);
A basic node of the scene graph or data graph.
bool is_dirty()
Returns a bool indicating whether the terrain is marked 'dirty', that means the terrain has to be reg...
void set_factor(PN_stdfloat factor)
DEPRECATED method.
The name of this class derives from the fact that we originally implemented it as a layer on top of t...
GeoMipTerrain, meaning Panda3D GeoMipMapping, can convert a heightfield image into a 3D terrain...
float get_red(int x, int y) const
Returns the red component color at the indicated pixel.
float get_blue(int x, int y) const
Returns the blue component color at the indicated pixel.
float get_bright(int x, int y) const
Returns the linear brightness of the given xel, as a linearized float in the range 0...
NodePath get_root() const
Returns the root of the terrain.
bool read(const Filename &filename, PNMFileType *type=NULL, bool report_unknown_type=true)
Reads the indicated image filename.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
bool set_color_map(const Filename &filename, PNMFileType *type=NULL)
Loads the specified image as color map.
This is the base class of a family of classes that represent particular image file types that PNMImag...
const NodePath get_block_node_path(unsigned short mx, unsigned short my)
Returns the NodePath of the specified block.
PNMImage & heightfield()
Returns a reference to the heightfield (a PNMImage) contained inside GeoMipTerrain.
unsigned short get_min_level()
Gets the minimum level of detail at which blocks may be generated by generate() or update()...
double get_far()
Returns the far LOD distance in the terrain coordinate space.
void set_bruteforce(bool bf)
Sets a boolean specifying whether the terrain will be rendered bruteforce.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
This is a two-component point in space.
void set_pos(PN_stdfloat x, PN_stdfloat y, PN_stdfloat z)
Sets the translation component of the transform, leaving rotation and scale untouched.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
PNMImage & color_map()
Returns a reference to the color map (a PNMImage) contained inside GeoMipTerrain. ...
unsigned short get_block_size()
Gets the block size.
double get_near()
Returns the near LOD distance in the terrain coordinate space.
void set_near_far(double input_near, double input_far)
Sets the near and far LOD distances in one call.
float get_green(int x, int y) const
Returns the green component color at the indicated pixel.
bool has_color_map() const
Returns whether a color map has been set.
static NodePath fail()
Creates a NodePath with the ET_fail error type set.
The name of a file, such as a texture file or an Egg file.
bool get_bruteforce()
Returns a boolean whether the terrain is rendered bruteforce or not.
void clear_color_map()
Clears the color map.
unsigned short get_max_level()
Returns the highest level possible for this block size.
This is the base class for all two-component vectors and points.
LVector3 get_normal(int x, int y)
Fetches the terrain normal at (x, y), where the input coordinate is specified in pixels.
bool get_border_stitching()
Returns the current stitching setting.
void set_border_stitching(bool stitching)
If this value is true, the LOD level at the borders of the terrain will be 0.
int get_flatten_mode()
Returns the automatic-flatten mode (e.g., off, flatten_light, flatten_medium, or flatten_strong) ...
bool store(PNMImage &pnmimage) const
Saves the texture to the indicated PNMImage, but does not write it to disk.
bool set_heightfield(const Filename &filename, PNMFileType *type=NULL)
Loads the specified heightmap image file into the heightfield.
ColorSpace get_color_space() const
Returns the color space in which the image is encoded.
void set_near(double input_near)
Sets the near LOD distance, at which the terrain will be rendered at highest quality.
void set_auto_flatten(int mode)
The terrain can be automatically flattened (using flatten_light, flatten_medium, or flatten_strong) a...
void clear()
Frees all memory allocated for the image, and clears all its parameters (size, color, type, etc).
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
void remove_node(Thread *current_thread=Thread::get_current_thread())
Disconnects the referenced node from the scene graph.
NodePath get_focal_point() const
Returns the focal point, as a NodePath.
void set_block_size(unsigned short newbs)
Sets the block size.
void set_far(double input_far)
Sets the far LOD distance, at which the terrain will be rendered at lowest quality.
void copy_from(const PNMImage ©)
Makes this image become a copy of the other image.
This is a two-component point in space.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
LVecBase2 get_block_from_pos(double x, double y)
Gets the coordinates of the block at the specified position.
void set_min_level(unsigned short minlevel)
Sets the minimum level of detail at which blocks may be generated by generate() or update()...