summaryrefslogtreecommitdiff
path: root/indra/newview/llsurface.h
blob: 264080078c63b2b6b9bb6f7cfdb3999b0e033ca5 (plain)
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
/** 
 * @file llsurface.h
 * @brief Description of LLSurface class
 *
 * $LicenseInfo:firstyear=2000&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#ifndef LL_LLSURFACE_H
#define LL_LLSURFACE_H

//#include "vmath.h"
#include "v3math.h"
#include "v3dmath.h"
#include "v4math.h"
#include "m3math.h"
#include "m4math.h"
#include "llquaternion.h"

#include "v4coloru.h"
#include "v4color.h"

#include "llvowater.h"
#include "llpatchvertexarray.h"
#include "llviewertexture.h"

class LLTimer;
class LLUUID;
class LLAgent;

static const U8 NO_EDGE    = 0x00;
static const U8 EAST_EDGE  = 0x01;
static const U8 NORTH_EDGE = 0x02;
static const U8 WEST_EDGE  = 0x04;
static const U8 SOUTH_EDGE = 0x08;

static const S32 ONE_MORE_THAN_NEIGHBOR	= 1;
static const S32 EQUAL_TO_NEIGHBOR 		= 0;
static const S32 ONE_LESS_THAN_NEIGHBOR	= -1;

const S32 ABOVE_WATERLINE_ALPHA = 32;  // The alpha of water when the land elevation is above the waterline.

class LLViewerRegion;
class LLSurfacePatch;
class LLBitPack;
class LLGroupHeader;

class LLSurface 
{
public:
	LLSurface(U32 type, LLViewerRegion *regionp = NULL);
	virtual ~LLSurface();

	static void initClasses(); // Do class initialization for LLSurface and its child classes.

	void create(const S32 surface_grid_width,
				const S32 surface_patch_width,
				const LLVector3d &origin_global,
				const F32 width);	// Allocates and initializes surface

	void setRegion(LLViewerRegion *regionp);

	void setOriginGlobal(const LLVector3d &origin_global);

	void connectNeighbor(LLSurface *neighborp, U32 direction);
	void disconnectNeighbor(LLSurface *neighborp);
	void disconnectAllNeighbors();

	virtual void decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, bool b_large_patch);
	virtual void updatePatchVisibilities(LLAgent &agent);

	inline F32 getZ(const U32 k) const				{ return mSurfaceZ[k]; }
	inline F32 getZ(const S32 i, const S32 j) const	{ return mSurfaceZ[i + j*mGridsPerEdge]; }

	LLVector3 getOriginAgent() const;
	const LLVector3d &getOriginGlobal() const;
	F32 getMetersPerGrid() const;
	S32 getGridsPerEdge() const; 
	S32 getPatchesPerEdge() const;
	S32 getGridsPerPatchEdge() const;
	U32 getRenderStride(const U32 render_level) const;
	U32 getRenderLevel(const U32 render_stride) const;

	// Returns the height of the surface immediately above (or below) location,
	// or if location is not above surface returns zero.
	F32 resolveHeightRegion(const F32 x, const F32 y) const;
	F32 resolveHeightRegion(const LLVector3 &location) const
			{ return resolveHeightRegion( location.mV[VX], location.mV[VY] ); }
	F32 resolveHeightGlobal(const LLVector3d &position_global) const;
	LLVector3 resolveNormalGlobal(const LLVector3d& v) const;				//  Returns normal to surface

	LLSurfacePatch *resolvePatchRegion(const F32 x, const F32 y) const;
	LLSurfacePatch *resolvePatchRegion(const LLVector3 &position_region) const;
	LLSurfacePatch *resolvePatchGlobal(const LLVector3d &position_global) const;

	// Update methods (called during idle, normally)
    template<bool PBR>
	bool idleUpdate(F32 max_update_time);

	bool containsPosition(const LLVector3 &position);

	void moveZ(const S32 x, const S32 y, const F32 delta);	

	LLViewerRegion *getRegion() const				{ return mRegionp; }

	F32 getMinZ() const								{ return mMinZ; }
	F32 getMaxZ() const								{ return mMaxZ; }

	void setWaterHeight(F32 height);
	F32 getWaterHeight() const;

	LLViewerTexture *getSTexture();
	LLViewerTexture *getWaterTexture();
	bool hasZData() const							{ return mHasZData; }

	void dirtyAllPatches();	// Use this to dirty all patches when changing terrain parameters

	void dirtySurfacePatch(LLSurfacePatch *patchp);
	LLVOWater *getWaterObj()						{ return mWaterObjp; }

	static void setTextureSize(const S32 texture_size);

	friend class LLSurfacePatch;
	friend std::ostream& operator<<(std::ostream &s, const LLSurface &S);
	
	void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions );
	void getNeighboringRegionsStatus( std::vector<S32>& regions );
	
public:
	// Number of grid points on one side of a region, including +1 buffer for
	// north and east edge.
	S32 mGridsPerEdge;

	F32 mOOGridsPerEdge;			// Inverse of grids per edge

	S32 mPatchesPerEdge;			// Number of patches on one side of a region
	S32 mNumberOfPatches;			// Total number of patches


	// Each surface points at 8 neighbors (or NULL)
	// +---+---+---+
	// |NW | N | NE|
	// +---+---+---+
	// | W | 0 | E |
	// +---+---+---+
	// |SW | S | SE|
	// +---+---+---+
	LLSurface *mNeighbors[8]; // Adjacent patches

	U32 mType;				// Useful for identifying derived classes
	
	F32 mDetailTextureScale;	//  Number of times to repeat detail texture across this surface 

protected:
	void createSTexture();
	void createWaterTexture();
	void initTextures();
	void initWater();


	void createPatchData();		// Allocates memory for patches.
	void destroyPatchData();    // Deallocates memory for patches.

	bool generateWaterTexture(const F32 x, const F32 y,
						const F32 width, const F32 height);		// Generate texture from composition values.

	//F32 updateTexture(LLSurfacePatch *ppatch);
	
	LLSurfacePatch *getPatch(const S32 x, const S32 y) const;

protected:
	LLVector3d	mOriginGlobal;		// In absolute frame
	LLSurfacePatch *mPatchList;		// Array of all patches

	// Array of grid data, mGridsPerEdge * mGridsPerEdge
	F32 *mSurfaceZ;

	// Array of grid normals, mGridsPerEdge * mGridsPerEdge
	LLVector3 *mNorm;

	std::set<LLSurfacePatch *> mDirtyPatchList;


	// The textures should never be directly initialized - use the setter methods!
	LLPointer<LLViewerTexture> mSTexturep;		// Texture for surface
	LLPointer<LLViewerTexture> mWaterTexturep;	// Water texture

	LLPointer<LLVOWater>	mWaterObjp;

	// When we want multiple cameras we'll need one of each these for each camera
	S32 mVisiblePatchCount;

	U32			mGridsPerPatchEdge;			// Number of grid points on a side of a patch
	F32			mMetersPerGrid;				// Converts (i,j) indecies to distance
	F32			mMetersPerEdge;				// = mMetersPerGrid * (mGridsPerEdge-1)

	LLPatchVertexArray mPVArray;

	bool		mHasZData;				// We've received any patch data for this surface.
	F32			mMinZ;					// min z for this region (during the session)
	F32			mMaxZ;					// max z for this region (during the session)

	S32			mSurfacePatchUpdateCount;					// Number of frames since last update.

private:
	LLViewerRegion *mRegionp; // Patch whose coordinate system this surface is using.
	static S32	sTextureSize;				// Size of the surface texture
};

extern template bool LLSurface::idleUpdate</*PBR=*/false>(F32 max_update_time);
extern template bool LLSurface::idleUpdate</*PBR=*/true>(F32 max_update_time);



//        .   __.
//     Z /|\   /| Y                                 North
//        |   / 
//        |  /             |<----------------- mGridsPerSurfaceEdge --------------->|
//        | /              __________________________________________________________
//        |/______\ X     /_______________________________________________________  /
//                /      /      /      /      /      /      /      /M*M-2 /M*M-1 / /  
//                      /______/______/______/______/______/______/______/______/ /  
//                     /      /      /      /      /      /      /      /      / /  
//                    /______/______/______/______/______/______/______/______/ /  
//                   /      /      /      /      /      /      /      /      / /  
//                  /______/______/______/______/______/______/______/______/ /  
//      West       /      /      /      /      /      /      /      /      / /  
//                /______/______/______/______/______/______/______/______/ /     East
//               /...   /      /      /      /      /      /      /      / /  
//              /______/______/______/______/______/______/______/______/ /  
//       _.    / 2M   /      /      /      /      /      /      /      / /  
//       /|   /______/______/______/______/______/______/______/______/ /  
//      /    / M    / M+1  / M+2  / ...  /      /      /      / 2M-1 / /   
//     j    /______/______/______/______/______/______/______/______/ /   
//         / 0    / 1    / 2    / ...  /      /      /      / M-1  / /   
//        /______/______/______/______/______/______/______/______/_/   
//                                South             |<-L->|
//             i -->
//
// where M = mSurfPatchWidth
// and L = mPatchGridWidth
// 
// Notice that mGridsPerSurfaceEdge = a power of two + 1
// This provides a buffer on the east and north edges that will allow us to 
// fill the cracks between adjacent surfaces when rendering.
#endif