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