/** @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