119 lines
3.8 KiB
C++
119 lines
3.8 KiB
C++
/**
|
|
* PANDA 3D SOFTWARE
|
|
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
*
|
|
* All use of this software is subject to the terms of the revised BSD
|
|
* license. You should have received a copy of this license along
|
|
* with this source code in a file named "LICENSE."
|
|
*
|
|
* @file heightfieldTesselator.h
|
|
* @author jyelon
|
|
* @date 2006-07-17
|
|
*/
|
|
|
|
#ifndef HEIGHTFIELDTESSELATOR_H
|
|
#define HEIGHTFIELDTESSELATOR_H
|
|
|
|
#include "pandabase.h"
|
|
|
|
#include "luse.h"
|
|
#include "pandaNode.h"
|
|
#include "pointerTo.h"
|
|
#include "namable.h"
|
|
#include "pnmImage.h"
|
|
#include "geom.h"
|
|
#include "geomTristrips.h"
|
|
#include "geomTriangles.h"
|
|
#include "geomVertexWriter.h"
|
|
#include "geomVertexFormat.h"
|
|
#include "nodePath.h"
|
|
|
|
/**
|
|
* Converts a height field in the form of a greyscale image into a scene
|
|
* consisting of a number of GeomNodes.
|
|
*
|
|
* The tesselation uses an LOD algorithm. You supply a "focal point" (X,Y)
|
|
* which tells the tesselator where the bulk of the detail should be
|
|
* concentrated. The intent is that as the player walks around the terrain,
|
|
* you should occasionally move the focal point to wherever the player is.
|
|
* You should not move the focal point every frame: tesselation is not that
|
|
* fast. Also, changing the focal point may cause popping, so it is best to
|
|
* minimize the number of changes. There are a number of parameters that you
|
|
* can use to control tesselation, such as a target polygon count, and a
|
|
* visibility radius.
|
|
*
|
|
* The heightfield needs to be a multiple of 128 pixels in each dimension. It
|
|
* does not need to be square, and it does not need to be a power of two. For
|
|
* example, a 384 x 640 heightfield is fine. Be aware that tesselation time
|
|
* is proportional to heightfield area, so if you plan to use a size larger
|
|
* than about 512x512, it may be desirable to benchmark.
|
|
*
|
|
* Altering parameters, such as the poly count, the view radius, or the focal
|
|
* point, does not alter any GeomNodes already generated. Parameter changes
|
|
* only affect subsequently-generated GeomNodes. It is possible to cache many
|
|
* different tesselations of the same terrain.
|
|
*
|
|
*/
|
|
|
|
class EXPCL_PANDA_GRUTIL HeightfieldTesselator : public Namable {
|
|
PUBLISHED:
|
|
INLINE explicit HeightfieldTesselator(const std::string &name);
|
|
INLINE ~HeightfieldTesselator();
|
|
|
|
INLINE PNMImage &heightfield();
|
|
INLINE bool set_heightfield(const Filename &filename, PNMFileType *type = nullptr);
|
|
INLINE void set_poly_count(int n);
|
|
INLINE void set_visibility_radius(int r);
|
|
INLINE void set_focal_point(int x, int y);
|
|
INLINE void set_horizontal_scale(double h);
|
|
INLINE void set_vertical_scale(double v);
|
|
INLINE void set_max_triangles(int n);
|
|
|
|
double get_elevation(double x, double y);
|
|
|
|
NodePath generate();
|
|
|
|
private:
|
|
|
|
// These are initialized during the first 'generate'
|
|
int _radii[16];
|
|
bool _radii_calculated;
|
|
|
|
// These are only valid during the generate process.
|
|
int *_triangle_totals;
|
|
int *_vertex_index;
|
|
int *_dirty_vertices;
|
|
|
|
// These are only valid when a geom is open.
|
|
int _next_index;
|
|
int _last_vertex_a;
|
|
int _last_vertex_b;
|
|
PT(GeomVertexData) _vdata;
|
|
GeomVertexWriter *_vertex_writer;
|
|
GeomVertexWriter *_normal_writer;
|
|
PT(GeomTriangles) _triangles;
|
|
|
|
INLINE bool subdivide(int scale, int x, int y);
|
|
void calculate_radii(int scale);
|
|
void generate_square(NodePath root, int scale, int x, int y, bool forceclose);
|
|
int count_triangles(int scale, int x, int y);
|
|
int get_vertex(int x, int y);
|
|
void add_quad_to_strip(int v1, int v2, int v3, int v4);
|
|
void add_quad(int v1, int v2, int v3, int v4);
|
|
void fix_heightfield(int size);
|
|
void open_geom();
|
|
void close_geom(NodePath root);
|
|
|
|
PNMImage _heightfield;
|
|
int _poly_count;
|
|
int _visibility_radius;
|
|
int _focal_x;
|
|
int _focal_y;
|
|
double _horizontal_scale;
|
|
double _vertical_scale;
|
|
int _max_triangles;
|
|
};
|
|
|
|
#include "heightfieldTesselator.I"
|
|
|
|
#endif
|