1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
/*
* Modification History
*
* 2001-January-9 Jason Rohrer
* Created. Copied from LandscapePrimitiveGL, which this class will replace
*
* 2001-January-15 Jason Rohrer
* Fixed a bug in the constructor.
*
* 2001-January-17 Jason Rohrer
* Fliped how x and y in height map correspond to x and z in the terrain.
*
* 2001-January-19 Jason Rohrer
* Changed to support multi-texturing.
*
* 2001-January-30 Jason Rohrer
* Fixed a bug that occurs when the class defaults to no detail texture.
*
* 2001-March-11 Jason Rohrer
* Fixed a bug in the texture map anchor points.
*/
#ifndef LANDSCAPE_PRIMITIVE_3D_INCLUDED
#define LANDSCAPE_PRIMITIVE_3D_INCLUDED
#include "Primitive3D.h"
/**
* Primitive 3D lanscape object.
*
* Made from a height map. Mesh generated spans both x and z between -1 and
* 1, and can vary in height (y) from 0 to 1.
*
* @author Jason Rohrer
*/
class LandscapePrimitive3D : public Primitive3D {
public:
/**
* Constructs a LandscapePrimitive with a multi-layer texture.
*
* @param inWide width of mesh in number of vertices.
* Must be even and at least 2.
* @param inHigh height of mesh in number of vertices.
* @param inHeights array of heights for each vertex, each in
* [0,1]. Must be destroyed by caller.
* @param inTexture the texture to map onto the lanscape.
* Texture is anchored by its corners to the corners of the
* lanscape. inTexture is destroyed when primitive is destroyed.
* @param inDetailTexture the second layer in the multi-texture.
* The alpha channel of inDetailTexture will be used as
* the blending factor to mix the detail with the global texture.
* Set to NULL to use only a single layer.
* @param inDetailScale the scale factor of the detailed texture.
* Setting to 1.0 will anchor the detail at the corners of the
* mesh (just like inTexture). Setting to 0.25 will cause
* the detail texture to cycle 4 times across the surface of the
* mesh.
*/
LandscapePrimitive3D( int inWide, int inHigh, double *inHeights,
RGBAImage *inTexture, RGBAImage *inDetailTexture = NULL,
double inDetailScale = 1.0 );
};
inline LandscapePrimitive3D::LandscapePrimitive3D( int inWide,
int inHigh, double *inHeights,
RGBAImage *inTexture, RGBAImage *inDetailTexture,
double inDetailScale ) {
// first, set Primitve3D members
mHigh = inHigh;
mWide = inWide;
mNumVertices = mHigh * mWide;
if( inDetailTexture == NULL ) {
mNumTextures = 1;
mTexture = new RGBAImage*[1];
mTexture[0] = inTexture;
mAnchorX = new double*[1];
mAnchorY = new double*[1];
mAnchorX[0] = new double[mNumVertices];
mAnchorY[0] = new double[mNumVertices];
}
else {
mNumTextures = 2;
mTexture = new RGBAImage*[2];
mTexture[0] = inTexture;
mTexture[1] = inDetailTexture;
mAnchorX = new double*[2];
mAnchorY = new double*[2];
mAnchorX[0] = new double[mNumVertices];
mAnchorY[0] = new double[mNumVertices];
mAnchorX[1] = new double[mNumVertices];
mAnchorY[1] = new double[mNumVertices];
}
mVertices = new Vector3D*[mNumVertices];
// anchor at texture corners, and step linearly through texture
double anchorYStep = 1.0 / ( mHigh - 1 );
double anchorXStep = 1.0 / ( mWide - 1 );
double detailAnchorYStep = 1.0 / ( ( mHigh - 1 ) * inDetailScale );
double detailAnchorXStep = 1.0 / ( ( mWide - 1 ) * inDetailScale );
for( int y=0; y<mHigh; y++ ) {
for( int x=0; x<mWide; x++ ) {
int index = y * mWide + x;
mAnchorX[0][index] = anchorXStep * x;
mAnchorY[0][index] = anchorYStep * y;
if( mNumTextures == 2 ) {
mAnchorX[1][index] = detailAnchorXStep * x;
mAnchorY[1][index] = detailAnchorYStep * y;
}
// add height for this x and y position
mVertices[index] = new Vector3D( 2 * mAnchorX[0][index] - 1,
inHeights[index], -2 * mAnchorY[0][index] + 1 );
// note that y coordinates in the 2d height map must be
// inverted before they can be used as z coordinates in the mesh
}
}
generateNormals();
}
#endif
|