Panda3D
 All Classes Functions Variables Enumerations
geoMipTerrain.I
00001 // Filename: geoMipTerrain.I
00002 // Created by:  rdb (29Jun07)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "config_grutil.h"
00016 
00017 ////////////////////////////////////////////////////////////////////
00018 //     Function: GeoMipTerrain::Constructor
00019 //       Access: Published
00020 //  Description:
00021 ////////////////////////////////////////////////////////////////////
00022 INLINE GeoMipTerrain::
00023 GeoMipTerrain(const string &name) {
00024   _root = NodePath(name);
00025   _root_flattened = false;
00026   _xsize = 0;
00027   _ysize = 0;
00028   _block_size = 16;
00029   _max_level = 4; // Always log(_block_size) / log(2.0)
00030   _min_level = 0;
00031   _factor = 100.0;
00032   _near = 16.0;
00033   _far = 128.0;
00034   _use_near_far = false;
00035   _has_color_map = false;
00036   PT(PandaNode) tmpnode = new PandaNode("tmp_focal");
00037   _auto_flatten = AFM_off;
00038   _focal_point = NodePath(tmpnode);
00039   _focal_is_temporary = true;
00040   _is_dirty = true;
00041   _bruteforce = false;
00042   _stitching = false;
00043 }
00044 
00045 ////////////////////////////////////////////////////////////////////
00046 //     Function: GeoMipTerrain::Destructor
00047 //       Access: Published
00048 //  Description: This will not remove the terrain node itself.
00049 //               To have the terrain itself also deleted, please
00050 //               call remove_node() prior to destruction.
00051 ////////////////////////////////////////////////////////////////////
00052 INLINE GeoMipTerrain::
00053 ~GeoMipTerrain() {
00054 }
00055 
00056 ////////////////////////////////////////////////////////////////////
00057 //     Function: GeoMipTerrain::heightfield
00058 //       Access: Published
00059 //  Description: Returns a reference to the heightfield (a PNMImage)
00060 //               contained inside GeoMipTerrain.  You can use
00061 //               the reference to alter the heightfield.
00062 ////////////////////////////////////////////////////////////////////
00063 INLINE PNMImage &GeoMipTerrain::
00064 heightfield() {
00065   return _heightfield;
00066 }
00067 
00068 ////////////////////////////////////////////////////////////////////
00069 //     Function: GeoMipTerrain::color_map
00070 //       Access: Published
00071 //  Description: Returns a reference to the color map (a PNMImage)
00072 //               contained inside GeoMipTerrain.  You can use
00073 //               the reference to alter the color map.
00074 ////////////////////////////////////////////////////////////////////
00075 INLINE PNMImage &GeoMipTerrain::
00076 color_map() {
00077   return _color_map;
00078 }
00079 
00080 ////////////////////////////////////////////////////////////////////
00081 //     Function: GeoMipTerrain::set_bruteforce
00082 //       Access: Published
00083 //  Description: Sets a boolean specifying whether the terrain will
00084 //               be rendered bruteforce. If the terrain is rendered
00085 //               bruteforce, there will be no Level of Detail, and
00086 //               the update() call will only update the
00087 //               terrain if it is marked dirty.
00088 ////////////////////////////////////////////////////////////////////
00089 INLINE void GeoMipTerrain::
00090 set_bruteforce(bool bf) {
00091   if (bf == true && _bruteforce == false) {
00092     _is_dirty = true;
00093   }
00094   _bruteforce = bf;
00095 }
00096 
00097 ////////////////////////////////////////////////////////////////////
00098 //     Function: GeoMipTerrain::get_bruteforce
00099 //       Access: Published
00100 //  Description: Returns a boolean whether the terrain is rendered
00101 //               bruteforce or not. See set_bruteforce for more
00102 //               information.
00103 ////////////////////////////////////////////////////////////////////
00104 INLINE bool GeoMipTerrain::
00105 get_bruteforce() {
00106   return _bruteforce;
00107 }
00108 
00109 ////////////////////////////////////////////////////////////////////
00110 //     Function: GeoMipTerrain::set_auto_flatten
00111 //       Access: Private
00112 //  Description: The terrain can be automatically flattened (using
00113 //               flatten_light, flatten_medium, or flatten_strong)
00114 //               after each update.  This only affects future
00115 //               updates, it doesn't flatten the current terrain.
00116 ////////////////////////////////////////////////////////////////////
00117 INLINE void GeoMipTerrain::
00118 set_auto_flatten(int mode) {
00119   _auto_flatten = mode;
00120 }
00121 
00122 ////////////////////////////////////////////////////////////////////
00123 //     Function: GeoMipTerrain::set_focal_point
00124 //       Access: Published
00125 //  Description: Sets the focal point.  GeoMipTerrain generates
00126 //               high-resolution terrain around the focal point, and
00127 //               progressively lower and lower resolution terrain
00128 //               as you get farther away. If a point is supplied
00129 //               and not a NodePath, make sure it's relative to
00130 //               the terrain. Only the x and y coordinates of
00131 //               the focal point are taken in respect.
00132 ////////////////////////////////////////////////////////////////////
00133 INLINE void GeoMipTerrain::
00134 set_focal_point(double x, double y) {
00135   if (!_focal_is_temporary) {
00136     PT(PandaNode) tmpnode = new PandaNode("tmp_focal");
00137     _focal_point = NodePath(tmpnode);
00138   }
00139   _focal_point.set_pos(_root, x, y, 0);
00140   _focal_is_temporary = true;
00141 }
00142 INLINE void GeoMipTerrain::
00143 set_focal_point(const LPoint2d &fp) {
00144   set_focal_point(fp.get_x(), fp.get_y());
00145 }
00146 INLINE void GeoMipTerrain::
00147 set_focal_point(const LPoint2f &fp) {
00148   set_focal_point(double(fp.get_x()), double(fp.get_y()));
00149 }
00150 INLINE void GeoMipTerrain::
00151 set_focal_point(const LPoint3d &fp) {
00152   set_focal_point(fp.get_x(), fp.get_y());
00153 }
00154 INLINE void GeoMipTerrain::
00155 set_focal_point(const LPoint3f &fp) {
00156   set_focal_point(double(fp.get_x()), double(fp.get_y()));
00157 }
00158 INLINE void GeoMipTerrain::
00159 set_focal_point(NodePath fp) {
00160   if (_focal_is_temporary) {
00161     _focal_point.remove_node();
00162   }
00163   _focal_point = fp;
00164   _focal_is_temporary = false;
00165 }
00166 
00167 ////////////////////////////////////////////////////////////////////
00168 //     Function: GeoMipTerrain::get_focal_point
00169 //       Access: Published
00170 //  Description: Returns the focal point, as a NodePath.
00171 //               If you have set it to be just a point, it will
00172 //               return an empty node at the focal position.
00173 ////////////////////////////////////////////////////////////////////
00174 INLINE NodePath GeoMipTerrain::
00175 get_focal_point() const {
00176   return _focal_point;
00177 }
00178 
00179 ////////////////////////////////////////////////////////////////////
00180 //     Function: GeoMipTerrain::get_root
00181 //       Access: Published
00182 //  Description: Returns the root of the terrain.  This is a
00183 //               single PandaNode to which all the rest of the
00184 //               terrain is parented.  The generate and update
00185 //               operations replace the nodes which are parented
00186 //               to this root, but they don't replace this root
00187 //               itself.
00188 ////////////////////////////////////////////////////////////////////
00189 INLINE NodePath GeoMipTerrain::
00190 get_root() const {
00191   return _root;
00192 }
00193 
00194 ////////////////////////////////////////////////////////////////////
00195 //     Function: GeoMipTerrain::set_min_level
00196 //       Access: Published
00197 //  Description: Sets the minimum level of detail at which blocks
00198 //               may be generated by generate() or update().
00199 //               The default value is 0, which is the highest
00200 //               quality. This value is also taken in respect when
00201 //               generating the terrain bruteforce.
00202 ////////////////////////////////////////////////////////////////////
00203 INLINE void GeoMipTerrain::
00204 set_min_level(unsigned short minlevel) {
00205   _min_level = minlevel;
00206 }
00207 
00208 ////////////////////////////////////////////////////////////////////
00209 //     Function: GeoMipTerrain::get_min_level
00210 //       Access: Published
00211 //  Description: Gets the minimum level of detail at which blocks
00212 //               may be generated by generate() or update().
00213 //               The default value is 0, which is the highest
00214 //               quality.
00215 ////////////////////////////////////////////////////////////////////
00216 INLINE unsigned short GeoMipTerrain::
00217 get_min_level() {
00218   return _min_level;
00219 }
00220 
00221 ////////////////////////////////////////////////////////////////////
00222 //     Function: GeoMipTerrain::get_max_level
00223 //       Access: Published
00224 //  Description: Returns the highest level possible for this block
00225 //               size. When a block is at this level, it will be
00226 //               the worst quality possible.
00227 ////////////////////////////////////////////////////////////////////
00228 INLINE unsigned short GeoMipTerrain::
00229 get_max_level() {
00230   return _max_level;
00231 }
00232 
00233 ////////////////////////////////////////////////////////////////////
00234 //     Function: GeoMipTerrain::get_block_size
00235 //       Access: Published
00236 //  Description: Gets the block size.
00237 ////////////////////////////////////////////////////////////////////
00238 INLINE unsigned short GeoMipTerrain::
00239 get_block_size() {
00240   return _block_size;
00241 }
00242 
00243 ////////////////////////////////////////////////////////////////////
00244 //     Function: GeoMipTerrain::set_block_size
00245 //       Access: Published
00246 //  Description: Sets the block size. If it is not a power of two,
00247 //               the closest power of two is used.
00248 ////////////////////////////////////////////////////////////////////
00249 INLINE void GeoMipTerrain::
00250 set_block_size(unsigned short newbs) {
00251   if (is_power_of_two(newbs)) {
00252     _block_size = newbs;
00253   } else {
00254     if (is_power_of_two(newbs - 1)) {
00255       _block_size = newbs - 1;
00256     } else {
00257       if (is_power_of_two(newbs + 1)) {
00258         _block_size = newbs + 1;
00259       } else {
00260         _block_size = (unsigned short) pow(2.0,
00261                             floor(log((double) newbs) / log(2.0) + 0.5));
00262       }
00263     }
00264   }
00265   _max_level = (unsigned short) (log((double) _block_size) / log(2.0));
00266   _is_dirty = true;
00267 }
00268 
00269 ////////////////////////////////////////////////////////////////////
00270 //     Function: GeoMipTerrain::is_dirty
00271 //       Access: Published
00272 //  Description: Returns a bool indicating whether the terrain is
00273 //               marked 'dirty', that means the terrain has to be
00274 //               regenerated on the next update() call, because
00275 //               for instance the heightfield has changed.
00276 //               Once the terrain has been regenerated, the dirty
00277 //               flag automatically gets reset internally.
00278 ////////////////////////////////////////////////////////////////////
00279 INLINE bool GeoMipTerrain::
00280 is_dirty() {
00281   return _is_dirty;
00282 }
00283 
00284 ////////////////////////////////////////////////////////////////////
00285 //     Function: GeoMipTerrain::set_factor
00286 //       Access: Published
00287 //  Description: DEPRECATED method. Use set_near/far instead.
00288 //               Sets the quality factor at which blocks must be
00289 //               generated. The higher this level, the better
00290 //               quality the terrain will be, but more expensive
00291 //               to render. A value of 0 makes the terrain the
00292 //               lowest quality possible, depending on blocksize.
00293 //               The default value is 100.
00294 ////////////////////////////////////////////////////////////////////
00295 INLINE void GeoMipTerrain::
00296 set_factor(PN_stdfloat factor) {
00297   grutil_cat.debug() << "Using deprecated method set_factor, use set_near and set_far instead!\n";
00298   _use_near_far = false;
00299   _factor = factor;
00300 }
00301 
00302 ////////////////////////////////////////////////////////////////////
00303 //     Function: GeoMipTerrain::set_near_far
00304 //       Access: Published
00305 //  Description: Sets the near and far LOD distances in one call.
00306 ////////////////////////////////////////////////////////////////////
00307 INLINE void GeoMipTerrain::
00308 set_near_far(double input_near, double input_far) {
00309   _use_near_far = true;
00310   _near = input_near;
00311   _far = input_far;
00312 }
00313 
00314 ////////////////////////////////////////////////////////////////////
00315 //     Function: GeoMipTerrain::set_near
00316 //       Access: Published
00317 //  Description: Sets the near LOD distance, at which the terrain
00318 //               will be rendered at highest quality.
00319 //               This distance is in the terrain's coordinate space!
00320 ////////////////////////////////////////////////////////////////////
00321 INLINE void GeoMipTerrain::
00322 set_near(double input_near) {
00323   _use_near_far = true;
00324   _near = input_near;
00325 }
00326 
00327 ////////////////////////////////////////////////////////////////////
00328 //     Function: GeoMipTerrain::set_far
00329 //       Access: Published
00330 //  Description: Sets the far LOD distance, at which the terrain
00331 //               will be rendered at lowest quality.
00332 //               This distance is in the terrain's coordinate space!
00333 ////////////////////////////////////////////////////////////////////
00334 INLINE void GeoMipTerrain::
00335 set_far(double input_far) {
00336   _use_near_far = true;
00337   _far = input_far;
00338 }
00339 
00340 ////////////////////////////////////////////////////////////////////
00341 //     Function: GeoMipTerrain::get_far
00342 //       Access: Published
00343 //  Description: Returns the far LOD distance in the terrain coordinate
00344 //               space
00345 ////////////////////////////////////////////////////////////////////
00346 INLINE double GeoMipTerrain::
00347 get_far() {
00348   return _far;
00349 }
00350 
00351 ////////////////////////////////////////////////////////////////////
00352 //     Function: GeoMipTerrain::get_near
00353 //       Access: Published
00354 //  Description: Returns the near LOD distance in the terrain coordinate
00355 //               space
00356 ////////////////////////////////////////////////////////////////////
00357 INLINE double GeoMipTerrain::
00358 get_near() {
00359   return _near;
00360 }
00361 
00362 ////////////////////////////////////////////////////////////////////
00363 //     Function: GeoMipTerrain::get_flatten_mode
00364 //       Access: Published
00365 //  Description: Returns the automatic-flatten mode (e.g., off,
00366 //               flatten_light, flatten_medium, or flatten_strong)
00367 ////////////////////////////////////////////////////////////////////
00368 INLINE int GeoMipTerrain::
00369 get_flatten_mode() {
00370   return _auto_flatten;
00371 }
00372 
00373 ////////////////////////////////////////////////////////////////////
00374 //     Function: GeoMipTerrain::get_block_node_path
00375 //       Access: Published
00376 //  Description: Returns the NodePath of the specified block.
00377 //               If auto-flatten is enabled and the node is
00378 //               getting removed during the flattening process,
00379 //               it will still return a NodePath with the
00380 //               appropriate terrain chunk, but it will be in
00381 //               a temporary scenegraph.
00382 //               Please note that this returns a const object and
00383 //               you can not modify the node. Modify the heightfield
00384 //               instead.
00385 ////////////////////////////////////////////////////////////////////
00386 INLINE const NodePath GeoMipTerrain::
00387 get_block_node_path(unsigned short mx, unsigned short my) {
00388   return _blocks[mx][my];
00389 }
00390 ////////////////////////////////////////////////////////////////////
00391 //     Function: GeoMipTerrain::get_block_from_pos
00392 //       Access: Published
00393 //  Description: Gets the coordinates of the block at the specified
00394 //               position. This position must be relative to the
00395 //               terrain, not to render. Returns an array containing
00396 //               two values: the block x and the block y coords.
00397 //               If the positions are out of range, the closest
00398 //               block is taken.
00399 //               Note that the VecBase returned does not represent
00400 //               a vector, position, or rotation, but it contains
00401 //               the block index of the block which you can use
00402 //               in GeoMipTerrain::get_block_node_path.
00403 ////////////////////////////////////////////////////////////////////
00404 INLINE LVecBase2 GeoMipTerrain::
00405 get_block_from_pos(double x, double y) {
00406   if (x < 0) x = 0;
00407   if (y < 0) y = 0;
00408   if (x > _xsize - 1) x = _xsize - 1;
00409   if (y > _ysize - 1) y = _ysize - 1;
00410   x = floor(x / _block_size);
00411   y = floor(y / _block_size);
00412   return LVecBase2(x, y);
00413 }
00414 ////////////////////////////////////////////////////////////////////
00415 //     Function: GeoMipTerrain::lod_decide
00416 //       Access: Private
00417 //  Description: Calculates the level for the given mipmap.
00418 ////////////////////////////////////////////////////////////////////
00419 INLINE unsigned short GeoMipTerrain::
00420 lod_decide(unsigned short mx, unsigned short my) {
00421   PN_stdfloat cx = mx;
00422   PN_stdfloat cy = my;
00423   cx = (cx * _block_size + _block_size / 2) * _root.get_sx();
00424   cy = (cy * _block_size + _block_size / 2) * _root.get_sy();
00425   PN_stdfloat d;
00426   if (_use_near_far) {
00427     d = sqrt(pow(_focal_point.get_x(_root) - cx, 2) +
00428              pow(_focal_point.get_y(_root) - cy, 2));
00429     if (d < _near) {
00430       return 0;
00431     } else if (d > _far) {
00432       return _max_level;
00433     } else {
00434       return (unsigned short)((d - _near) / (_far - _near) * _max_level * (1.0 - (_min_level / _max_level)) + _min_level);
00435     }
00436   } else {
00437     if (_factor > 0.0) {
00438       d = sqrt(pow(_focal_point.get_x(_root) - cx, 2) +
00439                pow(_focal_point.get_y(_root) - cy, 2)) / _factor;
00440     } else {
00441       d = _max_level;
00442     }
00443     return short(floor(d));
00444   }
00445 }
00446 
00447 ////////////////////////////////////////////////////////////////////
00448 //     Function: GeoMipTerrain::set_heightfield
00449 //       Access: Published
00450 //  Description: Loads the specified heightmap image file into
00451 //               the heightfield. Returns true if succeeded, or
00452 //               false if an error has occured.
00453 //               If the heightmap is not a power of two plus one,
00454 //               it is scaled up using a gaussian filter.
00455 ////////////////////////////////////////////////////////////////////
00456 INLINE bool GeoMipTerrain::
00457 set_heightfield(const PNMImage &image) {
00458   // Before we apply anything, validate the size.
00459   if(is_power_of_two(image.get_x_size() - 1) && is_power_of_two(image.get_y_size() - 1)) {
00460     _heightfield = image;
00461     _is_dirty = true;
00462     _xsize = _heightfield.get_x_size();
00463     _ysize = _heightfield.get_y_size();
00464     return true;
00465   } else {
00466     grutil_cat.error() << "Specified image does not have a power-of-two-plus-one size!\n";
00467   }
00468   return false;
00469 }
00470 
00471 INLINE bool GeoMipTerrain::
00472 set_heightfield(const string &path) {
00473   return set_heightfield(Filename(path));
00474 }
00475 
00476 ////////////////////////////////////////////////////////////////////
00477 //     Function: GeoMipTerrain::set_color_map
00478 //       Access: Published
00479 //  Description: Loads the specified image as color map. The next
00480 //               time generate() is called, the terrain is painted
00481 //               with this color map using the vertex color column.
00482 //               Returns a boolean indicating whether the operation
00483 //               has succeeded.
00484 ////////////////////////////////////////////////////////////////////
00485 INLINE bool GeoMipTerrain::
00486 set_color_map(const Filename &filename, PNMFileType *ftype) {
00487   if (_color_map.read(filename, ftype)) {
00488     _is_dirty = true;
00489     _has_color_map = true;
00490     return true;
00491   }
00492   return false;
00493 }
00494 
00495 INLINE bool GeoMipTerrain::
00496 set_color_map(const PNMImage &image) {
00497   _color_map.copy_from(image);
00498   _is_dirty = true;
00499   _has_color_map = true;
00500   return true;
00501 }
00502 
00503 INLINE bool GeoMipTerrain::
00504 set_color_map(const Texture *tex) {
00505   tex->store(_color_map);
00506   _is_dirty = true;
00507   return true;
00508 }
00509 
00510 INLINE bool GeoMipTerrain::
00511 set_color_map(const string &path) {
00512   return set_color_map(Filename(path));
00513 }
00514 
00515 ////////////////////////////////////////////////////////////////////
00516 //     Function: GeoMipTerrain::has_color_map
00517 //       Access: Published
00518 //  Description: Returns whether a color map has been set.
00519 ////////////////////////////////////////////////////////////////////
00520 INLINE bool GeoMipTerrain::
00521 has_color_map() const {
00522   return _has_color_map;
00523 }
00524 
00525 ////////////////////////////////////////////////////////////////////
00526 //     Function: GeoMipTerrain::clear_color_map
00527 //       Access: Published
00528 //  Description: Clears the color map.
00529 ////////////////////////////////////////////////////////////////////
00530 INLINE void GeoMipTerrain::
00531 clear_color_map() {
00532   if (_has_color_map) {
00533     _color_map.clear();
00534     _has_color_map = false;
00535   }
00536 }
00537 
00538 ////////////////////////////////////////////////////////////////////
00539 //     Function: GeoMipTerrain::set_border_stitching
00540 //       Access: Published
00541 //  Description: If this value is true, the LOD level at the
00542 //               borders of the terrain will be 0. This is useful
00543 //               if you have multiple terrains attached and you
00544 //               want to stitch them together, to fix seams.
00545 //               This setting also has effect when bruteforce is
00546 //               enabled, although in that case you are probably
00547 //               better off with setting the minlevels to the same
00548 //               value.
00549 ////////////////////////////////////////////////////////////////////
00550 INLINE void GeoMipTerrain::
00551 set_border_stitching(bool stitching) {
00552   if (stitching && !_stitching) {
00553     _is_dirty = true;
00554   }
00555   _stitching = stitching;
00556 }
00557 
00558 ////////////////////////////////////////////////////////////////////
00559 //     Function: GeoMipTerrain::get_stitching
00560 //       Access: Published
00561 //  Description: Returns the current stitching setting. False by
00562 //               default, unless set_stitching has been set.
00563 ////////////////////////////////////////////////////////////////////
00564 INLINE bool GeoMipTerrain::
00565 get_border_stitching() {
00566   return _stitching;
00567 }
00568 
00569 ////////////////////////////////////////////////////////////////////
00570 //     Function: GeoMipTerrain::get_pixel_value
00571 //       Access: Private
00572 //  Description: Get the elevation at a certain pixel of the image.
00573 //               This function does NOT linearly interpolate.
00574 //               For that, use GeoMipTerrain::get_elevation() instead.
00575 ////////////////////////////////////////////////////////////////////
00576 INLINE double GeoMipTerrain::
00577 get_pixel_value(int x, int y) {
00578   x = max(min(x,int(_xsize-1)),0);
00579   y = max(min(y,int(_ysize-1)),0);
00580   if (_heightfield.is_grayscale()) {
00581     return double(_heightfield.get_bright(x, y));
00582   } else {
00583     return double(_heightfield.get_red(x, y))
00584          + double(_heightfield.get_green(x, y)) / 256.0
00585          + double(_heightfield.get_blue(x, y)) / 65536.0;
00586   }
00587 }
00588 INLINE double GeoMipTerrain::
00589 get_pixel_value(unsigned short mx, unsigned short my, int x, int y) {
00590   nassertr_always(mx < (_xsize - 1) / _block_size, false);
00591   nassertr_always(my < (_ysize - 1) / _block_size, false);
00592   return get_pixel_value(mx * _block_size + x, (_ysize - 1) -
00593                          (my * _block_size + y));
00594 }
00595 
00596 ////////////////////////////////////////////////////////////////////
00597 //     Function: GeoMipTerrain::get_normal
00598 //       Access: Published
00599 //  Description: Fetches the terrain normal at (x,y), where the input
00600 //               coordinate is specified in pixels. This ignores the
00601 //               current LOD level and instead provides an
00602 //               accurate number.
00603 //               Terrain scale is NOT taken into account! To get
00604 //               accurate normals, please divide it by the
00605 //               terrain scale and normalize it again!
00606 ////////////////////////////////////////////////////////////////////
00607 INLINE LVector3 GeoMipTerrain::
00608 get_normal(unsigned short mx, unsigned short my, int x, int y) {
00609   nassertr_always(mx < (_xsize - 1) / _block_size, false);
00610   nassertr_always(my < (_ysize - 1) / _block_size, false);
00611   return get_normal(mx * _block_size + x, (_ysize - 1) -
00612                     (my * _block_size + y));
00613 }
00614 
00615 ////////////////////////////////////////////////////////////////////
00616 //     Function: GeoMipTerrain::is_power_of_two
00617 //       Access: Private
00618 //  Description: Returns a bool whether the given int i is a
00619 //               power of two or not.
00620 ////////////////////////////////////////////////////////////////////
00621 INLINE bool GeoMipTerrain::
00622 is_power_of_two(unsigned int i) {
00623   return !((i - 1) & i);
00624 }
00625 
00626 ////////////////////////////////////////////////////////////////////
00627 //     Function: GeoMipTerrain::f_part
00628 //       Access: Private
00629 //  Description: Returns the part of the number right of the
00630 //               floating-point.
00631 ////////////////////////////////////////////////////////////////////
00632 INLINE float GeoMipTerrain::
00633 f_part(float i) {
00634   return i - floor(i);
00635 }
00636 INLINE double GeoMipTerrain::
00637 f_part(double i) {
00638   return i - floor(i);
00639 }
00640 
00641 ////////////////////////////////////////////////////////////////////
00642 //     Function: GeoMipTerrain::sfav
00643 //       Access: Private
00644 //  Description: Used to calculate vertex numbers. Only to
00645 //               be used internally.
00646 ////////////////////////////////////////////////////////////////////
00647 INLINE int GeoMipTerrain::
00648 sfav(int n, int powlevel, int mypowlevel) {
00649   double t = n - 1;
00650   t /= pow(2.0, powlevel - mypowlevel);
00651   t = double(int(t > 0.0 ? t + 0.5 : t - 0.5));
00652   t *= pow(2.0, powlevel - mypowlevel);
00653   return int(t);
00654 }
00655 
 All Classes Functions Variables Enumerations