open_toontown_panda3d/panda/src/grutil/heightfieldTesselator.h

131 lines
4.5 KiB
C++

// Filename: heightfieldTesselator.h
// Created by: jyelon (17jul06)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
#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"
////////////////////////////////////////////////////////////////////
// Class : HeightfieldTesselator
// Description : 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 HeightfieldTesselator(const string &name);
INLINE ~HeightfieldTesselator();
INLINE PNMImage &heightfield();
INLINE bool set_heightfield(const Filename &filename, PNMFileType *type = NULL);
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