/** @file Terrain.h @brief 地形封装类
 *	Copyright (c) 2007,第九城市游戏研发中心
 *	All rights reserved.
 *
 *	当前版本:
 *	作    者:Zhaixufeng
 *	完成日期:2007-09-26
*
 *	取代版本:
 *	作    者:
 *	完成日期:
 
*/ #ifndef TERRAIN_H #define TERRAIN_H #include "NiBoxBV.h" #include #include "Vegetation.h" #include "TerrainMaterial.h" // 在编辑器中使用游戏中不使用的类 #ifndef CODE_INGAME #include "EditableBaseObj.h" #include "NPCManager.h" #include "NPCCreatorManager.h" #include "AreaManager.h" #include "QuadTree.h" #include #include "NiPoint3.h" //#include "utility.h" class CObjectsManager; class CLightsManager; #endif #define EDIT_UNIT 1 #define MAX_CHUNK 16 #define GRIDINCHUNK 64 #define INVALID_CHUNK -1 #define INVALID_GRID -1 #define COLLISION_DATA_OFFSET 0.5f //#define BLEND_TEX_SIZE 2048 //#define BLEND_TEXEL_SIZE 0.25 // 0.00048828125f //1/2048 #define SHADOWMAP_SIZE_CHUNK 128 // 每 chunk shadow texture 尺寸 //class CTerrainMaterial; /** @brief 地形封装类 * 它也是Chunk的管理实体类 */ class MAIN_ENTRY CTerrain { friend class CObjectsManager; friend class CTerrainModifier; typedef pair NO_PAIR; public: /// 获得这个Terrain的地图号 DWORD GetCurMapNo() const {return m_MapNO;} /// 设置地图号 void SetMapNo(DWORD dwNumber) {m_MapNO = dwNumber;} enum EntityType {OBJECT, LIGHT, NPCCreator, REGION}; /// 构造 CTerrain(void); /// 析构 virtual ~CTerrain(void); /// 地表属性的枚举 enum eTerrainProperty { TP_EMPTY = 0, TP_BLOCK = 1, }; /** @brief grid定义 * * 这是地形编辑的最小单位,记录物理阻挡信息 */ typedef struct stGrid { /// 顶点索引 int iPointIndx[4]; /// 地表属性 0 - 空白 1 - 不可进入 int iTerrainProperty; /// 构造 stGrid(): iTerrainProperty(0){} }*LPGrid; /** @brief Chunk定义 * * 这是分区(块)的逻辑和渲染单位,它保存可放置的物件集,活动对象例外 */ typedef struct stChunk { /// 材质 CTerrainMaterial *pChunkMtl; /// 最小位置, 最大位置 NiPoint2 vPosMin, vPosMax; /////////////////////////以下为几何实体定义////////////////////////////////////////// /// 几何实体定义 struct stGeomData { /// 三角形条带 NiTriShapePtr pTriShape; /// normal线 NiLinesPtr pLine; /// 全局顶点索引,非Index Buffer DWORD *pGlobalVertIndx; stGeomData() : pGlobalVertIndx( 0 ) {} /// 析构 ~stGeomData() { SAFE_DELETE_ARRAY(pGlobalVertIndx); pTriShape = NULL; } }; /// 几何渲染数据 stGeomData geomData; /// 构造 stChunk() : pChunkMtl(0) { } /// 析构 ~stChunk() { //ClearAllObjects(); //ClearAllVegetation(); SAFE_DELETE( pChunkMtl ); } }*LPChunk; public: /** *
功能说明: 创建地形 *
可访问性: *
注 释: * @param 无 * @return 无 */ bool Create( int iChunkX, int iChunkY, const char *pszBaseTex, DWORD dwNumber = 0); /// 创建混和纹理 bool CreateBlendTexture( bool bNeedInit = true ); /** *
功能说明: *
可访问性: *
注 释: * @param pszFile[in] 高度图文件名 * @param pszBaseTex[in] 基本纹理贴图文件名 * @return 无 */ bool CreateFromHeightmap( const char* pszFile, const char *pszBaseTex ); /// 重新分配每个chunk顶点索引,取消优化 void ReorderVertexIndex(); /// 销毁 void Destroy(); /** *
功能说明:更新 *
可访问性: *
注 释: * @param dTime[in] 总时间 * @param fElapsedTime[in] 从上一帧的消逝时间 * @return 无 */ void Update( double dTime, float fElapsedTime ); /// 内部更新 void _Update( double dTime, float fElapsedTime ); /// 渲染 void Render( NiCamera *pCamera, NiCullingProcess *pCuller, NiVisibleArray *pVisible ); /// 设置渲染可见集 void BuilderVisibleSet( NiCamera *pCamera, NiVisibleArray *pVisible ); /// 设置活动相机 void SetActiveCamera( NiCamera* pCamera ){m_spCamera = pCamera;} /// 获取活动相机 NiCamera* GetActiveCamera() { return m_spCamera; } /// 获取地形块根节点 NiNode* GetTerrainRootNode() { return m_spTerrainRoot; } /// 获得指定位置的Chunk索引, 边际交接部分依最小chunk索引处理 int GetChunkIndex( const NiPoint3& vPos ); // 获得指定点在指定位置的索引 [6/23/2009 hemeng] int GetIndexInChunk(int iChunkID,const NiPoint3& kPoint); /// 获得指定位置的Chunk索引, 边际交接部分全部处理 void GetChunkIndex( const NiPoint3& vPos, set& chunkset ); /// 获得指定位置的Grid索引 int GetGridIndex( const NiPoint3& vPos ); /// 获得指定位置的Grid索引 void GetGridPosInServer( const NiPoint3& vPos, int& iPosX, int& iPosY); /** *
功能说明:获取与指定chunk相距一定距离的chunks. *
可访问性: *
注 释: * @param iChunk[in] chunk索引 * @param iOffset[in] 距离 * @param chunkset[in,out] 返回chunk索引集 * @return 无 */ void GetChunkArray( int iChunk, WORD usOffset, set& chunkset ); /// 获取 X 方向 chunk 数 int GetChunkNumX(); /// 获取 Y 方向 chunk 数 int GetChunkNumY(); /// 获取 Chunk 数组 stChunk* GetChunks(); /** *
功能说明:获取与指定grid相距一定距离的grid, 距离单位同样为grid *
可访问性: *
注 释: * @param iGrid[in] grid索引 * @param iOffset[in] 距离 * @param gridset[in,out] 返回grid索引集 * @return 无 */ void GetGridArray( int iGrid, WORD usOffset, set& gridset ); /** *
功能说明:查找矩形范围覆盖的所有网格点,包括交点 *
可访问性: *
注 释:一般用于鼠标拖拉的范围显示, 地表贴花等 * @param rect[in] 输入的鼠标范围 * @param vPointArray[in,out] 返回的点集,二维数组 * @return 无 */ void GetPointsFromRectangle( const NiRect& rect, vector< vector >& vPointArray ); void GetPointsFromRectangle( float fLB_x, float fLB_y, float fRT_x, float fRT_y, vector< vector >& vPointArray ); /// 获取高度值(精确) float GetHeight( const NiPoint2& vPos ); /// 获取高度值(粗糙) float GetRawHeight( const NiPoint2& vPos ); /// 获取第 y 行 x 列 顶点坐标 inline const NiPoint3& GetVertex(int x, int y); /// 获取第 iIndex 顶点坐标 inline const NiPoint3& GetVertex(int iIndex); /// 获取地形所有顶点 const NiPoint3* GetVertices() {return m_pVertices;} /// 获取第 y 行 x 列 顶点的 z 值(高度) inline float GetVertexHeight(int x, int y); /// 获取第 y 行 x 列 顶点的 alpha inline float GetVertexAlpha(int x, int y); /// 获取第 y 行 x 列 顶点的 R inline float GetVertexR(int x, int y); /// 获取第 y 行 x 列 顶点的 G inline float GetVertexG(int x, int y); /// 获取地形尺寸 NiPoint2 GetTotalSize(); /// 获取线段所包含的所有顶点,返回顶点的数目 int GetVerticesInLine(int iPosX1, int iPosY1, int iPoxX2, int iPosY2, vector& verticesList, vector& verticesNewHeight); /// 制造斜坡 int MakeIncline(int iPosX1, int iPosY1, int iPoxX2, int iPosY2, float fRadius, vector& verticesList, vector& verticesNewHeight); // 设置雾效参数 void SetFog(bool bEnable, NiColor& kColor, float fDepth); ////////////////////////////////文件功能//////////////////////////////////////////// public: /// 从文件导入地形 bool ImportFromFile( const char* pszFile ); /// 从流导入地形 bool ImportFromStream(NiBinaryStream * pBinStream, std::vector chunkTextures); //////////////////////////////////////////////////////////////////////////////////////// /// 创建灯光-Debug使用 void CreatePointLight_Debug(); void ExportTextTexture(); // 将地形旋转180度.因为美术刷地形时候和原画不符,为符合原画做的补救函数.用过作废 //bool RotateTerrain(); /************************************************ * 这里是只在编辑器中使用,游戏中不使用的函数 *************************************************/ #ifndef CODE_INGAME public: // 更新地表水波 [10/22/2009 hemeng] void UpdateWaterCausticsTex( float fAccumTime,NiSourceTexturePtr pTex); // 地表水波相关 [10/22/2009 hemeng] void SetWaterScene( bool bWaterScene ); void SetImageFrameCount( float fImageFrameCount ); void SetWaterSceneConfig(float fSize, float fXOffset, float fYOffset, float fFactor); CLightsManager *GetLightsManager() { return m_pLightsMgr; } //从Xml中加载NPC信息,并且生成Pal文件 static int CreateNpcCreatorPal(); //加载NPC生成器信息 static int LoadNpcCreator(); //设定GSA文件的编码格式 static int SetGsaEncodingCode(const char* szXmlFileName); //////////////////////////物件管理通信函数////////////////////////////////////////////////// void AddEntity(NiEntityInterface* pkEntityInterface, EntityType kType); void UpdateEntity(NiEntityInterface* pkEntityInterface, NiFixedString &pkPropertyName, EntityType kType); void RemoveEntity(NiEntityInterface* pkEntityInterface, EntityType kType); void RemoveAllEntity(); void InitEntity(NiEntityInterface* pkEntityInterface, EntityType kType); ////////////////////////////////文件功能//////////////////////////////////////////// /// 从文件加载,加载项目文件中的地形 bool LoadFromFile( const char *pszFile ); /// 保存到文件, *.trr bool SaveToFile( const char *pszFile ); /// 从 xml 中加载地形 (工程S/L中使用) bool LoadFromXML(const char* pszFile); /// 将地形保存到 xml 中 (工程S/L中使用) bool SaveToXML(const char* pszFile); /// 将地形优化后导出 保存为 *.etr 与 *.trr 相比多包含三角形连接信息 bool ExportToFile( const char* pszFile ); /// 地形保存到Nif文件 bool SaveTerrainToNif(const char *pszPath); // add [5/31/2009 hemeng] // 检查chunk是否全部为隐藏地形 bool IsHideChunk(int iChunkID); /// 导出地形数据提供服务器使用, *.map bool ExportTerrainToServer( const char *pszFile,const char* pszMapID ); /// 导出地图配置文件到 xml // modified [5/18/2009 hemeng] // 取消部分节点,以便导出xml为dll bool ExportTerrainInfo( const char *pszFile, TiXmlElement* pElmtWalkableObject, /*TiXmlElement* pElmtEntityInfo, TiXmlElement* pElmtBGMusic, */TiXmlElement* pElmtGlobalSetting, const char* pszMapID); /** *
功能说明:读取地形文件*.map文件头 *
可访问性:服务器使用 *
注 释: * @param pszFile[in] 文件名 * @param iTotalX[in] X向Size, 单位米 * @param iTotalY[in] Y向Size, 单位米 * @param iGridX[in] X向网格数目 * @param iGridY[in] Y向网格数目 * @return 无 */ bool ReadTerrainFile( const char *pszFile, int& iTotalX, int& iTotalY, int& iGridX, int& iGridY ); /// 读取地形文件网格数据 bool ReadDataFromTerrainFile( const char *pszFile, int *pBlockInfo ); /// 导出NPC生成器 bool ExportNPCCreator(); /// 将地形所有 chunk 的混合纹理导出 bExportPropTexture - 是否导出地表属性纹理 bool ExportBlendTexture(const char* szDirectory, bool bExportPropTexture = true); /// 保存Blend纹理,调试用 bool SaveBlendTexture( const char *pszFile ); ////////////////////////////////其他功能//////////////////////////////////////////// /// 设置Cursor半径, 目前在库中完成, 以提高效率 void SetCursorRadius( float fRadius ); /// 设置Cursor位置, 目前在库中完成, 以提高效率 void SetCursorPosition( const NiPoint3& vPoint ); /// 设置Cursor纹理, 目前在库中完成, 以提高效率 void SetCursorTexture( const char * pTexFile ); /// 设置碰撞显示纹理, 目前在库中完成, 以提高显示效率 void SetCollisionTexture( ); /// 设置是否显示碰撞数据 void SetShowCollisonData( bool bShow ); // add [6/11/2009 hemeng] //// 设置是否显示隐藏地形 void SetShowHiddenTerrain( bool bShow); // 渲染NPC生成范围框 函数作废 //int CreateNPCRange(const NiPoint3& vPos, WORD usOffset, const NiFixedString& strNPCCreateName); ///获取NPC生成范围框所覆盖的点 int GetCreateNPCRangeArray( const NiPoint3& vPos, WORD usOffset, int* pVerts); int GetCreateNPCRangeArrayM1(const NiPoint3& vPos, WORD usOffsetX, WORD usOffsetY, int* pVerts);//M1阶段范围框支持矩形 CObjectsManager *GetObjectsManager() { return m_pObjectsMgr; } /// 清除所有碰撞块 void ClearAllCollisionBlock(); /// 根据地形计算碰撞块 // 修改为可设置碰撞或显示碰撞 [1/29/2010 hemeng] void SlopeToCollisionBlock(int iBoundDegree, bool bRenderOnly = false); /// 设置最近被改变的 chunk id void SetLastChangedChunk(int iChunkIndex) {m_iLastChangedChunk = iChunkIndex;} int GetLastChangedChunk() {return m_iLastChangedChunk;} /// 设置/获取顶点颜色 void SetVertexColor(int iIdx, const NiColorA& kColor) {m_pVertexClr[iIdx] = kColor;} NiColorA GetVertexColor(int iIdx) {return m_pVertexClr[iIdx];} /// 获取所有 grid const stGrid* GetGrids() {return m_pGrids;} /// 重新创建所有 chunk 数据 void RebuildAllChunkData(); /// 获取所有顶点法线 NiPoint3* GetNormals(); /// 设置地形简单渲染 void SetSimpleRender(bool bSimple); bool GetSimpleRender() {return m_bSimpleRender;} /// 检查 chunk 空纹理层 bool CheckEmptyTextureLayer(); //更新by 和萌 //获得顶点颜色指针 NiColorA* GetVertexColor() { return m_pVertexClr;} /// 获取所有遮挡视线的点(高度太高) int GetOverTopVertexByHeight(float fHeight); int GetOverTopVertexByAngle(float fVisualAngle, float uiDistance); /// 区域工具的操作 unsigned int AddRegion(NiEntityInterface* pkEntityInterface, unsigned short usAreaType); void AddRegionPoint(NiEntityInterface* pkEntityInterface, unsigned int niAreaID); /// 导出地形信息给任务编辑器。包括地形俯视草图和地形尺寸 void ExportTerrainInfoToMissionEditor(const char* pszPath, vector& aObjList); //导出、导入地形grid属性 add by 和萌 void ExportGridProPerty( const char *pszFile ); void ImportGridProPerty( const char *pszFile ); bool ExportGridProPertyTexture( const char *pszFile ); // add [5/25/2009 hemeng] // 计算grid属性百分比 int GetGridPropertyPercent(int iGridProperty); // 获取三角形区域内的所有 Grid 中心点坐标 void GetGridCentersInTriangle(NiPoint3 kP0, NiPoint3 kP1, NiPoint3 kP2, vector &vertList); friend class CTerrainChangeVertexCommand; friend class CTerrainChangeVertexColorCommand; #endif // end #ifdef CODE_INGAME private: /// 活动相机 NiCameraPtr m_spCamera; /// 地形节点的根 NiNodePtr m_spTerrainRoot; /// NPC生成范围框的根 //NiNodePtr m_spPhyxRoot; /// Grid数组, 记录物理阻挡信息 stGrid *m_pGrids; /// 可渲染地形根节点 set< NiGeometry* > m_RenderableChunkset; /// 可渲染植被集 VegetationSet m_RenderableVegset; /// Vertex Buffer,被所有Chunk共享 NiPoint3 *m_pVertices; //NiPoint3 *m_pCollisionVertices; /// 行顶点数目 int m_iVertexX, m_iVertexY; /// 顶点法线 NiPoint3 *m_pNormals; /// UV0 NiPoint2 *m_pTexset0; /// UV1 NiPoint2 *m_pTexset1; /// 顶点颜色 NiColorA *m_pVertexClr; /// Blend纹理 NiSourceTexturePtr m_spBlendTexture; /// Chunk数组 stChunk *m_pChunks; /// 长、宽Chunk数目 int m_iChunkNumX, m_iChunkNumY; /// 长, 宽 int m_iTotalX, m_iTotalY; //地图号管理 static vector m_NOList; //地图号 DWORD m_MapNO; protected: /** *
功能说明:为Chunk分配渲染数据 *
可访问性:保护 *
注 释: * @param iIndexX[in] Chunk行索引 * @param iIndexY[in] Chunk列索引 * @return */ bool _BuildChunkData(int iIndexX, int iIndexY, bool bBuildGeometryData = true, bool bBuildMaterialData = true); /// for Debug bool _BuildChunkNormalLine( int iIndexX, int iIndexY ); /// 添加第iChunkIndex个附近某个范围内的Chunks及可渲染物件到可渲染列表 //void _AddRenderableItemsChunks( int iChunkIndx, int iOffset, bool bEditableObjIncluded = false ); ///// 添加第iChunkIndex个附近1个范围内的植被到可渲染列表 //void _AddRenderableVegetations( int iChunkIndx, int iOffset ); ///// 从四叉树添加可渲染几何体到渲染列表 //void _AddRendrablObjectFromQuadTree(); /************************************************** * 这里是只在编辑器中使用,游戏中不使用的成员变量 ***************************************************/ #ifndef CODE_INGAME protected: /// 可渲染物件集 EditableObjectSet m_RenderableObjset; /// 物件管理器 CObjectsManager *m_pObjectsMgr; /// 灯光管理器 CLightsManager *m_pLightsMgr; int m_iLastChangedChunk; // 最近被改变的 chunk id bool m_bSimpleRender; // 是否简单渲染 // 地表水波相关 [10/22/2009 hemeng] bool m_bWaterScene; float m_fImageFrameCount; float m_fPreTime; float m_fWaterCaustics_Size; float m_fWaterCaustics_XOffset; float m_fWaterCaustics_YOffset; float m_fWaterCausticsFactor; public: //NPC信息 static CNPCManager m_NpcManager; //NPC生成器信息 static CNPCCreatorManager m_NpcCreatorManager; CAreaManager *m_pAreaMgr; /// 四叉树组织 //CQuadTree *m_pQuadTree; //存放场景中过高的点 map> m_mapOverTopVertexs; private: #endif }; #pragma make_public(CTerrain) #include "Terrain.inl" #endif