/** * @file llsurface.h * @brief Description of LLSurface class * * $LicenseInfo:firstyear=2000&license=viewergpl$ * * Copyright (c) 2000-2009, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab * to you under the terms of the GNU General Public License, version 2.0 * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, * and agree to abide by those obligations. * * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. * $/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 "llviewerimage.h" class LLTimer; class LLUUID; class LLAgent; class LLStat; 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) 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; LLViewerImage *getSTexture(); LLViewerImage *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); 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 static F32 sTextureUpdateTime; static S32 sTexelsUpdated; static LLStat sTexelsUpdatedPerSecStat; 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 mDirtyPatchList; // The textures should never be directly initialized - use the setter methods! LLPointer mSTexturep; // Texture for surface LLPointer mWaterTexturep; // Water texture LLPointer 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 }; // . __. // 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