/* ========================================================================== * ÀÛ ¼º ÀÚ : À̼ø±Ô * ÀÛ ¼º ÀÏ : 2006.12.04 * ³» ¿ë : ÁöÇü * ÁÖÀÇ»çÇ× : *===========================================================================*/ #pragma once #include "Shader.h" class cBox; class cSphere; class cTerrainNode; class cTerrainBranchNode; class cTerrainLeafNode; /// ÁöÇü »ó¼ö const unsigned int TERRAIN_DEFAULT_RESOLUTION = 512; const unsigned int TERRAIN_BUFF_CELL_COUNT = 128; const unsigned int TERRAIN_BUFF_LINE_COUNT = TERRAIN_BUFF_CELL_COUNT + 1; const unsigned int TERRAIN_BUFF_VERT_COUNT = TERRAIN_BUFF_LINE_COUNT * TERRAIN_BUFF_LINE_COUNT; const unsigned int TERRAIN_LEAF_CELL_COUNT = 8; const unsigned int TERRAIN_LEAF_LINE_COUNT = TERRAIN_LEAF_CELL_COUNT + 1; const unsigned int TERRAIN_LEAF_LINE_COUNT_X2 = TERRAIN_LEAF_LINE_COUNT * 2; const unsigned int TERRAIN_LEAF_VERT_COUNT = TERRAIN_LEAF_LINE_COUNT * TERRAIN_LEAF_LINE_COUNT; const unsigned int TERRAIN_RENDER_PRIME_COUNT = TERRAIN_LEAF_CELL_COUNT*TERRAIN_LEAF_CELL_COUNT * 2; /// ÁöÇü ÅØ½ºÃ³ »ó¼ö const unsigned int TERRAIN_TEXTURE_COUNT = 21; const unsigned int TERRAIN_TEXTURE_COUNT_VER2 = 16; /// ÁöÇü Lod enum eTerrainLod { TERRAIN_LOD_0 = 0, TERRAIN_LOD_1, TERRAIN_LOD_2, TERRAIN_LOD_COUNT }; /// ÁöÇü ÆÄÀÏ Çì´õ #pragma pack( push, 1 ) class cTerrainFileHeader { public: /// ½Äº° ÄÚµå char mCode[12]; /// ¹öÀü unsigned int mVersion; /// ±×¸®µå Å©±â (¼¿ ¼ö) unsigned int mCellCount; /// Á¤Á¡´ç ¹ÌÅÍ ¼ö float mMetersPerVertex; /// ¹ÌÅÍ´ç ´ÜÀ§ ¼ö unsigned int mUnitsPerMeter; /// ÅØ½ºÃ³ ¼ö unsigned int mNumTextures; }; #pragma pack( pop ) /// ÁöÇü ÅØ½ºÃ³ class cTerrainTexture { friend class cTerrain; friend class cTerrainLeafNode; public: cTerrainTexture( unsigned int index, LPDIRECT3DTEXTURE9 tex ); ~cTerrainTexture(); void Grab(); void Drop(); private: /// ÁöÇü¿¡ ÀÇÇØ ¼³Á¤µÈ ³»ºÎ À妽º unsigned int mIndexByTerrain; /// ÂüÁ¶ Ä«¿îÆ® unsigned int mRefCount; /// DX9 LPDIRECT3DTEXTURE9 mTexture; }; /// ÁöÇü ¹öÆÛ class cTerrainBuffer { friend class cTerrain; friend class cTerrainLeafNode; public: cTerrainBuffer(); ~cTerrainBuffer(); bool Init( cTerrain* terrain, unsigned int xi, unsigned int yi ); protected: void UpdatePosCoord( cTerrain* terrain, unsigned int xstart, unsigned int ystart, unsigned int count ); void UpdateColor( cTerrain* terrain, unsigned int xstart, unsigned int ystart, unsigned int count ); void UpdateAlpha( cTerrain* terrain, unsigned int xstart, unsigned int ystart, unsigned int count ); private: unsigned int mXIndex; unsigned int mYIndex; /// DX9 LPDIRECT3DVERTEXBUFFER9 mPosCoordBuffer; LPDIRECT3DVERTEXBUFFER9 mNormalBuffer; LPDIRECT3DVERTEXBUFFER9 mColorBuffer; LPDIRECT3DVERTEXBUFFER9 mAlphaBuffer; }; /// ÁöÇü class cTerrain { static cTerrain* mSingleton; friend class cTerrainLeafNode; friend class cTerrainTexture; friend class cTerrainBuffer; public: static const unsigned int MAX_NODES = 21845; public: cTerrain(); ~cTerrain(); /// Áö¿ò void Clear(); // /// ·Îµù bool LoadHeader( unsigned int& count, const cString& pathName ); int LoadNodes( unsigned int count ); /// ó¸® void Process(); /// ·»´õ¸µ void Render(); /// ±¸¿Í Ãæµ¹ÇÏ´Â ³ëµåµéÀ» ¼öÁý /// ¹Ù¿îµù ¹Ú½º·Î °Ë»çÇÑ´Ù. bool CollideSphere( tArray* pickedArray, const cSphere& sphere ); /// ´ÜÀ§ float GetUnitsPerVertex() const; float GetUnitsPerLeafNode() const; /// º¸ÀÌ´Â ¸®ÇÁ ³ëµå ¼ö unsigned int GetNumVisibleNodes() const; /// °æ°è »óÀÚ const cBox& GetBoundBox() const; /// ÇÑ º¯ÀÇ ±æÀÌ float GetSegmentLength() const; protected: /// ±×¸®µå Å©±â¸¦ °Ë»ç bool CheckCellCount( unsigned int cellCount ); // /// ÅØ½ºÃ³ bool LoadTexture( unsigned int index, const cString& pathName ); cTerrainTexture* GetTexture( unsigned int index ); void AddTexture( unsigned int index, cTerrainTexture* tex ); void RemoveTexture( unsigned int index ); /// ¹öÆÛ cTerrainBuffer* GetBuffer( unsigned int xi, unsigned int yi ); /// ¸®ÇÁ ³ëµå void SetLeafNode( unsigned int xi, unsigned int yi, cTerrainLeafNode* node ); cTerrainLeafNode* GetLeafNode( float x, float y ) const; /// ³ôÀ̰ª void SetHeight( unsigned int xi, unsigned int yi, float height ); bool GetHeight( float* height, unsigned int xi, unsigned int yi ); float GetHeightFast( unsigned int xi, unsigned int yi ) const; /// ¹ý¼±°ª void ComputeNormals( unsigned int xbegin, unsigned int ybegin, unsigned int xend, unsigned int yend ); const NiPoint3& GetNormalFast( unsigned int xi, unsigned int yi ) const; /// »ö»ó°ª void SetColor( unsigned int xi, unsigned int yi, const NiColor& color ); const NiColor& GetColorFast( unsigned int xi, unsigned int yi ) const; /// ¾ËÆÄ°ª void SetAlpha( unsigned int xi, unsigned int yi, const NiPoint3& alpha ); const NiPoint3& GetAlphaFast( unsigned int xi, unsigned int yi ) const; /// Àü¿ª±¤À» ¸®ÅÏ NiAmbientLight* GetAmbientLight() const; void CreateIndexedBuffer(); unsigned int CalcLOD( float sqrDist ); public: /// ´ÜÀÏü¸¦ ¸®ÅÏ static cTerrain* GetSingleton(); protected: /// ±×¸®µå Å©±â ( 512ÀÇ ¹è¼ö + 1 ) unsigned int mCellCount; unsigned int mLineCount; /// ´ÜÀ§ float mMetersPerVertex; unsigned int mUnitsPerMeter; float mUnitsPerVertex; float mUnitsPerLeafNode; /// ÇÑ º¯ÀÇ ±æÀÌ float mSegmentLength; /// ·çÆ® ³ëµå cTerrainBranchNode* mRootNode; /// ¸®ÇÁ ³ëµå ¹è¿­ typedef tArray cLeafNodeArray; cLeafNodeArray mNodeArray; /// °¡½Ã ¹è¿­ cLeafNodeArray mVisibleArray; /// ³ôÀÌ ¹è¿­ float* mHeights; /// ¹ý¼± ¹è¿­ NiPoint3* mNormals; /// »ö»ó ¹è¿­ NiColor* mColors; /// ¾ËÆÄ ¹è¿­ NiPoint3* mAlphas; /// Level of detail float mSquaredDistanceLod[TERRAIN_LOD_COUNT]; /// ÅØ½ºÃ³ ¹è¿­ cTerrainTexture* mTextures[TERRAIN_TEXTURE_COUNT]; /// ¼ÎÀÌ´õ cTerrainShader mShader; /// ¹öÆÛ cTerrainBuffer** mBuffer; /// DX9 LPDIRECT3DVERTEXDECLARATION9 mVertexDeclaration; ////////////////////////////////////////////////////////////////////////// /// LOD index buffer Ãß°¡ /// 8x8 LOD-0 enum { eCRACK_LEFT = 0, eCRACK_RIGHT, eCRACK_UP, eCRACK_DOWN, eCRACK_LEFTUP, eCRACK_LEFTDOWN, eCRACK_RIGHTUP, eCRACK_RIGHTDOWN, eCRACK_MAX, }; unsigned int mIndexCount8x8; LPDIRECT3DINDEXBUFFER9 mIndexBuffer8x8; /// 4x4 LOD-1 unsigned int mIndexCount4x4; LPDIRECT3DINDEXBUFFER9 mIndexBuffer4x4; unsigned int mCrackIndexCount4x4[eCRACK_MAX]; LPDIRECT3DINDEXBUFFER9 mCrackIndexBuffer4x4[eCRACK_MAX]; /// 2x2 LOD-2 unsigned int mIndexCount2x2; LPDIRECT3DINDEXBUFFER9 mIndexBuffer2x2; unsigned int mCrackIndexCount2x2[eCRACK_MAX]; LPDIRECT3DINDEXBUFFER9 mCrackIndexBuffer2x2[eCRACK_MAX]; ////////////////////////////////////////////////////////////////////////// /// ·Îµù cFileLoader mLoader; cTerrainNode** mLoadArray; unsigned int mLoadCount; unsigned int mLoadIndex; }; inline cTerrainTexture* cTerrain::GetTexture( unsigned int i ) { assert( i < TERRAIN_TEXTURE_COUNT && "index out of range" ); return mTextures[i]; } inline cTerrainBuffer* cTerrain::GetBuffer( unsigned int xi, unsigned int yi ) { return &(mBuffer[yi / TERRAIN_BUFF_CELL_COUNT][xi / TERRAIN_BUFF_CELL_COUNT]); } inline void cTerrain::SetHeight( unsigned int xi, unsigned int yi, float height ) { mHeights[yi * mLineCount + xi] = height; } inline float cTerrain::GetHeightFast( unsigned int xi, unsigned int yi ) const { return mHeights[yi * mLineCount + xi]; } inline const NiPoint3& cTerrain::GetNormalFast( unsigned int xi, unsigned int yi ) const { return mNormals[yi * mLineCount + xi]; } inline void cTerrain::SetAlpha( unsigned int xi, unsigned int yi, const NiPoint3& alpha ) { mAlphas[yi * mLineCount + xi] = alpha; } inline const NiPoint3& cTerrain::GetAlphaFast( unsigned int xi, unsigned int yi ) const { return mAlphas[yi * mLineCount + xi]; } inline void cTerrain::SetColor( unsigned int xi, unsigned int yi, const NiColor& color ) { mColors[yi * mLineCount + xi] = color; } inline const NiColor& cTerrain::GetColorFast( unsigned int xi, unsigned int yi ) const { return mColors[yi * mLineCount + xi]; } inline float cTerrain::GetUnitsPerVertex() const { return mUnitsPerVertex; } inline float cTerrain::GetUnitsPerLeafNode() const { return mUnitsPerLeafNode; } inline float cTerrain::GetSegmentLength() const { return mSegmentLength; } inline unsigned int cTerrain::GetNumVisibleNodes() const { return mVisibleArray.GetSize(); } inline cTerrain* cTerrain::GetSingleton() { return mSingleton; } #define TERRAIN cTerrain::GetSingleton()