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); };