Panda3D

heightfieldTesselator.h

00001 // Filename: heightfieldTesselator.h
00002 // Created by:  jyelon (17jul06)
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 #ifndef HEIGHTFIELDTESSELATOR_H
00016 #define HEIGHTFIELDTESSELATOR_H
00017 
00018 #include "pandabase.h"
00019 
00020 #include "luse.h"
00021 #include "pandaNode.h"
00022 #include "pointerTo.h"
00023 #include "namable.h"
00024 #include "pnmImage.h"
00025 #include "geom.h"
00026 #include "geomTristrips.h"
00027 #include "geomTriangles.h"
00028 #include "geomVertexWriter.h"
00029 #include "geomVertexFormat.h"
00030 #include "nodePath.h"
00031 
00032 ////////////////////////////////////////////////////////////////////
00033 //       Class : HeightfieldTesselator
00034 // Description : Converts a height field in the form of a greyscale
00035 //               image into a scene consisting of a number of GeomNodes.
00036 //
00037 //               The tesselation uses an LOD algorithm.  You
00038 //               supply a "focal point" (X,Y) which tells the
00039 //               tesselator where the bulk of the detail should
00040 //               be concentrated.  The intent is that as the player
00041 //               walks around the terrain, you should occasionally
00042 //               move the focal point to wherever the player is.
00043 //               You should not move the focal point every frame:
00044 //               tesselation is not that fast.  Also, changing the
00045 //               focal point may cause popping, so it is best to
00046 //               minimize the number of changes.  There are a number
00047 //               of parameters that you can use to control tesselation,
00048 //               such as a target polygon count, and a visibility
00049 //               radius.
00050 //
00051 //               The heightfield needs to be a multiple of 128 pixels
00052 //               in each dimension.  It does not need to be square,
00053 //               and it does not need to be a power of two.  For
00054 //               example, a 384 x 640 heightfield is fine.
00055 //               Be aware that tesselation time is proportional to
00056 //               heightfield area, so if you plan to use a size larger
00057 //               than about 512x512, it may be desirable to benchmark.
00058 //
00059 //               Altering parameters, such as the poly count, the
00060 //               view radius, or the focal point, does not alter any
00061 //               GeomNodes already generated.  Parameter changes only
00062 //               affect subsequently-generated GeomNodes.  It is
00063 //               possible to cache many different tesselations of the
00064 //               same terrain.
00065 //               
00066 ////////////////////////////////////////////////////////////////////
00067 
00068 class EXPCL_PANDA_GRUTIL HeightfieldTesselator : public Namable {
00069 PUBLISHED:
00070   INLINE HeightfieldTesselator(const string &name);
00071   INLINE ~HeightfieldTesselator();
00072 
00073   INLINE PNMImage &heightfield();
00074   INLINE bool set_heightfield(const Filename &filename, PNMFileType *type = NULL);
00075   INLINE void set_poly_count(int n);
00076   INLINE void set_visibility_radius(int r);
00077   INLINE void set_focal_point(int x, int y);
00078   INLINE void set_horizontal_scale(double h);
00079   INLINE void set_vertical_scale(double v);
00080   INLINE void set_max_triangles(int n);
00081 
00082   double get_elevation(double x, double y);
00083   
00084   NodePath generate();
00085 
00086 private:
00087 
00088   // These are initialized during the first 'generate'
00089   int  _radii[16];
00090   bool _radii_calculated;
00091 
00092   // These are only valid during the generate process.
00093   int *_triangle_totals;
00094   int *_vertex_index;
00095   int *_dirty_vertices;
00096   
00097   // These are only valid when a geom is open.
00098   int _next_index;
00099   int _last_vertex_a;
00100   int _last_vertex_b;
00101   PT(GeomVertexData) _vdata;
00102   GeomVertexWriter *_vertex_writer;
00103   GeomVertexWriter *_normal_writer;
00104   PT(GeomTriangles) _triangles;
00105 
00106   INLINE bool subdivide(int scale, int x, int y);
00107   void calculate_radii(int scale);
00108   void generate_square(NodePath root, int scale, int x, int y, bool forceclose);
00109   int  count_triangles(int scale, int x, int y);
00110   int  get_vertex(int x, int y);
00111   void add_quad_to_strip(int v1, int v2, int v3, int v4);
00112   void add_quad(int v1, int v2, int v3, int v4);
00113   void fix_heightfield(int size);
00114   void open_geom();
00115   void close_geom(NodePath root);
00116   
00117   PNMImage _heightfield;
00118   int _poly_count;
00119   int _visibility_radius;
00120   int _focal_x;
00121   int _focal_y;
00122   double _horizontal_scale;
00123   double _vertical_scale;
00124   int _max_triangles;
00125 };
00126 
00127 #include "heightfieldTesselator.I"
00128 
00129 #endif
00130 
 All Classes Functions Variables Enumerations