/** @file TerrainModifier.h @brief 地形修改器,目前实现几何编辑和材质编辑
 *	Copyright (c) 2007,第九城市游戏研发中心
 *	All rights reserved.
 *
 *	当前版本:
 *	作    者:zhaixufeng
 *	完成日期:2007-12-03
*
 *	取代版本:
 *	作    者:
 *	完成日期:
 
*/ #ifndef CODE_INGAME #ifndef TERRAIN_MODIFIER_H #define TERRAIN_MODIFIER_H class CTerrain; class CTerrainChangeVertexCommand; // 获取按键的状态 #define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) class MAIN_ENTRY CTerrainModifier { public: /// 构造 CTerrainModifier(); /// 析构 virtual ~CTerrainModifier(void); /// Paint通道,用于刷纹理 enum EPaintChannel { PAINT_R = 2, PAINT_G, PAINT_B , PAINT_MAX }; /// 地形操作类型 enum ETerrainOperation { TO_FLAT, // 刷平地形到指定高度 TO_UPPER, // 抬高地形 TO_FALL, // 降低地形 TO_SMOOTH, // 平滑地形 }; public: /// 初始化 static bool Initialize(); /// 终结 static void UnInitialize(); /** *
功能说明:调整地形高度 *
可访问性: *
注 释:由当前鼠标位置及影响半径,调整所影响范围的三角形高度,并发通知到影响到的Chunk,改变几何体顶点值 * @param vPos[in] 鼠标Click位置 * @param fHeight[in] 调整到的高度 * @param fRadius0[in] 影响半径(小) * @param fRadius1[in] 影响半径(大), fRadius0和fRadius1之前自行插值过渡 * @param command[out] 所有被改变的顶点生成的 TerrainChangeVertexCommand * @return 无 */ static void AdjustHeight( CTerrain *pTerrain, const NiPoint3& vPos, float fHeight, float fRadius0, float fRadius1, bool bAddTo = false, CTerrainChangeVertexCommand* pCommand = NULL ); /// 设定基础材质 static bool SetBaseTexture( CTerrain *pTerrain, const char *pszBaseText ); /** *
功能说明:对地表进行绘制 *
可访问性: *
注 释:由当前鼠标位置及画刷的强度、影响范围自动为地表添加纹理,Chunk纹理数超过四层自动返回 * @param pszTex[in] 纹理文件名 * @param vPos[in] 鼠标Click位置 * @param fHeight[in] 调整到的高度 * @param fRadius0[in] 影响半径(小) * @param fRadius1[in] 影响半径(大), fRadius0和fRadius1之前自行插值过渡 * @return 文件不存在,影响到的chunk纹理层数超过4,都会返回false. 否则为true */ static bool PaintTerrain( CTerrain *pTerrain, const char *pszTex, const NiPoint3& vPos, float fAlpha, float fRadius0, float fRadius1, bool bAddTo = false ); // 081008 add by 和萌 /// 通过纹理设置grid地表属性 static void SetRegionPropertyByMaterial( CTerrain* pTerrain ); /// 设置碰撞数据 /** *
功能说明:设置碰撞数据 *
可访问性: *
注 释:设置所选取grid的碰撞标志 * @param pTerrain[in] 地表对象 * @param vPos[in] 鼠标Click位置 * @param fRadius[in] 鼠标点选范围 * @param iProperty[in] 标志, 地表属性 * @return 无 */ //static void SetCollisionData( CTerrain *pTerrain, const NiPoint3& vPos, float fRadius, bool bSignal ); static void SetTerrainSurfaceProperty( CTerrain *pTerrain, const NiPoint3& vPos, float fRadius, bool bDelete, int iProperty = -1); /// 设置当前需要显示和改变的 property static void SetCurrentTerrainProperty( CTerrain *pTerrain, int iProperty); /// 平滑 static void Smooth( CTerrain *pTerrain, float fRadius, float fPower ); /// 计算所有的法线 static void CalculateAllNormals( CTerrain *pTerrain ); /// 线程函数 static DWORD ThreadProc( LPVOID lpParam ); /// 是否需要线程处理 static bool NeedThreadDisposal() { return m_bNeedThread; } /// 设置线程处理标志 static void SetThreadDisposal( bool bSignal ); /// 处理实体 static void Disposal(); /// 计算Terrain第index个顶点的法线 static const NiPoint3 CalculateNormal( CTerrain *pTerrain, int index ); static void CalculateTBN( CTerrain*, int index, NiPoint3& vTangent, NiPoint3& vBinormal, NiPoint3& vNormal ); /// 通知第index个Chunk数据发生变化 static void NotifyChunkVertexChanged( CTerrain *pTerrain, int index ); /// 设置当前绘制状态,绘制纹理还是顶点 static void SetPaintState(bool bPaintTexture, bool bPaintVertexColor,bool bPatinWaterScene); /// 设置当前使用的顶点颜色 static void SetInUseVertexColor(const NiColorA& kColor); /// 设置笔刷纹理 static void SetBrushTexture(const char *pszBaseText); /// 设置对地形的操作类型 static void SetTerrainOp(ETerrainOperation op); /// 设置地形纹理绘制是否为叠加效果 static void SetPaintAddTo(bool bAddTo); /// 将纹理写到地形的 blend texture 的 alpha 通道中 static bool ApplyShadowTexture(CTerrain* pTerrain, NiTexturePtr pkTexture); /// 将纹理写到地形特定 chunk 的 blend texture 的 alpha 通道 static bool ApplyShadowTexture(CTerrain* pTerrain, NiTexturePtr pkTexture, int iChunkID); /// 将纹理的颜色值根据 UV 写入到地形顶点色中 static bool ApplyVertexColorTexture(CTerrain* pTerrain, NiSourceTexturePtr pkTexture, float fLum = 100.0f); /// 将纹理颜色值根据 UV 写入地形特定 chunk 顶点色中 static bool ApplyVertexColorTexture(CTerrain* pTerrain, NiSourceTexturePtr pkTexture, const int iChunkID, const float fLum, const bool bFixLum, const float fIncMultiple); /// 从地形 chunk 的 blend texture alpha 通道中获取阴影纹理 static NiSourceTexturePtr ExtractShadowTexture(CTerrain* pTerrain); /// 射线测试方式烘焙地表纹理 static bool RayTestShadowProcess( CTerrain *pTerrain,const NiVisibleArray &kGeometryArray, const NiPoint3& vLitDir, int iChunkID); /// 设置鼠标的坐标 static void SetMousePos(int iPosX1, int iPosY1, int iPoxX2, int iPosY2); // 计算地形最高最低点 [7/15/2009 hemeng] static void ComputeTerrainHeight(CTerrain *pTerrain, float& iLow, float& iHeigh); /// 导出地形的高度图 static bool ExportTerrainHeightMap(CTerrain *pTerrain, const char *pszTexFile,float& iLow,float& iHeigh); /// 导入地形的高度图 static bool LoadTerrainHeightMap(CTerrain * pTerrain, const char * pszTexFile, CTerrainChangeVertexCommand* pCommand,float iLow,float iHeigh); /// 设置地形顶点 alpha 值 //static void SetTerrainVertexAlpha(CTerrain* pTerrain, set& gridSet, float fAlpha); // 地形顶点alpha高7位记录地形水波信息,低1位记录地形是否隐藏 [11/24/2009 hemeng] static void SetTerrainVertexHidden(CTerrain* pTerrain, set& gridSet, bool bHidden); /// 设置 grid 的属性 static void CTerrainModifier::SetTerrainSurfaceProperty( CTerrain *pTerrain, const set& gridSet, int iProperty, bool bDelete ); /// 设置地形某层的纹理 // pkTerrain - 目标地形 // iLayer - 设置哪一层 (总共4层) // pszTextureFile - 纹理名称 static bool ApplyTextureToTerrain(CTerrain* pkTerrain, int iLayer, const char* pszTextureFile); // 模糊 blend texture 边缘像素, 使相临像素值相同,消除接缝 static bool SmoothBlendTextureEdge(CTerrain* pkTerrain); protected: /** *
功能说明: 更新chunk中的mtl材质 *
可访问性: *
注 释: * @param pChunk[in] Chunk指针 * @param eChannel[in] 通道索引,指R,G,B分量, 分别为1, 2, 3 * @param vPos[in] 鼠标指示位置 * @param fAlpha[in] 调整到的Alpha值 * @param fRadius0[in] 影响半径(小) * @param fRadius1[in] 影响半径(大) * @return 无 */ static void _Painting( CTerrain *pTerrain, const NiPoint3& vPos, float fAlpha, float fRadius0, float fRadius1, bool bAddTo ); static void _Painting( CTerrain *pTerrain, int iChunkIndx, EPaintChannel eChannel, const NiPoint3& vPos, float fAlpha, float fr, float fR, bool bAddTo ); /// 绘制顶点颜色 // bPaintWater控制是否是绘制地形海波效果 [11/25/2009 hemeng] static void _PaintingVertexColor(CTerrain *pTerrain, const NiPoint3& vPos, float fAlpha, float fRadius0, float fRadius1, bool bPaintWater ); /// 设置碰撞数据 /** *
功能说明:设置碰撞数据 *
可访问性: *
注 释:设置所选取grid的碰撞标志 * @param pTerrain[in] 地表对象 * @param grdiSet[in] grid集合 * @param iProperty[in] 标志, 地表属性 * @return 无 */ //static void _SetCollisionData( CTerrain *pTerrain, const set& gridSet, bool bSignal ); static void CTerrainModifier::_SetTerrainSurfaceProperty( CTerrain *pTerrain, const set& gridSet, int iProperty, bool bDelete ); /** *
功能说明: 更新chunk中的mtl材质 *
可访问性: *
注 释: * @param pChunk[in] Chunk指针 * @param eChannel[in] 通道索引,指R,G,B分量, 分别为1, 2, 3 * @param vPos[in] 鼠标指示位置 * @param fAlpha[in] 调整到的Alpha值 * @param fRadius0[in] 影响半径(小) * @param fRadius1[in] 影响半径(大) * @return 无 */ //static void _Painting( CTerrain *pTerrain, CTerrain::stChunk* pChunk, EPaintChannel eChannel, const NiPoint3& vPos, float fAlpha, float fRadius0, float fRadius1 ); static void _DoPainting( CTerrain *pTerrain, NiPixelData *pPixelData, int iYFrom, int iYTo, int iXFrom, int iXTo, const NiPoint2& vPos2D, float fr, float fR, float fAlpha, bool bAddTo ); /** *
功能说明: 获取位置及影响半径覆盖的Chunk区域 *
可访问性: *
注 释: * @param vPos[in] 指定位置 * @param fRadius[in] 影响半径 * @return 影响到的Chunk索引集合 */ static vector _GetAffectedChunks( CTerrain *pTerrain, const NiPoint3& vPos, float fRadius ); /// 获取像素对应的地表Chunk块 static int _GetPixelLocationChunk( CTerrain *pTerrain, NiPoint2& vPixel ); static void _CalculateFaceTB( CTerrain *pTerrain, int index0, int index1, int index2, NiPoint3& vFaceTangent, NiPoint3& vFaceBinormal ); // 081008 add by 和萌 /// 查找Gird对应BlendTexture的像素值 static unsigned char* _GetBlendPixelByGrid( CTerrain *pTerrain,int iChunkID, NiPoint2 vPos); static int _GetRegionPropertyByPixel( CTerrain *pTerrain,int iChunkID,unsigned char* ucPixel); private: /// 额外线程 static HANDLE m_hThread; /// 同步事件 static HANDLE m_hEvent; /// 需要线程处理标志 static bool m_bNeedThread; /// 线程处理Block块定义 struct stPaintThreadBlock { CTerrain *pTerrain; NiPixelData *pPixelData; int iXFrom; int iXTo; int iYFrom; int iYTo; NiPoint2 ptCenter; float fr; float fR; float fAlpha; bool bAddTo; stPaintThreadBlock( CTerrain *pTerrain_, NiPixelData* pPixelData_, int iYFrom_, int iYTo_, int iXFrom_, int iXTo_, const NiPoint2& ptCenter_, float fr_, float fR_, float fAlpha_, bool bAddTo_ ) { pTerrain = pTerrain_; pPixelData = pPixelData_; iYFrom = iYFrom_; iYTo = iYTo_; iXFrom = iXFrom_; iXTo = iXTo_; ptCenter = ptCenter_; fr = fr_; fR = fR_; fAlpha = fAlpha_; bAddTo = bAddTo_; } }; /// 线程处理Block块 static stPaintThreadBlock m_stPaintThreadBlock; // 当前是否在绘制纹理 static bool m_bPaintTexture; // 当前是否在绘制顶点颜色 static bool m_bPaintVertexColor; // 当前是否在绘制地形海波 [11/25/2009 hemeng] static bool m_bPaintWaterScene; // 当前使用的顶点颜色 static NiColorA m_kInUseVertexColor; // 笔刷纹理 static NiSourceTexture* m_pkBrushTexture; // 地形操作 static ETerrainOperation m_TerrainOperation; // 绘制操作是否是叠加效果 static bool m_bPaintAddTo; // 是否是覆盖的方式绘制地表属性 (否的话只绘制空白区域) static bool m_bPaintTerrPropOverlap; // 当前显示和被改变的 property static int m_iOnEditProperty; /// 记录鼠标的操作 static int m_iStartX; static int m_iStartY; static int m_iEndX; static int m_iEndY; }; #pragma make_public(CTerrainModifier) #endif //TERRAIN_MODIFIER_H #endif