www.pudn.com > notWow.rar > Map.h


#pragma once 
 
#include  
#include  
#include "Enums.h" 
#include "M2Block.h" 
#include "Camera.h" 
#include "Model.h" 
#include "Char.h" 
#include "Effect.h" 
 
 
#include  
 
#include  
#include  
#include  
#include  
 
using namespace std; 
 
 
//    Z : Height 
//    | 
//    | 
//    | 
//   O'------------X : Width 
//  
 
/* 
	class Map Instruction: 
	地图(Map)有2个部分组成:地形(Terrians)和物品(Object) 
 
		地形有个2个基本划分:地块(TerrianPlate)和纹理块(TexturePlate),他们都是正方形 
		一个TerrianPlate的边长(m_fTerrianSize)为1.0f, 
		而TexturePlat的m_fTextureSize为4.0f 
		也就是说,TexturePlate含有16的TerrianPlate. 
		TerrianPlate的作用是体现地形的高低,是Map的基本逻辑单位 
		TexturePlate的作用的是体现地面的外貌,Map的顶点储存是按TexturePlate来安排的 
		一个Map的逻辑尺寸(TerrianPlate的个数)必须是4的倍数 
		一个TexturePlate含有25的Vertices,构成32个Faces,所有的TexturePlate都使用相同的Indices 
		也就是说,在Render时,是对每个TexturePlate分别Render 
		m_pHeights用来储存Vertex的高度,尺寸是(m_TerrianWidth + 1 ) * (m_TerrianHeight + 1 ) 
		m_pTerrains用来储存TerrianPlate的逻辑属性,尺寸是m_TerrianWidth * m_TerrianHeight  
		Map中X的正方向为Width的正方向,Z的正方向为Height的正方向 
 
		下面举例说明说明: 
 
		如一个逻辑(TerrianPlate)上8 * 8 的Map,TexturePlate为2 * 2 
 
        +Z 
         | 
         '-- +X 
					0  1  2  3  4     4  5  6  7  8							 
				TexturePlate2(1,0)                Height(TerrianWidth+1,TerrianHeight+1) 
8					.  .  .  .  .     .  .  .  .  . 
7					.  .  .  .  .     .  .  .  .  . 
6					.  .  .  .  .     .  .  .  .  . 
5					.  .  .  .  .     .  .  .  .  . 
4					.  .  .  .  .     .  .  .  .  .  
				TexturePlate0(0,0)    TexturePlate1(0,1) 
4					.  .  .  .  .     .  .  .  .  . 
3					.  .  .  .  .     .  .  .  .  . 
2					.  .  .  .  .     .  .  .  .  . 
1					.  .  .  .  .     .  .  .  .  . 
0	 Terrian(0,0) =>.  .  .  .  .     .  .  .  .  . <=Terrian(0,TerrianHeight)            
					^            
				Height(0,0) 
 
		Map全部采用的的行主存储 
		处于TexturePlate边上的Vertex显然是重复的. 
		Vertices按TexturePlate储存在VertexBuffer中 
		这样的结构对逻辑-物理转化是带来的不便. 
		比如Vertex(5,6) 的 Height可以直接求得 m_pHeights[6 * (m_TerrainWidth + 1) + 5] 
            但它的在VertexBuffer的位置则这样计算: 
		TexX = 5 / m_fTextureSize;	 
		TexZ = 6 / m_fTextureSize; 
		InTX = 5 % m_fTextureSize; 
		InTZ = 6 % m_fTextureSize; 
		Offset = m_nTextureVertices * (TexX + TexZ * m_TexturesWidth) ; 该TexturePlate的基位置 
		Offset += InTX + InTZ * 5; TexturePlate内的Offset 
		 
*/ 
 
typedef unsigned short TERRIAN; 
#define TRR_NORMAL	0x0000 
#define TRR_FORBID	0x0100 
#define TRR_WATER	0x0200 
#define TRR_SPECIAL	0x0400 
 
class Map 
{ 
	friend class Scene; 
protected: 
	struct TERRIANVERTEX 
	{ 
		D3DXVECTOR3 Pos;       						 
		D3DXVECTOR3 Normal;        
		D3DXVECTOR2 Texcoord; 
		const static DWORD FVF = (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1); 
	}; 
	struct SKYVERTEX 
	{ 
		D3DXVECTOR3 Pos;    
		DWORD		Color; 
		D3DXVECTOR2 Texcoord; 
		const static DWORD FVF = (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1); 
	}; 
	struct BACKVERTEX 
	{ 
		D3DXVECTOR3 Pos; 
		DWORD		Color; 
		const static DWORD FVF = ( D3DFVF_XYZ | D3DFVF_DIFFUSE ); 
	}; 
	 
	struct Node 
	{ 
		float           XPos, YPos, ZPos;  
		float           Size;              
 
		unsigned long   nObjects; 
		list::iterator> ObjectsList; 
		list		TerrianList; 
		Node*		Nodes[8];         
 
		Node() 
		{ 
			XPos = YPos = ZPos = Size = 0.0f;  
			nObjects = 0;            
			for(short i=0;i<8;i++)   
				Nodes[i] = NULL;      
		} 
 
		~Node() 
		{ 
			ObjectsList.clear();  
			TerrianList.clear(); 
			for(short i=0;i<8;i++)  
			{ 
				delete Nodes[i];  
				Nodes[i] = NULL; 
			} 
		} 
		bool CheckRectangle(const D3DXVECTOR3 &vMin,const D3DXVECTOR3 &vMax) 
		{	 
			if(vMin.x > XPos + Size || vMax.x < XPos - Size) 
				return false; 
			if(vMin.y > YPos + Size || vMax.y < YPos - Size) 
				return false; 
			if(vMin.z > ZPos + Size || vMax.z < ZPos - Size) 
				return false; 
			return true; 
		} 
	}; 
 
	LPDIRECT3DDEVICE9		m_pd3dDevice; 
	LPDIRECT3DVERTEXBUFFER9 m_pTerriansVB; 
	LPDIRECT3DINDEXBUFFER9  m_pIB; 
 
	LPDIRECT3DVERTEXBUFFER9	m_pSkyVB; 
	LPDIRECT3DVERTEXBUFFER9 m_pBackVB; 
	 
	Effect					m_Effect; 
 
	TextureID				m_SkyTexture; 
 
	int						m_nTerrianVertices; 
 
	int						m_TerriansWidth; 
	int						m_TerriansHeight; 
	float					m_fTerrianSize; 
 
 
	int						m_TexturesHeight; 
	int						m_TexturesWidth; 
	float					m_fTextureSize; 
 
	// Objects : 
	TERRIAN*				m_pTerrians; 
	float*					m_pHeights; 
	float*					m_pMaxHeights; 
	float*					m_pMinHeights; 
	TextureID*				m_pTextureID; 
	 
	list				m_NearDrawList; 
	list				m_FarDrawList; 
	bool*					m_pTerrianDraw; 
 
	vector			m_TexName;			// use for MapEditor 
	map	m_IDtoOffset;		// use for MapEditor 
 
	list		m_ObjectsList; 
	vector		m_NearPtrs; 
	vector		m_FarPtrs; 
	vector::iterator m_NearCurItr; 
	vector::iterator m_FarCurItr; 
	int						m_FarCurPos; 
	int						m_NearCurPos; 
 
	Node*					m_pRootNode; 
 
	int						m_LastID; 
 
	ScriptID				m_ScriptID; 
 
public: 
	Map() : m_pd3dDevice(NULL),m_pIB(NULL),m_pTerriansVB(NULL), 
			m_pSkyVB(NULL),m_pBackVB(NULL),m_pMinHeights(NULL),m_pMaxHeights(NULL), 
			m_pTerrians(NULL),m_pTextureID(NULL),m_pTerrianDraw(NULL), 
			m_pHeights(NULL),m_pRootNode(NULL) 
	{ 
 
	} 
 
	// rebuild the source in the default pool 
	bool Reset(); 
	void Lost(); 
 
	bool Init(LPDIRECT3DDEVICE9 pd3dDevice,const char *Name,const char *SkyName,ScriptID ID); 
	void Free(); 
 
	void Update(); 
	void Render(); 
 
	inline unsigned short GetTerrianID(int x,int z) 
	{ 
		return (0x00FF & m_pTerrians[z * m_TerriansWidth + x]); 
	}	 
	inline TERRIAN GetTerrian(int x,int z) 
	{ 
		return (0xFF00 & m_pTerrians[z * m_TerriansWidth + x]); 
	} 
	float GetY(float fX,float fZ); 
 
	inline float GetY(int iX,int iZ) 
	{ 
		return m_pHeights[(m_TerriansWidth+1) * iZ + iX]; 
	} 
	 
protected: 
	void CreateTree(Node *pParent,Node **ppNode,float XPos,float YPos,float ZPos,float Size); 
	void AddTreeNode(Frustum* pFrustum,bool bNear,Node *Node); 
};