随机生成游戏建筑物的算法

版本一

随机生成游戏建筑和导航网格。使用房屋四壁扩张生长的方式生成。.
存在的缺陷,有机会重构一下:
模型细致度不够,模板顶点数据直接通过程序生成使得算法变的复杂,扩展功能也变得复杂,可以试试将模板在3dsmax中预制导出。
建筑结构有些凌乱。
风格太少,需要多加模板。
todo在编辑器中根据设计师引导半自动生成。


 

版本二
先生成道路网,划分地块,再生成大厦类建筑。
存在的缺陷,有机会重构一下:
道路太直
模型细致度不够,大厦类建筑一般不适合使用预制模板,暂时使用多边形放样的形式。需要添加更多参数和功能比如生成异形艺术建筑。
需要添加点缀物品,比如路灯、树木、桥、等。关于树木的随机生成另外有一套算法,这里不再重复,当然也可以使用预制的树木。
todo在编辑器中根据设计师引导半自动生成。

 版本一源码:

//========================================================
//  @Date:     2016.05
//  @File:     Include/Render/Building.h
//  @Brief:     Building
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================
#ifndef building_H
#define building_H 

#include "General/General.h"
#include "Render/Texture.h"
#include "Math/Mathlib.h"

class Box;
class VertexBuffer;
class IndexBuffer;
//!todo  楼梯 路灯 路 石头 裁切爆炸
class House
{
public:
	enum HouseType
	{
		HouseNull=0,
		HouseTypeFourWall, //四面墙体
		HouseTypeRoof,     //屋顶
		HouseTypeHallway,  //走廊
		HouseTypeCityWall, //城墙
		HouseTypeStairs,   //楼梯
		HouseTypeCityGate, //城门楼
		HouseTypeSeparator,//分隔板
		HouseTypeColumn,   //柱子
		HouseTypeFence,    //栅栏
		HouseTypeSquare,   //广场
		HouseTypeSteps,    //广场台阶
	};

	enum HouseDirIndex
	{
		HouseUpIndex    =0,
		HouseDownIndex  =1,
		HouseFrontIndex =2,
		HouseBackIndex  =3,
		HouseLeftIndex  =4,
		HouseRightIndex =5,
		HouseIndexMax   =6,
	};
	enum HouseDir
	{
		HouseDirNull = -1,
		HouseUp    =1,
		HouseDown  =1<<HouseDownIndex,
		HouseFront =1<<HouseFrontIndex,
		HouseBack  =1<<HouseBackIndex,
		HouseLeft  =1<<HouseLeftIndex,
		HouseRight =1<<HouseRightIndex,
	};

	House();
	virtual ~House();

	virtual void Render();
	bool overlap(Box & bound);
	void SetParm(House* parentHouse,const vec3 & pos, const vec3 & halfExtend,HouseType type,HouseDir houseDir,int depthLevel,int depthHigh);
	virtual bool GenTopoBuilding();
	virtual bool GenSelfModel();
	virtual bool GenNavgation();
	virtual bool IsGenBreak(HouseDir dir); //本次gen是否终端
	virtual bool IsNextGenBreak(HouseDir dir);//下个方向上的house是否终端
	bool NotifySubCheckPosFail(House* subHouse,HouseDir dir);

public:
	mat4  GetVertexMatrix(const vec3& pos,const vec3& scale);
	mat4  GetVertexMatrix(const vec3& pos,const vec3& scale,const vec3& rot);
	vec3  GetDirVector(HouseDir dir);
	static HouseDirIndex DirIndex(HouseDir dir);
	static HouseDir InverseDir(HouseDir dir);
public:
	enum HouseTemplateType
	{
		BoxSimple = 0,
		BoxDoorFront,
		HouseTemplateNum
	};
	class TVertex
	{
	public:
		float u;
		float v;
		float w;
		float r;
		float g;
		float b;
	};
	class HouseTemplate
	{
	public:
		virtual ~HouseTemplate();
		vec3*     VVertexs;
		TVertex*  TVertexs;
		HouseDir* VertexDir;
		int       vertexNum;
		virtual void InitTemplate();
		//!点在面上
		bool IsVertexInDir(int vertexIndex,int dir);
		//!点是面的起点
		bool IsVertexBeginDirWithoutChange(int vertexIndex,int dir);
		bool IsVertexBeginDirWithinChange(int vertexIndex,int dir);
	};
	class HouseTemplateBox:public HouseTemplate
	{
	public:
		static const int VertexNum = 36;
		vec3     VVertexs[VertexNum];
		TVertex  TVertexs[VertexNum];
		HouseDir VertexDir[VertexNum];
		virtual void InitTemplate();
	};
	//!双层box,每一个面是个box,共6个box
	class HouseTemplateBoxWall:public HouseTemplate
	{
	public:
		static const int VertexNum = 36;
		vec3     VVertexs[VertexNum];
		TVertex  TVertexs[VertexNum];
		HouseDir VertexDir[VertexNum];
		virtual void InitTemplate();
	};
	class HouseTemplateDoor:public HouseTemplate
	{
	public:
		static const int MaxVertexNum = 108;
		static const int TemplateNum = 64; //dir 正好对应templateindex  null+HouseUp+HouseDown+...HouseRight=64
		vec3     m_VVertexs[TemplateNum][MaxVertexNum];
		TVertex  m_TVertexs[TemplateNum][MaxVertexNum];
		HouseDir m_VertexDir[TemplateNum][MaxVertexNum];
		int      m_VertexNum[TemplateNum];
		void InitDoorDir(int doorDir);
		virtual void InitTemplate();
	};
	static HouseTemplate* VertexTemplate[HouseTemplateNum];
	static void InitTemplate();

	//!todo通用的大鼓形状
	HouseType m_houseType;
	int       m_depthLevel;
	int       m_depthHigh;
	vec3      m_pos;
	vec3      m_halfExtend;
	//!父house 拓扑关系,以决定是否开门
	House*    m_parentHouse;
	HouseDir  m_houseDirFromParent;
	House*    m_subHouse[HouseIndexMax];

};

class HouseFourWall:public House
{
public:
	virtual void Rend();
	virtual bool GenTopoBuilding();
	virtual bool GenSelfModel();
};


class HouseRoof:public House
{
public:
	virtual void Rend();
	virtual bool GenTopoBuilding();
	virtual bool GenSelfModel();
	virtual bool GenNavgation();
};

class HouseColumn:public House
{
public:
	virtual void Rend();
	virtual bool GenTopoBuilding();
	virtual bool GenSelfModel();
	virtual bool GenNavgation();
};

class HouseHallway:public House
{
public:
	virtual void Rend();
	virtual bool GenTopoBuilding();
	virtual bool GenSelfModel();
	virtual bool IsGenBreak(HouseDir dir); 
};


class HouseSquare:public House
{
public:
	HouseSquare();
	virtual void Rend();
	virtual bool GenTopoBuilding();
	virtual bool GenSelfModel();
	virtual bool IsGenBreak(HouseDir dir); 
	virtual bool GenNavgation();
	bool    m_skipFace[6];
	bool    m_bWall;
	bool    m_bWater;
	//!路 栏杆
};

class HouseSteps:public House
{
public:
	virtual void Rend();
	virtual bool GenTopoBuilding();
	virtual bool GenSelfModel();
	virtual bool IsGenBreak(HouseDir dir); 
	//virtual bool GenNavgation();
};

class BuildingDef
{
public:
	enum TextureUnitType
	{
		TexWall = 0,  //四壁
		TexWallDoor,  //四壁带门
		TexWallColumn,//四壁为柱
		TexRoof,      //屋顶
		TexColumn,    //柱子
		//TexHallway,   //使用栅栏
		TexFence,     //栅栏
		TexFloor,     //地板
		TexSteps,     //台阶
		TexWater,     //水
		TexDecalWall,
		TexDecalFloor,
		TexDecalWater,
		TexNum,

	};
	class TextureUnit
	{
	public:
		//!TextureUnitType;
		RectF texCoordRect[8];
		int   unitNum;
	};
	TextureUnit m_textureUnits[TexNum];
	bool  LoadFromFile(const char* filename);
	RectF GetTextureRect(TextureUnitType type,int index=-1);
	//!mat32d 获得矩阵将纹理坐标从【0,1】转到实际区域
	mat4  GetTextureMatrix(TextureUnitType type,int index=-1);
};

class WayEdge
{
public:
	vec3 start;
	vec3 end;
};

//todo方案:bsp分割空间构建地牢房间  
class Building
{
public:
	Building();
	~Building();
	void Free();
	void SaveAsObj(const char* filename);
	void GenBuilding(BuildingDef* buildingDef);
	//!缩减顶点数
	void GenIndex();
	void Rend();
	void RendNavgation();
	void AddHouse(House* house);
	//!返回位置冲突的house
	House* CheckHousePos(House* house);
	House* CheckBound(Box* bound,House* houseExcept);
	float  GetTerrainHeight(const vec3& pos);
	void   PushQueue(House* house);

	House** m_houseList;
	int     m_houseNum;
	int     m_houseMaxNum;

	class Vertex
	{
	public:
		float x;
		float y;
		float z;
		float u;
		float v;
		float w;
	};

	int m_indexNum;
	int m_vVertexNum;
	int m_maxVertexNum;

	IndexInt*   m_indexs;
	Vertex*     m_vertices;

	BuildingDef* m_buildingDef;

	vec3      m_normalHalfExtend;
	vec3      m_normalSquareHalfExtend;

	static const int DepthZero = 1;    //起始层为1
	int MaxDepthLevel;//3;             //可以分3层
	int MaxDepthHeight;

	int MaxSquareDepthLevel;
	int MaxSquareDepthHeight;

	WayEdge*  m_wayEdges;
	int       m_wayEdgesNum;

	//!地平线
	float     m_houseBaseHeight;

	TexturePtr m_texture;	
	VertexBuffer*  m_vertexBuffer;
	IndexBuffer*   m_indexBuffer;

private:
	void*     m_HouseQueue;

};

extern Building G_Building;

#endif 

//========================================================
//  @Date:     2016.05
//  @File:     SourceLib/Render/Building.cpp
//  @Brief:     Building
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================
 
#include "General/Pch.h"
#include "Render/Building.h"
#include "Render/RendDriver.h"

#include "Render/Building.h"
//#include <GL/glut.h>
#include <list>
#include "Ozcollide/box.h"
#include "General/Pce.h"

Building G_Building;

House::HouseTemplate* House::VertexTemplate[HouseTemplateNum];
House::HouseTemplate::~HouseTemplate()
{
}
void House::HouseTemplate::InitTemplate()
{
}
bool House::HouseTemplate::IsVertexBeginDirWithoutChange(int vertexIndex,int dir)
{
	if (VertexDir[vertexIndex]&dir)
	{
		if (vertexIndex==0)
		{
			return true;
		}
		else if (!(VertexDir[vertexIndex-1]&dir))
		{
			return true;
		}
	}
	return false;
}
bool House::HouseTemplate::IsVertexBeginDirWithinChange(int vertexIndex,int dir)
{
	if (VertexDir[vertexIndex]&dir)
	{
		if (vertexIndex==0)
		{
			return true;
		}
		else if (VertexDir[vertexIndex-1]!=VertexDir[vertexIndex])
		{
			return true;
		}
	}
	return false;
}
bool House::HouseTemplate::IsVertexInDir(int vertexIndex,int dir)
{
	if (VertexDir[vertexIndex]&dir)
	{
		return true;
	}
	return false;
}

void House::HouseTemplateBox::InitTemplate()
{
	HouseTemplate::vertexNum = VertexNum;
	HouseTemplate::VVertexs = VVertexs;
	HouseTemplate::TVertexs = TVertexs;
	HouseTemplate::VertexDir = VertexDir;

	//VertexNum=36
	TVertex BoxTVertexs[VertexNum]=
	{
		{0,0,1,1,1,1},{1,0,1,1,1,1},{1,1,1,1,1,1},  {0,0,1,1,1,1},{1,1,1,1,1,1},{0,1,1,1,1,1}, 
		{0,0,1,1,1,1},{1,0,1,1,1,1},{1,1,1,1,1,1},  {0,0,1,1,1,1},{1,1,1,1,1,1},{0,1,1,1,1,1},						  

		{0,0,1,1,1,1},{1,0,1,1,1,1},{1,1,1,1,1,1},  {0,0,1,1,1,1},{1,1,1,1,1,1},{0,1,1,1,1,1}, 
		{0,0,1,1,1,1},{1,0,1,1,1,1},{1,1,1,1,1,1},  {0,0,1,1,1,1},{1,1,1,1,1,1},{0,1,1,1,1,1},

		{0,0,1,1,1,1},{1,0,1,1,1,1},{1,1,1,1,1,1},  {0,0,1,1,1,1},{1,1,1,1,1,1},{0,1,1,1,1,1}, 
		{0,0,1,1,1,1},{1,0,1,1,1,1},{1,1,1,1,1,1},  {0,0,1,1,1,1},{1,1,1,1,1,1},{0,1,1,1,1,1},
	};

	vec3 BoxVVertexs[VertexNum]=
	{
		vec3(-1,-1,-1),vec3(1,-1,-1),vec3(1,1,-1),  vec3(-1,-1,-1),vec3(1,1,-1),vec3(-1,1,-1),
		vec3(-1,-1,1),vec3(1,-1,1),vec3(1,1,1),  vec3(-1,-1,1),vec3(1,1,1),vec3(-1,1,1),

		vec3(-1,-1,-1),vec3(-1,-1,1),vec3(-1,1,1),  vec3(-1,-1,-1),vec3(-1,1,1),vec3(-1,1,-1),
		vec3(1,-1,-1),vec3(1,-1,1),vec3(1,1,1),  vec3(1,-1,-1),vec3(1,1,1),vec3(1,1,-1),

		vec3(-1,-1,-1),vec3(1,-1,-1),vec3(1,-1,1),  vec3(-1,-1,-1),vec3(1,-1,1),vec3(-1,-1,1),
		vec3(-1,1,-1),vec3(1,1,-1),vec3(1,1,1),  vec3(-1,1,-1),vec3(1,1,1),vec3(-1,1,1),
	};

	HouseDir BoxVertexDir[VertexNum] =
	{
		HouseBack,   HouseBack,   HouseBack,    HouseBack,    HouseBack,    HouseBack,
		HouseFront,	 HouseFront,  HouseFront,	HouseFront,	  HouseFront,	HouseFront,
		HouseLeft,	 HouseLeft,	  HouseLeft,	HouseLeft,	  HouseLeft,	HouseLeft,
		HouseRight,	 HouseRight,  HouseRight,	HouseRight,	  HouseRight,	HouseRight,
		HouseDown,	 HouseDown,	  HouseDown,	HouseDown,	  HouseDown,	HouseDown, 
		HouseUp,	 HouseUp,	  HouseUp,		HouseUp,	  HouseUp,		HouseUp,   
	};

	for(int i=0;i<VertexNum;i++)
	{
		VVertexs[i] = BoxVVertexs[i];
		TVertexs[i] = BoxTVertexs[i];
		VertexDir[i] = BoxVertexDir[i];
	}
}
void House::HouseTemplateBoxWall::InitTemplate()
{
	HouseTemplate::vertexNum = VertexNum;
	HouseTemplate::VVertexs = VVertexs;
	HouseTemplate::TVertexs = TVertexs;
	HouseTemplate::VertexDir = VertexDir;

	//VertexNum=36
	TVertex BoxTVertexs[VertexNum]=
	{
		{0,0,1,1,1,1},{1,0,1,1,1,1},{1,1,1,1,1,1},  {0,0,1,1,1,1},{1,1,1,1,1,1},{0,1,1,1,1,1}, 
		{0,0,1,1,1,1},{1,0,1,1,1,1},{1,1,1,1,1,1},  {0,0,1,1,1,1},{1,1,1,1,1,1},{0,1,1,1,1,1},						  

		{0,0,1,1,1,1},{1,0,1,1,1,1},{1,1,1,1,1,1},  {0,0,1,1,1,1},{1,1,1,1,1,1},{0,1,1,1,1,1}, 
		{0,0,1,1,1,1},{1,0,1,1,1,1},{1,1,1,1,1,1},  {0,0,1,1,1,1},{1,1,1,1,1,1},{0,1,1,1,1,1},

		{0,0,1,1,1,1},{1,0,1,1,1,1},{1,1,1,1,1,1},  {0,0,1,1,1,1},{1,1,1,1,1,1},{0,1,1,1,1,1}, 
		{0,0,1,1,1,1},{1,0,1,1,1,1},{1,1,1,1,1,1},  {0,0,1,1,1,1},{1,1,1,1,1,1},{0,1,1,1,1,1},
	};

	vec3 BoxVVertexs[VertexNum]=
	{
		vec3(-1,-1,-1),vec3(1,-1,-1),vec3(1,1,-1),  vec3(-1,-1,-1),vec3(1,1,-1),vec3(-1,1,-1),
		vec3(-1,-1,1),vec3(1,-1,1),vec3(1,1,1),  vec3(-1,-1,1),vec3(1,1,1),vec3(-1,1,1),

		vec3(-1,-1,-1),vec3(-1,-1,1),vec3(-1,1,1),  vec3(-1,-1,-1),vec3(-1,1,1),vec3(-1,1,-1),
		vec3(1,-1,-1),vec3(1,-1,1),vec3(1,1,1),  vec3(1,-1,-1),vec3(1,1,1),vec3(1,1,-1),

		vec3(-1,-1,-1),vec3(1,-1,-1),vec3(1,-1,1),  vec3(-1,-1,-1),vec3(1,-1,1),vec3(-1,-1,1),
		vec3(-1,1,-1),vec3(1,1,-1),vec3(1,1,1),  vec3(-1,1,-1),vec3(1,1,1),vec3(-1,1,1),
	};

	HouseDir BoxVertexDir[VertexNum] =
	{
		HouseBack,   HouseBack,   HouseBack,    HouseBack,    HouseBack,    HouseBack,
		HouseFront,	 HouseFront,  HouseFront,	HouseFront,	  HouseFront,	HouseFront,
		HouseLeft,	 HouseLeft,	  HouseLeft,	HouseLeft,	  HouseLeft,	HouseLeft,
		HouseRight,	 HouseRight,  HouseRight,	HouseRight,	  HouseRight,	HouseRight,
		HouseDown,	 HouseDown,	  HouseDown,	HouseDown,	  HouseDown,	HouseDown, 
		HouseUp,	 HouseUp,	  HouseUp,		HouseUp,	  HouseUp,		HouseUp,   
	};

	for(int i=0;i<VertexNum;i++)
	{
		VVertexs[i] = BoxVVertexs[i];
		TVertexs[i] = BoxTVertexs[i];
		VertexDir[i] = BoxVertexDir[i];
	}
}
void House::HouseTemplateDoor::InitTemplate()
{
	HouseTemplate::vertexNum = m_VertexNum[0];
	HouseTemplate::VVertexs = m_VVertexs[0];
	HouseTemplate::TVertexs = m_TVertexs[0];
	HouseTemplate::VertexDir = m_VertexDir[0];


	//包含门的面
	//  ________________
	//  |    /|5 /|    /|
	//  | 1 / | /6| 3 / |
	//  |  /  |/__|  /  |
	//  | / 2 |   | / 4 |
	//  |/____|门 |/____|


	TVertex BoxTVertexs[6]=
	{
		{0,0,1,1,1,1},{1,0,1,1,1,1},{1,1,1,1,1,1},  {0,0,1,1,1,1},{1,1,1,1,1,1},{0,1,1,1,1,1},
	};
	TVertex BoxDoorTVertexs[18]=
	{		
		{0,0,1,1,1,1},{1/3.0f,0,1,1,1,1},{1/3.0f,1,1,1,1,1},  {0,0,1,1,1,1},{1/3.0f,1,1,1,1,1},{0,1,1,1,1,1},		
		{2/3.0f,0,1,1,1,1},{1,0,1,1,1,1},{1,1,1,1,1,1},  {2/3.0f,0,1,1,1,1},{1,1,1,1,1,1},{2/3.0f,1,1,1,1,1},	
		{1/3.0f,0.5f,1,1,1,1},{2/3.0f,0.5f,1,1,1,1},{2/3.0f,1,1,1,1,1},  {1/3.0f,0.5f,1,1,1,1},{2/3.0f,1,1,1,1,1},{1/3.0f,1,1,1,1,1},	
	};

	//HouseUp    =1,
	//HouseDown  =1<<1,
	//HouseFront =1<<2,
	//HouseBack  =1<<3,
	//HouseLeft  =1<<4,
	//HouseRight =1<<5,
	//VertexNum=36
	float left = -1;
	float right = 1;
	float down = -1;
	float up = 1;
	vec3 BoxVVertexs[6][6]=
	{
		{vec3(-1,1,-1),vec3(1,1,-1),vec3(1,1,1),  vec3(-1,1,-1),vec3(1,1,1),vec3(-1,1,1)      },
		{vec3(-1,-1,-1),vec3(1,-1,-1),vec3(1,-1,1),  vec3(-1,-1,-1),vec3(1,-1,1),vec3(-1,-1,1)},

		{vec3(-1,-1,1),vec3(1,-1,1),vec3(1,1,1),  vec3(-1,-1,1),vec3(1,1,1),vec3(-1,1,1)      },
		{vec3(-1,-1,-1),vec3(1,-1,-1),vec3(1,1,-1),  vec3(-1,-1,-1),vec3(1,1,-1),vec3(-1,1,-1)},

		{vec3(-1,-1,-1),vec3(-1,-1,1),vec3(-1,1,1),  vec3(-1,-1,-1),vec3(-1,1,1),vec3(-1,1,-1)},
		{vec3(1,-1,-1),vec3(1,-1,1),vec3(1,1,1),  vec3(1,-1,-1),vec3(1,1,1),vec3(1,1,-1)      },
	};

	vec3 BoxDoorVVertexs[6][18]=
	{
		//vec3(-1,1,-1),vec3(1,1,-1),vec3(1,1,1),  vec3(-1,1,-1),vec3(1,1,1),vec3(-1,1,1),
		{vec3(-1,1,-1),vec3(1,1,-1),vec3(1,1,1),  vec3(-1,1,-1),vec3(1,1,1),vec3(-1,1,1),
		vec3(-1,1,-1),vec3(1,1,-1),vec3(1,1,1),  vec3(-1,1,-1),vec3(1,1,1),vec3(-1,1,1),
		vec3(-1,1,-1),vec3(1,1,-1),vec3(1,1,1),  vec3(-1,1,-1),vec3(1,1,1),vec3(-1,1,1)},

		//vec3(-1,-1,-1),vec3(1,-1,-1),vec3(1,-1,1),  vec3(-1,-1,-1),vec3(1,-1,1),vec3(-1,-1,1),
		{vec3(-1,-1,-1),vec3(1,-1,-1),vec3(1,-1,1),  vec3(-1,-1,-1),vec3(1,-1,1),vec3(-1,-1,1),
		vec3(-1,-1,-1),vec3(1,-1,-1),vec3(1,-1,1),  vec3(-1,-1,-1),vec3(1,-1,1),vec3(-1,-1,1),
		vec3(-1,-1,-1),vec3(1,-1,-1),vec3(1,-1,1),  vec3(-1,-1,-1),vec3(1,-1,1),vec3(-1,-1,1)},

		/
		//vec3(-1,-1,1),vec3(1,-1,1),vec3(1,1,1),  vec3(-1,-1,1),vec3(1,1,1),vec3(-1,1,1),
		{vec3(-1,-1,1),vec3(-1/3.0f,-1,1),vec3(-1/3.0f,1,1),  vec3(-1,-1,1),vec3(-1/3.0f,1,1),vec3(-1,1,1),
		vec3(1/3.0f,-1,1),vec3(1,-1,1),vec3(1,1,1),  vec3(1/3.0f,-1,1),vec3(1,1,1),vec3(1/3.0f,1,1),
		vec3(-1/3.0f,0,1),vec3(1/3.0f,0,1),vec3(1/3.0f,1,1),  vec3(-1/3.0f,0,1),vec3(1/3.0f,1,1),vec3(-1/3.0f,1,1)},

		//vec3(-1,-1,-1),vec3(1,-1,-1),vec3(1,1,-1),  vec3(-1,-1,-1),vec3(1,1,-1),vec3(-1,1,-1),
		{vec3(-1,-1,-1),vec3(-1/3.0f,-1,-1),vec3(-1/3.0f,1,-1),  vec3(-1,-1,-1),vec3(-1/3.0f,1,-1),vec3(-1,1,-1),
		vec3(1/3.0f,-1,-1),vec3(1,-1,-1),vec3(1,1,-1),  vec3(1/3.0f,-1,-1),vec3(1,1,-1),vec3(1/3.0f,1,-1),
		vec3(-1/3.0f,0,-1),vec3(1/3.0f,0,-1),vec3(1/3.0f,1,-1),  vec3(-1/3.0f,0,-1),vec3(1/3.0f,1,-1),vec3(-1/3.0f,1,-1)},

		//==================^_^
		//vec3(-1,-1,-1),vec3(-1,-1,1),vec3(-1,1,1),  vec3(-1,-1,-1),vec3(-1,1,1),vec3(-1,1,-1),
		{vec3(-1,-1,-1),vec3(-1,-1,-1/3.0f),vec3(-1,1,-1/3.0f),  vec3(-1,-1,-1),vec3(-1,1,-1/3.0f),vec3(-1,1,-1),
		vec3(-1,-1,1/3.0f),vec3(-1,-1,1),vec3(-1,1,1),  vec3(-1,-1,1/3.0f),vec3(-1,1,1),vec3(-1,1,1/3.0f),
		vec3(-1,0,-1/3.0f),vec3(-1,0,1/3.0f),vec3(-1,1,1/3.0f),  vec3(-1,0,-1/3.0f),vec3(-1,1,1/3.0f),vec3(-1,1,-1/3.0f)},

		//vec3(1,-1,-1),vec3(1,-1,1),vec3(1,1,1),  vec3(1,-1,-1),vec3(1,1,1),vec3(1,1,-1),
		{vec3(1,-1,-1),vec3(1,-1,-1/3.0f),vec3(1,1,-1/3.0f),  vec3(1,-1,-1),vec3(1,1,-1/3.0f),vec3(1,1,-1),
		vec3(1,-1,1/3.0f),vec3(1,-1,1),vec3(1,1,1),  vec3(1,-1,1/3.0f),vec3(1,1,1),vec3(1,1,1/3.0f),
		vec3(1,0,-1/3.0f),vec3(1,0,1/3.0f),vec3(1,1,1/3.0f),  vec3(1,0,-1/3.0f),vec3(1,1,1/3.0f),vec3(1,1,-1/3.0f)},
	};

	//dir 正好对应templateindex,  max= null+HouseUp+HouseDown+...HouseRight=64
	for (int templateIndex=0;templateIndex<TemplateNum;templateIndex++)
	{
		int vertexNum = 0;
		//构造每种开门类型的模版
		//HouseUp    =1,
		//HouseDown  =1<<1,
		//HouseFront =1<<2,
		//HouseBack  =1<<3,
		//HouseLeft  =1<<4,
		//HouseRight =1<<5,
		for (int f=0;f<HouseIndexMax;f++)
		{
			HouseDir dir =(HouseDir) (1<<f);
			if(templateIndex&dir)
			{
				for (int i=0;i<18;i++)
				{
					m_VVertexs[templateIndex][vertexNum] = BoxDoorVVertexs[f][i];
					m_TVertexs[templateIndex][vertexNum] = BoxDoorTVertexs[i];
					m_VertexDir[templateIndex][vertexNum] = dir;
					vertexNum++;
				}
			}
			else
			{
				for (int i=0;i<6;i++)
				{
					m_VVertexs[templateIndex][vertexNum] = BoxVVertexs[f][i];
					m_TVertexs[templateIndex][vertexNum] = BoxTVertexs[i];
					m_VertexDir[templateIndex][vertexNum] = dir;
					vertexNum++;
				}
			}
		}
		m_VertexNum[templateIndex] = vertexNum;
	}
}

void House::HouseTemplateDoor::InitDoorDir(int doorDir)
{
	HouseTemplate::vertexNum = m_VertexNum[doorDir];
	HouseTemplate::VVertexs = m_VVertexs[doorDir];
	HouseTemplate::TVertexs = m_TVertexs[doorDir];
	HouseTemplate::VertexDir = m_VertexDir[doorDir];
}


void House::InitTemplate()
{
	static bool init = false;
	if (init==true)
	{
		return;
	}
	init = true;

	static HouseTemplateBox template0;
	static HouseTemplateDoor template1;
	VertexTemplate[0] = &template0;
	VertexTemplate[1] = &template1;
	for (int i=0;i<HouseTemplateNum;i++)
	{
		VertexTemplate[i]->InitTemplate();
	}
}

House::House()
:m_parentHouse(NULL)
{
	for (int i=0;i<HouseIndexMax;i++)
	{
		m_subHouse[i] = NULL;
	}
}

House::~House()
{

}

void House::Render()
{

}

bool House::overlap(Box & bound)
{
	return false;
}

void House::SetParm(House* parentHouse,const vec3 & pos, const vec3 & halfExtend,HouseType type,HouseDir houseDir,int depthLevel,int depthHigh)
{
	m_parentHouse = parentHouse;
	m_houseType = type;
	m_depthLevel = depthLevel;
	m_depthHigh = depthHigh;
	m_pos = pos;
	m_halfExtend = halfExtend;
	m_houseDirFromParent = houseDir;
}

bool House::GenTopoBuilding()
{
	if(G_Building.CheckHousePos(this))//没有位置,中断生成
	{
		if(m_parentHouse)m_parentHouse->NotifySubCheckPosFail(this,m_houseDirFromParent);
		return false;
	}

	G_Building.AddHouse(this);

	return true;
}

bool House::GenSelfModel()
{
	//是否重叠
	return true;
}

bool House::IsGenBreak(HouseDir dir)
{
	switch(dir)
	{
	case HouseDirNull:
		break;
	case HouseDown:
	case HouseUp:
		if (m_depthHigh>=G_Building.MaxDepthHeight)
		{
			return true;
		}
	default:
		if (m_depthLevel>=G_Building.MaxDepthLevel)
		{
			return true;
		}
	}
	return false;
}

bool House::IsNextGenBreak(HouseDir dir)
{
	if (m_depthLevel>=G_Building.MaxDepthLevel || m_depthHigh>=G_Building.MaxDepthHeight)
	{
		return true;
	}
	switch(dir)
	{
	case HouseDirNull:
		break;
	case HouseDown:
	case HouseUp:
		if (m_depthHigh+1>=G_Building.MaxDepthHeight)
		{
			return true;
		}
	default:
		if (m_depthLevel+1>=G_Building.MaxDepthLevel)
		{
			return true;
		}
	}
	return false;
}

mat4 House::GetVertexMatrix(const vec3& pos,const vec3& scale)
{
	mat4 mats;
	mats.FromScale(scale.x,scale.y,scale.z);
	mat4 mat;
	mat.FromTranslate(pos.x,pos.y,pos.z);
	mat = mat*mats;
	return mat;
}

mat4 House::GetVertexMatrix(const vec3& pos,const vec3& scale,const vec3& rot)
{
	mat4 mats;
	mats.FromScale(scale.x,scale.y,scale.z);
	mat4 matr;
	matr.FromRotateY(rot.y);
	mats = matr*mats;
	mat4 mat;
	mat.FromTranslate(pos.x,pos.y,pos.z);
	mat = mat*mats;
	return mat;
}

vec3 House::GetDirVector(HouseDir dir)
{
	static vec3 DirVector[6] = 
	{
		vec3(0,1,0),     //HouseUp  =0,
		vec3(0,-1,0),	 //HouseDown,
		vec3(0,0,1),	 //HouseFront,
		vec3(0,0,-1),	 //HouseBack,
		vec3(-1,0,0),	 //HouseLeft,
		vec3(1,0,0),	 //HouseRight,
	};
	int i = 0;
	switch(dir)
	{
	case HouseUp   : i=0;break;
	case HouseDown : i=1;break;
	case HouseFront: i=2;break;
	case HouseBack : i=3;break;
	case HouseLeft : i=4;break;
	case HouseRight: i=5;break;
	default: break;
	}
	return DirVector[i];
}

House::HouseDirIndex  House::DirIndex(HouseDir dir)
{
	switch(dir)
	{
	case HouseDirNull:return HouseUpIndex;
	case HouseUp    :return HouseUpIndex;
	case HouseDown  :return HouseDownIndex;
	case HouseFront :return HouseFrontIndex ;
	case HouseBack  :return HouseBackIndex  ;
	case HouseLeft  :return HouseLeftIndex  ;
	case HouseRight :return HouseRightIndex ;
	};
	return HouseUpIndex;
}

bool House::NotifySubCheckPosFail(House* subHouse,HouseDir dir)
{
	if (m_subHouse[DirIndex(dir)]!=subHouse)
	{
		MsgBox(0,"NotifySubCheckPosFail","m_subHouse[DirIndex(dir)]!=subHouse",MB_OK);
	}
	m_subHouse[DirIndex(dir)] = 0;
	return true;
}


bool House::GenNavgation()
{
	if (m_parentHouse)
	{
		if (m_houseDirFromParent==House::HouseUp)
		{
			vec3 start = m_parentHouse->m_pos-vec3(0,1,0).Mult(m_parentHouse->m_halfExtend)*0.9f;
			vec3 end = m_pos-vec3(0,1,0).Mult(m_halfExtend)*0.9f;
			//垂直扩张,在门处取中间路点
			vec3 middlep = m_parentHouse->m_pos + m_parentHouse->m_halfExtend.Mult(GetDirVector(m_houseDirFromParent));
			//取近点
			if (start.z<end.z)
			{
				middlep.z = start.z;
			}
			else
			{
				middlep.z = end.z;
			}

			G_Building.m_wayEdges[G_Building.m_wayEdgesNum].start = start;
			G_Building.m_wayEdges[G_Building.m_wayEdgesNum].end = middlep;
			G_Building.m_wayEdgesNum++;

			G_Building.m_wayEdges[G_Building.m_wayEdgesNum].start = middlep;
			G_Building.m_wayEdges[G_Building.m_wayEdgesNum].end = end;
			G_Building.m_wayEdgesNum++;
		}
		else
		{
			vec3 start = m_parentHouse->m_pos-vec3(0,1,0).Mult(m_parentHouse->m_halfExtend)*0.9f;
			vec3 end = m_pos-vec3(0,1,0).Mult(m_halfExtend)*0.9f;
			//水平扩张,在门处取中间路点
			vec3 middlep = m_parentHouse->m_pos + m_parentHouse->m_halfExtend.Mult(GetDirVector(m_houseDirFromParent));
			//取高点
			if (start.y>end.y)
			{
				middlep.y = start.y;
			}
			else
			{
				middlep.y = end.y;
			}

			G_Building.m_wayEdges[G_Building.m_wayEdgesNum].start = start;
			G_Building.m_wayEdges[G_Building.m_wayEdgesNum].end = middlep;
			G_Building.m_wayEdgesNum++;

			G_Building.m_wayEdges[G_Building.m_wayEdgesNum].start = middlep;
			G_Building.m_wayEdges[G_Building.m_wayEdgesNum].end = end;
			G_Building.m_wayEdgesNum++;
		}
		return true;
	}
	return false;
}

House::HouseDir House::InverseDir(HouseDir dir)
{
	switch(dir)
	{
	case HouseFront: return HouseBack;
	case HouseBack: return HouseFront;
	case HouseLeft: return HouseRight;
	case HouseRight: return HouseLeft;
	case HouseUp: return HouseDown;
	case HouseDown: return HouseUp;
	default: return HouseDirNull;
	}
	return HouseDirNull;
}



//==================^_^==================^_^==================^_^==================^_^
bool HouseFourWall::GenTopoBuilding()
{
	if(G_Building.CheckHousePos(this))//没有位置,中断生成
	{
		//判断: 水池上不能建立 广场边界的一半(广场栏杆)上不能建立 
		if(m_parentHouse)m_parentHouse->NotifySubCheckPosFail(this,m_houseDirFromParent);
		return false;
	}

	float spaceMin = 0.5f;//0.1f;
	float spaceMax = 3.0f;//0.3f;

	vec3 newHalfExtend;
	vec3 newPos;
	House* newHouse;

	//只能在某一个方向上扩张,平面状的一幢, 或者只能围绕一个圆形扩张,或者方形扩张城墙,或者根据地图上的区域来扩张
	if (IsGenBreak(HouseFront)==false)
	{
		//随机前后左右的顺序
		//HouseDir genHouseDir[4]={HouseFront,HouseBack,HouseLeft,HouseDirNull};
		HouseDir genHouseDir[4]={HouseFront,HouseBack,HouseLeft,HouseRight};
		//for (int i=0;i<4;i++)
		//{
		//	int n = Rand()%(4-i);
		//	genHouseDir[i] = n;
		//}

		//前后左右
		for (int i=0;i<4;i++)
		{
			//分4次随机方向扩充
			HouseDir genDir = genHouseDir[i];
			if (genDir!=HouseDirNull)
			{
				int type = Rand()%2;
				if (type==0)
				{
					//走廊
					HouseType houseType = House::HouseTypeHallway;
					newHalfExtend.x = G_Building.m_normalHalfExtend.x *RandRange(0.3f,0.6f);
					newHalfExtend.y = G_Building.m_normalHalfExtend.y *RandRange(0.3f,0.6f);
					newHalfExtend.z = G_Building.m_normalHalfExtend.z *RandRange(0.3f,0.6f);
					newHalfExtend += GetDirVector(genDir).Mult(G_Building.m_normalHalfExtend)*RandRange(1.0f,2.0f);

					newPos = m_pos+GetDirVector(genDir).Mult(m_halfExtend + newHalfExtend);
					//走廊底部和本层稍微对齐
					newPos.y -= (m_halfExtend.y-newHalfExtend.y)*0.5f;
					if (m_depthHigh==G_Building.DepthZero)
					{
						newPos.y = newHalfExtend.y+G_Building.GetTerrainHeight(newPos);
					}
					//不能到地下
					if (newPos.y < newHalfExtend.y)
					{
						newPos.y = newHalfExtend.y+G_Building.GetTerrainHeight(newPos);
					}
					newHouse = new HouseHallway;
					newHouse->SetParm(this,newPos,newHalfExtend,houseType,genDir,m_depthLevel+1,m_depthHigh);
					m_subHouse[DirIndex(genDir)] = newHouse;
					G_Building.PushQueue(newHouse);
				}
				else
				{
					//墙体
					HouseType houseType = House::HouseTypeFourWall;
					newHalfExtend.x = G_Building.m_normalHalfExtend.x *RandRange(0.7f,2.3f);
					newHalfExtend.y = G_Building.m_normalHalfExtend.y *RandRange(0.7f,2.3f);
					newHalfExtend.z = G_Building.m_normalHalfExtend.z *RandRange(0.7f,2.3f);
					newPos = m_pos+GetDirVector(genDir).Mult(m_halfExtend + newHalfExtend);
					//底部不需对齐

					if (m_depthHigh==G_Building.DepthZero)
					{
						if (Rand()%2==0)
						{
							//分离胡同
							newPos += GetDirVector(genDir)*(G_Building.m_normalHalfExtend.x*RandRange(spaceMin,spaceMax));
							//错落对齐
							newPos += (GetDirVector(genDir).Cross(vec3(0,1,0))) *(G_Building.m_normalHalfExtend.x*RandRange(spaceMin,spaceMax)*0.2f);
						}
						else
						{
							//错落对齐
							newPos += (GetDirVector(genDir).Cross(vec3(0,1,0))).Mult(newHalfExtend)*RandRange(0.0f,0.5f);
						}
						newPos.y = newHalfExtend.y+G_Building.GetTerrainHeight(newPos);
					}
					else
					{
						//错落对齐
						newPos += (GetDirVector(genDir).Cross(vec3(0,1,0))).Mult(newHalfExtend)*RandRange(0.0f,0.2f);
					}

					//不能到地下
					if (newPos.y < newHalfExtend.y)
					{
						newPos.y = newHalfExtend.y+G_Building.GetTerrainHeight(newPos);
					}
					newHouse = new HouseFourWall;
					newHouse->SetParm(this,newPos,newHalfExtend,houseType,genDir,m_depthLevel+1,m_depthHigh);
					m_subHouse[DirIndex(genDir)] = newHouse;
					G_Building.PushQueue(newHouse);
				}
			}
		}
	}

	if (IsGenBreak(HouseUp)==false)
	{
		//上下
		newHalfExtend.x = m_halfExtend.x *RandRange(1.1f,1.3f);
		newHalfExtend.y = G_Building.m_normalHalfExtend.y *RandRange(0.5f,1.0f);
		newHalfExtend.z = m_halfExtend.z *RandRange(1.1f,1.3f);
		HouseType houseType;
		if(Rand()%2!=0)
		{
			houseType = House::HouseTypeRoof;
			newHouse = new HouseRoof;
			if (IsNextGenBreak(HouseUp)==false)
			{
				//隔板屋顶 矮
				newHalfExtend.y = G_Building.m_normalHalfExtend.y *RandRange(0.2f,0.4f);
			}
		}
		else
		{
			houseType = House::HouseTypeFourWall;
			newHouse = new HouseFourWall;
		}
		newPos.x = m_pos.x;
		newPos.y = m_pos.y + m_halfExtend.y + newHalfExtend.y;
		newPos.z = m_pos.z;
		newHouse->SetParm(this,newPos,newHalfExtend,houseType,HouseUp,m_depthLevel,m_depthHigh+1);
		m_subHouse[DirIndex(HouseUp)] = newHouse;
		G_Building.PushQueue(newHouse);
	}


	if (IsGenBreak(HouseFront)==true || IsGenBreak(HouseUp)==true)
	{
		//fourwall出现在终端(如最高层,最外层),加封屋顶
		//if(Rand()%2==1)
		{
			newHalfExtend.x = m_halfExtend.x *RandRange(1.1f,1.3f);
			newHalfExtend.y = G_Building.m_normalHalfExtend.y *RandRange(0.5f,1.0f);
			newHalfExtend.z = m_halfExtend.z *RandRange(1.1f,1.3f);
			newPos.x = m_pos.x;
			newPos.y = m_pos.y + m_halfExtend.y + newHalfExtend.y;
			newPos.z = m_pos.z;
			HouseType houseType = House::HouseTypeRoof;
			newHouse = new HouseRoof;
			newHouse->SetParm(this,newPos,newHalfExtend,houseType,HouseUp,m_depthLevel,m_depthHigh+1);
			m_subHouse[DirIndex(HouseUp)] = newHouse;
			G_Building.PushQueue(newHouse);
		}
	}

	//柱子不受深度限制
	//[HouseDown]
	if (m_houseDirFromParent!=HouseUp)
	{
		newHalfExtend.x = m_halfExtend.x *RandRange(0.6f,0.7f);
		newHalfExtend.y = (m_pos.y - m_halfExtend.y)/2;
		newHalfExtend.z = m_halfExtend.z *RandRange(0.6f,0.7f);
		newPos.x = m_pos.x;
		newPos.y = m_pos.y - m_halfExtend.y - newHalfExtend.y;
		newPos.z = m_pos.z;
		HouseType houseType = House::HouseTypeColumn;
		newHouse = new HouseColumn;
		newHouse->SetParm(this,newPos,newHalfExtend,houseType,HouseDown,m_depthLevel,m_depthHigh+1);
		m_subHouse[DirIndex(HouseDown)] = newHouse;
		G_Building.PushQueue(newHouse);
	}

	G_Building.AddHouse(this);
	return true;
}

bool HouseFourWall::GenSelfModel()
{
	int doorDir = 0;
	//构造每种开门类型的模版
	//HouseUp    =1,
	//HouseRight =1<<5,
	for (int f=0;f<HouseIndexMax;f++)
	{
		HouseDir dir =(HouseDir) (1<<f);
		if(m_subHouse[DirIndex(dir)]!=NULL /*&& dynamic_cast<HouseHallway*>(m_subHouse[DirIndex(dir)])*/)
		{
			doorDir |= dir;
		}
	}
	if (m_parentHouse)
	{
		//开反面的门
		doorDir |= InverseDir(m_houseDirFromParent);
	}
	if (m_depthHigh==G_Building.DepthZero)
	{
		doorDir |= (1<<(Rand()%6));
	}

	//IndexInt index[36]={};
	//HouseTemplate* boxTemplate = VertexTemplate[BoxSimple];
	HouseTemplate* boxTemplate = VertexTemplate[BoxDoorFront];
	((HouseTemplateDoor*)boxTemplate)->InitDoorDir(doorDir);

	static vec3 vVertexs[108];
	{
		mat4 mat = GetVertexMatrix(m_pos,m_halfExtend*0.99f/*,vec3(0,RandRange(HALFPI,HALFPI)*0.1f,0)*/);
		for (int i=0;i<boxTemplate->vertexNum;i++)
		{
			//缩放
			vVertexs[i] = mat*boxTemplate->VVertexs[i];
		}
	}

	static TVertex tVertexs[108];
	{
		mat4 mat;
		vec3 tcoord;
		bool wallColumn = (Rand()%5==0);
		for (int i=0;i<boxTemplate->vertexNum;i++)
		{
			//每一面墙单独的纹理
			if (boxTemplate->IsVertexBeginDirWithinChange(i,HouseUp))
			{
				mat = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexRoof);
			}
			else if (boxTemplate->IsVertexBeginDirWithinChange(i,HouseDown))
			{
				mat = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexFloor);
			}
			else if (boxTemplate->IsVertexBeginDirWithinChange(i,HouseFront|HouseBack|HouseLeft|HouseRight))
			{
				if (wallColumn)
				{
					//柱子
					mat = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexWallColumn);
				}
				else if (boxTemplate->IsVertexInDir(i,doorDir))
				{
					//门
					mat = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexWallDoor);
				}
				else
				{
					//墙
					mat = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexWall);
				}
			}
			tcoord = vec3(boxTemplate->TVertexs[i].u,boxTemplate->TVertexs[i].v,boxTemplate->TVertexs[i].w);
			tcoord = mat*tcoord;
			tVertexs[i].u = tcoord.x;
			tVertexs[i].v = tcoord.y;
			tVertexs[i].w = tcoord.z;
		}
	}

	bool subUp = (m_subHouse[DirIndex(HouseUp)]!=NULL);
	for (int i=0;i<boxTemplate->vertexNum;i++)
	{
		//往上分的fourwall CheckHousePos()没有位置而中断时会漏掉屋顶?
		//节省顶部的面
		if (subUp && boxTemplate->IsVertexInDir(i,HouseUp))
		{
			continue;
		}
		G_Building.m_vertices[G_Building.m_vVertexNum].x = vVertexs[i].x;
		G_Building.m_vertices[G_Building.m_vVertexNum].y = vVertexs[i].y;
		G_Building.m_vertices[G_Building.m_vVertexNum].z = vVertexs[i].z;
		G_Building.m_vertices[G_Building.m_vVertexNum].u = tVertexs[i].u;
		G_Building.m_vertices[G_Building.m_vVertexNum].v = tVertexs[i].v;
		G_Building.m_vertices[G_Building.m_vVertexNum].w = 1;
		G_Building.m_indexs[G_Building.m_indexNum] = G_Building.m_vVertexNum;
		G_Building.m_indexNum++;
		G_Building.m_vVertexNum++;
	}


	return true;
}

void HouseFourWall::Rend()
{

}


//==================^_^==================^_^==================^_^==================^_^


//==================^_^==================^_^==================^_^==================^_^
bool HouseRoof::GenTopoBuilding()
{
	if(G_Building.CheckHousePos(this))//没有位置,中断生成
	{
		if(m_parentHouse)m_parentHouse->NotifySubCheckPosFail(this,m_houseDirFromParent);
		return false;
	}

	//vec3 newHalfExtend;
	//vec3 newPos;
	//House* newHouse;

	产生亭子 
	//if (IsGenBreak(HouseFront)==false)
	//{
	//	HouseDir genHouseDir[4]={HouseFront,HouseBack,HouseLeft,HouseRight};
	//	//for (int i=0;i<4;i++)
	//	//{
	//	//	int n = Rand()%(4-i);
	//	//	genHouseDir[i] = n;
	//	//}
	//	//前后左右
	//	for (int i=0;i<4;i++)
	//	{
	//		//分4次随机方向扩充
	//		HouseDir genDir = genHouseDir[i];
	//		if (genDir!=HouseDirNull)
	//		{
	//			{
	//				//亭子顶盖
	//				HouseType houseType = House::HouseTypeRoof;
	//				newHalfExtend.x = G_Building.m_normalHalfExtend.x *RandRange(0.7f,2.3f);
	//				newHalfExtend.y = G_Building.m_normalHalfExtend.y *RandRange(0.7f,2.3f);
	//				newHalfExtend.z = G_Building.m_normalHalfExtend.z *RandRange(0.7f,2.3f);
	//				newPos = m_pos+GetDirVector(genDir).Mult(m_halfExtend + newHalfExtend);
	//				//底部不需对齐
	//				{
	//					//错落对齐
	//					newPos += (GetDirVector(genDir).Cross(vec3(0,1,0))).Mult(newHalfExtend)*RandRange(0.0f,0.2f);
	//				}

	//				//不能到地下
	//				if (newPos.y < newHalfExtend.y)
	//				{
	//					newPos.y = newHalfExtend.y+G_Building.GetTerrainHeight();
	//				}
	//				newHouse = new HouseRoof;
	//				newHouse->SetParm(this,newPos,newHalfExtend,houseType,genDir,m_depthLevel+1,m_depthHigh);
	//				m_subHouse[DirIndex(genDir)] = newHouse;
	//				G_Building.PushQueue(newHouse);
	//			}
	//		}
	//	}
	//}


	//不需要上面一个也不是终端,因为fourwall产生屋顶不受depth限制
	if (IsGenBreak(HouseUp)==false)
	{
		vec3 newHalfExtend;
		vec3 newPos;
		House* newHouse;
		//屋顶只能往上加盖类似宝塔
		HouseType houseType = House::HouseTypeFourWall;
		newHalfExtend.x = m_halfExtend.x *RandRange(0.7f,0.9f);
		newHalfExtend.y = G_Building.m_normalHalfExtend.y *RandRange(0.7f,2.3f);
		newHalfExtend.z = m_halfExtend.z *RandRange(0.7f,0.9f);
		newPos.x = m_pos.x;
		newPos.y = m_pos.y + m_halfExtend.y + newHalfExtend.y;
		newPos.z = m_pos.z;
		newHouse = new HouseFourWall;
		newHouse->SetParm(this,newPos,newHalfExtend,houseType,HouseUp,m_depthLevel,m_depthHigh+1);
		m_subHouse[DirIndex(HouseUp)] = newHouse;
		G_Building.PushQueue(newHouse);
	}


	柱子不受深度限制 产生亭子
	[HouseDown]
	//if (m_houseDirFromParent!=HouseUp)
	//{
	//	newHalfExtend.x = m_halfExtend.x *RandRange(0.6f,0.7f);
	//	newHalfExtend.y = (m_pos.y - m_halfExtend.y)/2;
	//	newHalfExtend.z = m_halfExtend.z *RandRange(0.6f,0.7f);
	//	newPos.x = m_pos.x;
	//	newPos.y = m_pos.y - m_halfExtend.y - newHalfExtend.y;
	//	newPos.z = m_pos.z;
	//	HouseType houseType = House::HouseTypeColumn;
	//	newHouse = new HouseColumn;
	//	newHouse->SetParm(this,newPos,newHalfExtend,houseType,HouseDown,m_depthLevel,m_depthHigh+1);
	//	m_subHouse[DirIndex(HouseDown)] = newHouse;
	//	G_Building.PushQueue(newHouse);
	//}

	G_Building.AddHouse(this);
	return true;
}

bool HouseRoof::GenSelfModel()
{
	enum RoofMode
	{
		RoofScaleX = 0,
		RoofScaleZ,
		RoofScaleXZ,
		RoofFence,
		RoofSpace,//非终端 隔板
		RoofModeMax,
	};
	vec2 roofScale[RoofModeMax][2] =
	{
		vec2(0.0f,0.5f),vec2(0.0f,0.5f),
		vec2(0.0f,0.2f),vec2(0.0f,0.9f),
		vec2(0.0f,0.9f),vec2(0.0f,0.2f),
		vec2(1.0f,1.0f),vec2(1.0f,1.0f),
		vec2(0.6f,0.8f),vec2(0.6f,0.8f),
	};

	int roofMode = Rand()%4;
	//不需要上面一个也不是终端,因为fourwall产生屋顶不受depth限制
	if (m_subHouse[DirIndex(HouseUp)]!=NULL)
	{ 
		//非终端 是否一律用housespoace代替?
		roofMode = RoofSpace;
	}

	HouseTemplate* boxTemplate = VertexTemplate[BoxSimple];
	//四角屋顶
	//IndexInt index[36]={};
	vec3 vVertexs[36];
	{
		mat4 mat;
		if (roofMode==RoofFence)
		{
			//栅栏式屋顶矮些
			//纹理是部分无法repeat,只有通过加面来repeat        冲突
			mat = GetVertexMatrix(vec3(m_pos.x,m_pos.y-m_halfExtend.y*0.499f,m_pos.z),
				vec3(m_halfExtend.x*0.9f,m_halfExtend.y*0.5f,m_halfExtend.z*0.9f));
		}
		else
		{
			mat = GetVertexMatrix(m_pos,m_halfExtend);
		}

		float scaleX = RandRange(roofScale[roofMode][0].x,roofScale[roofMode][0].y);
		float scaleZ = RandRange(roofScale[roofMode][1].x,roofScale[roofMode][1].y);

		for (int i=0;i<boxTemplate->vertexNum;i++)
		{
			vVertexs[i] = boxTemplate->VVertexs[i];
			if (vVertexs[i].y==1)
			{
				//收缩顶盖
				vVertexs[i].x *= scaleX;
				vVertexs[i].z *= scaleZ;
			}
		}

		for (int i=0;i<boxTemplate->vertexNum;i++)
		{
			//缩放
			vVertexs[i] = mat*vVertexs[i];
		}
	}

	TVertex tVertexs[36];
	{
		vec3 tcoord;
		if (roofMode==RoofFence)
		{
			//栅栏式屋顶底部是地板
			mat4 matf = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexFence);
			mat4 matfl = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexFloor);
			for (int i=0;i<boxTemplate->vertexNum;i++)
			{
				tcoord = vec3(boxTemplate->TVertexs[i].u,boxTemplate->TVertexs[i].v,boxTemplate->TVertexs[i].w);
				if (boxTemplate->IsVertexInDir(i,HouseDown))
				{
					tcoord = matfl*tcoord;
				}
				else
				{
					tcoord = matf*tcoord;
				}
				tVertexs[i].u = tcoord.x;
				tVertexs[i].v = tcoord.y;
				tVertexs[i].w = tcoord.z;
			}
		}
		else
		{
			mat4 mat = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexRoof);
			for (int i=0;i<boxTemplate->vertexNum;i++)
			{
				屋脊
				//if (i==6)
				//{
				//	mat = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexRoof);
				//}
				tcoord = vec3(boxTemplate->TVertexs[i].u,boxTemplate->TVertexs[i].v,boxTemplate->TVertexs[i].w);
				tcoord = mat*tcoord;
				tVertexs[i].u = tcoord.x;
				tVertexs[i].v = tcoord.y;
				tVertexs[i].w = tcoord.z;
			}
		}
	}


	for (int i=0;i<boxTemplate->vertexNum;i++)
	{
		if(roofMode==RoofFence || roofMode==RoofSpace)
		{
			//栅栏式屋顶 剔除up
			if (boxTemplate->IsVertexInDir(i,HouseUp))
			{
				continue;
			}
		}
		G_Building.m_vertices[G_Building.m_vVertexNum].x = vVertexs[i].x;
		G_Building.m_vertices[G_Building.m_vVertexNum].y = vVertexs[i].y;
		G_Building.m_vertices[G_Building.m_vVertexNum].z = vVertexs[i].z;
		G_Building.m_vertices[G_Building.m_vVertexNum].u = tVertexs[i].u;
		G_Building.m_vertices[G_Building.m_vVertexNum].v = tVertexs[i].v;
		G_Building.m_vertices[G_Building.m_vVertexNum].w = 1;
		G_Building.m_indexs[G_Building.m_indexNum] = G_Building.m_vVertexNum;
		G_Building.m_indexNum++;
		G_Building.m_vVertexNum++;
	}


	return true;
}

void HouseRoof::Rend()
{

}

bool HouseRoof::GenNavgation()
{
	if (m_subHouse[HouseUp]==NULL)
	{
		return false;
	}
	return House::GenNavgation();
}


//==================^_^==================^_^==================^_^==================^_^

//==================^_^==================^_^==================^_^==================^_^
bool HouseColumn::GenTopoBuilding()
{
	//if(G_Building.CheckHousePos(this))//没有位置,中断生成
	//{
	//	if(m_parentHouse)m_parentHouse->NotifySubCheckPosFail(this,m_houseDirFromParent);
	//	return false;
	//}

	//if (m_depthHigh<MaxDepthHeight)
	//{
	//	vec3 newHalfExtend;
	//	vec3 newPos;
	//	House* newHouse;
	//	//[HouseUp]
	//	{
	//		//屋顶只能往上加盖类似宝塔
	//		HouseType houseType = House::HouseTypeFourWall;
	//		newHalfExtend.x = m_halfExtend.x *RandRange(0.7f,0.9f);
	//		newHalfExtend.y = G_Building.m_normalHalfExtend.y *RandRange(0.7f,2.3f);
	//		newHalfExtend.z = m_halfExtend.z *RandRange(0.7f,0.9f);
	//		newPos.x = m_pos.x;
	//		newPos.y = m_pos.y + m_halfExtend.y + newHalfExtend.y;
	//		newPos.z = m_pos.z;
	//		newHouse = new HouseFourWall;
	//		newHouse->SetParm(newPos,newHalfExtend,houseType,m_depthLevel,m_depthHigh+1);
	//		G_Building.PushQueue(newHouse);
	//	}
	//}
	G_Building.AddHouse(this);
	return true;
}

bool HouseColumn::GenSelfModel()
{
	float colloid = 0.5;//1.4f;
	vec3 tempExtend(m_halfExtend.x*0.1f,m_halfExtend.y,m_halfExtend.z*0.1f);
	vec3 clloidExtend(m_halfExtend.x*colloid,m_halfExtend.y*0.8f,m_halfExtend.z*colloid);
	//四个角向下没有house则建立柱子
	vec3 posOffset[4] = 
	{
		vec3(1,0,1),
		vec3(1,0,-1),
		vec3(-1,0,1),
		vec3(-1,0,-1),
	};

	bool checkPos[4];
	{
		bool haveColumn = false;
		for (int i=0;i<4;i++)
		{
			vec3 tempPos = m_pos+m_halfExtend.Mult(posOffset[i]);
			Box newBound(tempPos,clloidExtend);
			//if (1)
			if (G_Building.CheckBound(&newBound,this)==false)
			{
				haveColumn = true;
				checkPos[i] = true;
			}
			else
			{
				checkPos[i] = false;
			}
		}
		if(haveColumn==false)
		{
			return false;
		}
	}

	//if(G_Building.CheckHousePos(this))
	//{
	//	return false;
	//}

	HouseTemplate* boxTemplate = VertexTemplate[BoxSimple];

	TVertex tVertexs[36];
	{
		mat4 mat = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexColumn);
		vec3 tcoord;
		for (int i=0;i<boxTemplate->vertexNum;i++)
		{
			tcoord = vec3(boxTemplate->TVertexs[i].u,boxTemplate->TVertexs[i].v,boxTemplate->TVertexs[i].w);
			tcoord = mat*tcoord;
			tVertexs[i].u = tcoord.x;
			tVertexs[i].v = tcoord.y;
			tVertexs[i].w = tcoord.z;
		}
	}

	//==================^_^
	//IndexInt index[36]={};
	vec3 vVertexs[36];
	//四个角向下没有house则建立柱子
	for (int i=0;i<4;i++)
	{
		vec3 tempPos = m_pos+m_halfExtend.Mult(posOffset[i]);
		if (checkPos[i])
		{
			mat4 mat = GetVertexMatrix(tempPos,tempExtend);
			for (int i=0;i<boxTemplate->vertexNum;i++)
			{
				//缩放
				vVertexs[i] = mat*boxTemplate->VVertexs[i];
			}

			for (int i=0;i<boxTemplate->vertexNum;i++)
			{
				if (boxTemplate->IsVertexInDir(i,HouseUp|HouseDown))
				{
					continue;
				}
				G_Building.m_vertices[G_Building.m_vVertexNum].x = vVertexs[i].x;
				G_Building.m_vertices[G_Building.m_vVertexNum].y = vVertexs[i].y;
				G_Building.m_vertices[G_Building.m_vVertexNum].z = vVertexs[i].z;
				G_Building.m_vertices[G_Building.m_vVertexNum].u = tVertexs[i].u;
				G_Building.m_vertices[G_Building.m_vVertexNum].v = tVertexs[i].v;
				G_Building.m_vertices[G_Building.m_vVertexNum].w = 1;
				G_Building.m_indexs[G_Building.m_indexNum] = G_Building.m_vVertexNum;
				G_Building.m_indexNum++;
				G_Building.m_vVertexNum++;
			}
		}
	}


	return true;
}

void HouseColumn::Rend()
{

}

bool HouseColumn::GenNavgation()
{
	return false;
}


//==================^_^==================^_^==================^_^==================^_^
//==================^_^==================^_^==================^_^==================^_^
bool HouseHallway::GenTopoBuilding()
{
	if(G_Building.CheckHousePos(this))//没有位置,中断生成
	{
		if(m_parentHouse)m_parentHouse->NotifySubCheckPosFail(this,m_houseDirFromParent);
		return false;
	}

	if (IsGenBreak(HouseFront)==false)
	{
		vec3 newHalfExtend;
		vec3 newPos;
		House* newHouse;

		//只能向m_houseDir方向扩充
		HouseDir genDir = m_houseDirFromParent;
		if (genDir!=HouseDirNull)
		{
			//墙体
			HouseType houseType = House::HouseTypeFourWall;
			newHalfExtend.x = G_Building.m_normalHalfExtend.x *RandRange(0.7f,2.3f);
			newHalfExtend.y = G_Building.m_normalHalfExtend.y *RandRange(0.7f,2.3f);
			newHalfExtend.z = G_Building.m_normalHalfExtend.z *RandRange(0.7f,2.3f);
			newPos = m_pos+GetDirVector(genDir).Mult(m_halfExtend + newHalfExtend);
			//走廊底部和下层稍微对齐
			//newPos.y -= (m_halfExtend.y-newHalfExtend.y)*0.5f;

			if (m_depthHigh==G_Building.DepthZero)
			{
				newPos.y = newHalfExtend.y+G_Building.GetTerrainHeight(newPos);
			}
			//不能到地下
			if (newPos.y < newHalfExtend.y)
			{
				newPos.y = newHalfExtend.y+G_Building.GetTerrainHeight(newPos);
			}
			newHouse = new HouseFourWall;
			newHouse->SetParm(this,newPos,newHalfExtend,houseType,genDir,m_depthLevel+1,m_depthHigh);
			m_subHouse[DirIndex(genDir)] = newHouse;
			G_Building.PushQueue(newHouse);
		}

		[HouseDown] 柱子
		//{
		//	newHalfExtend.x = m_halfExtend.x *RandRange(0.6f,0.7f);
		//	newHalfExtend.y = (m_pos.y - m_halfExtend.y)/2;
		//	newHalfExtend.z = m_halfExtend.z *RandRange(0.6f,0.7f);
		//	newPos.x = m_pos.x;
		//	newPos.y = m_pos.y - m_halfExtend.y - newHalfExtend.y;
		//	newPos.z = m_pos.z;
		//	HouseType houseType = House::HouseTypeColumn;
		//	newHouse = new HouseColumn;

		//	newHouse->SetParm(newPos,newHalfExtend,houseType,HouseDown,m_depthLevel,m_depthHigh+1);
		//	G_Building.PushQueue(newHouse);
		//}
	}

	G_Building.AddHouse(this);
	return true;
}

bool HouseHallway::GenSelfModel()
{
	HouseTemplate* boxTemplate = VertexTemplate[BoxSimple];

	//IndexInt index[36]={};
	vec3 vVertexs[36];
	{
		mat4 mat = GetVertexMatrix(m_pos,m_halfExtend);
		for (int i=0;i<boxTemplate->vertexNum;i++)
		{
			//缩放
			vVertexs[i] = mat*boxTemplate->VVertexs[i];
		}
	}

	TVertex tVertexs[36];
	{
		mat4 matfen = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexFence);
		mat4 matr = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexRoof);
		mat4 matfl = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexFloor);
		vec3 tcoord;
		for (int i=0;i<boxTemplate->vertexNum;i++)
		{
			tcoord = vec3(boxTemplate->TVertexs[i].u,boxTemplate->TVertexs[i].v,boxTemplate->TVertexs[i].w);

			//相同的走廊纹理,两侧面相同
			if (boxTemplate->IsVertexInDir(i,HouseUp))
			{
				tcoord = matr*tcoord;
			}
			else if (boxTemplate->IsVertexInDir(i,HouseDown))
			{
				tcoord = matfl*tcoord;
			}
			else 
			{
				tcoord = matfen*tcoord;
			}
			tVertexs[i].u = tcoord.x;
			tVertexs[i].v = tcoord.y;
			tVertexs[i].w = tcoord.z;
		}
	}


	bool skipUp = true;
	//如果太矮就不加顶盖
	if (m_halfExtend.y > G_Building.m_normalHalfExtend.y *0.45f)
	{
		skipUp = (Rand()%2!=0);
	}

	for (int i=0;i<boxTemplate->vertexNum;i++)
	{
		//节省顶部的面
		if (skipUp)
		{
			if (boxTemplate->IsVertexInDir(i,HouseUp))
			{
				continue;
			}
		}
		//去掉走廊两端的面
		if (m_houseDirFromParent==HouseLeft||m_houseDirFromParent==HouseRight)
		{
			if (boxTemplate->IsVertexInDir(i,HouseLeft|HouseRight))
			{
				continue;
			}
		}
		else if (m_houseDirFromParent==HouseFront||m_houseDirFromParent==HouseBack)
		{
			if (boxTemplate->IsVertexInDir(i,HouseFront|HouseBack))
			{
				continue;
			}
		}
		G_Building.m_vertices[G_Building.m_vVertexNum].x = vVertexs[i].x;
		G_Building.m_vertices[G_Building.m_vVertexNum].y = vVertexs[i].y;
		G_Building.m_vertices[G_Building.m_vVertexNum].z = vVertexs[i].z;
		G_Building.m_vertices[G_Building.m_vVertexNum].u = tVertexs[i].u;
		G_Building.m_vertices[G_Building.m_vVertexNum].v = tVertexs[i].v;
		G_Building.m_vertices[G_Building.m_vVertexNum].w = 1;
		G_Building.m_indexs[G_Building.m_indexNum] = G_Building.m_vVertexNum;
		G_Building.m_indexNum++;
		G_Building.m_vVertexNum++;
	}


	return true;
}

void HouseHallway::Rend()
{

}

bool HouseHallway::IsGenBreak(HouseDir dir)
{
	//switch(dir)
	//{
	//case HouseDirNull:
	//	break;
	//case HouseDown:
	//case HouseUp:
	//	if (m_depthHigh>=MaxDepthHeight)
	//	{
	//		return true;
	//	}
	//default:
	//	if (m_depthLevel>=MaxDepthLevel)
	//	{
	//		return true;
	//	}
	//}
	//终端封口
	return false;
}

//==================^_^==================^_^==================^_^==================^_^
HouseSquare::HouseSquare()
{
	for (int f=0;f<HouseIndexMax;f++)
	{
		m_skipFace[f] = false;
	}
	m_bWall = false;
	m_bWater = false;
}

bool HouseSquare::GenTopoBuilding()
{
	if(G_Building.CheckHousePos(this))//没有位置,中断生成
	{
		if(m_parentHouse)m_parentHouse->NotifySubCheckPosFail(this,m_houseDirFromParent);
		return false;
	}


	{
		if (m_houseDirFromParent!=HouseDown)
		{
			vec3 newPos = m_pos+GetDirVector(HouseUp).Mult(m_halfExtend*2);
			vec3 newHalfExtend = m_halfExtend*0.8f;
			Box bound(newPos,newHalfExtend);
			House* house = G_Building.CheckBound(&bound,this);
			if (!(house /*&& dynamic_cast<HouseSquare*>(house)*/))
			{
				//上面没有square
				//if (m_depthHigh!=G_Building.DepthZero && dynamic_cast<HouseFourWall*>(house))
				//{
				//	Assert(0,"上面没有square");
				//}

				if (m_parentHouse 
					&& dynamic_cast<HouseSquare*>(m_parentHouse)
					&& (dynamic_cast<HouseSquare*>(m_parentHouse))->m_bWater)
				{
					//m_bWater = (Rand()%2==0);
					m_bWater = (Rand()%3!=0);
				}
				else
				{
					m_bWater = (Rand()%8==0);
				}
			}
		}
	}

	vec3 newHalfExtend;
	vec3 newPos;
	HouseSquare* newHouse;

	//只能在某一个方向上扩张,平面状的一幢, 或者只能围绕一个圆形扩张,或者方形扩张城墙,或者根据地图上的区域来扩张
	if (IsGenBreak(HouseFront)==false && m_bWall==false)
	{
		//随机前后左右的顺序
		//HouseDir genHouseDir[4]={HouseFront,HouseBack,HouseLeft,HouseDirNull};
		HouseDir genHouseDir[4]={HouseFront,HouseBack,HouseLeft,HouseRight};
		//for (int i=0;i<4;i++)
		//{
		//	int n = Rand()%(4-i);
		//	genHouseDir[i] = n;
		//}

		//前后左右
		for (int i=0;i<4;i++)
		{
			//if (IsGenBreak(HouseFront)==true) //效果不好
			//	continue;

			//分4次随机方向扩充
			HouseDir genDir = genHouseDir[i];
			if (genDir!=HouseDirNull)
			{
				//{
				//	//预排除提高效率
				//	vec3 newPos = m_pos+GetDirVector(genDir).Mult(m_halfExtend*2);
				//	vec3 newHalfExtend = m_halfExtend*0.8f;
				//	Box bound(newPos,newHalfExtend);
				//	House* house = G_Building.CheckBound(&bound,this);
				//	if (house) 
				//	{
				//		continue;
				//	}
				//}
				//墙体
				HouseType houseType = House::HouseTypeSquare;
				newHalfExtend = m_halfExtend;
				newPos = m_pos+GetDirVector(genDir).Mult(m_halfExtend + newHalfExtend);
				newHouse = new HouseSquare;
				newHouse->SetParm(this,newPos,newHalfExtend,houseType,genDir,m_depthLevel+1,m_depthHigh);
				m_subHouse[DirIndex(genDir)] = newHouse;
				//m_skipFace[DirIndex(genDir)] = true;
				//newHouse->m_skipFace[DirIndex(InverseDir(genDir))] = true;
				G_Building.PushQueue(newHouse);
			}
		}
	}
	//else //块太大
	//{
	//	//水平中断 , 边上加城墙
	//	if(m_bWall)
	//	{
	//		//往上
	//		HouseType houseType = House::HouseTypeSquare;
	//		newHalfExtend = m_halfExtend;
	//		newPos = m_pos+GetDirVector(HouseDown).Mult(m_halfExtend + newHalfExtend);
	//		newHouse = new HouseSquare;
	//		newHouse->SetParm(this,newPos,newHalfExtend,houseType,HouseDown,m_depthLevel,m_depthHigh+1);
	//		m_subHouse[DirIndex(HouseDown)] = newHouse;
	//		G_Building.PushQueue(newHouse);
	//	}
	//	//底部边界
	//	if (IsGenBreak(HouseDown)==true)
	//	{
	//		m_bWall = true;
	//		House* up = this;
	//		while (up->m_houseDirFromParent==House::HouseDown)
	//		{
	//			up = up->m_parentHouse;
	//		}
	//		//往上
	//		HouseType houseType = House::HouseTypeSquare;
	//		newHalfExtend = m_halfExtend;
	//		newPos = m_pos+GetDirVector(HouseDown).Mult(m_halfExtend + newHalfExtend);
	//		newHouse = new HouseSquare;
	//		newHouse->SetParm(this,newPos,newHalfExtend,houseType,HouseDown,m_depthLevel,m_depthHigh+1);
	//		m_subHouse[DirIndex(HouseDown)] = newHouse;
	//		G_Building.PushQueue(newHouse);
	//	}
	//}

	if (IsGenBreak(HouseDown)==false)
	{
		//必往下
		HouseType houseType = House::HouseTypeSquare;
		newHalfExtend = m_halfExtend;
		newPos = m_pos+GetDirVector(HouseDown).Mult(m_halfExtend + newHalfExtend);
		newHouse = new HouseSquare;
		newHouse->SetParm(this,newPos,newHalfExtend,houseType,HouseDown,m_depthLevel,m_depthHigh+1);
		m_subHouse[DirIndex(HouseDown)] = newHouse;
		G_Building.PushQueue(newHouse);
	}

	//台阶
	if((m_subHouse[DirIndex(HouseUp)]==NULL))
	{
		int r = 2;
		HouseDir stepsDir = HouseDirNull;
		vec3 newHalfExtend = m_halfExtend;
		if ((m_subHouse[DirIndex(HouseFront)]==NULL) && stepsDir == HouseDirNull && (Rand()%r==0))
		{
			stepsDir = HouseFront;
			newHalfExtend.z *= 0.5f;
		}
		else if ((m_subHouse[DirIndex(HouseBack)]==NULL) && stepsDir == HouseDirNull && (Rand()%r==0))
		{
			stepsDir = HouseBack;
			newHalfExtend.z *= 0.5f;
		}
		else if ((m_subHouse[DirIndex(HouseLeft)]==NULL) && stepsDir == HouseDirNull && (Rand()%r==0))
		{
			stepsDir = HouseLeft;
			newHalfExtend.x *= 0.5f;
		}
		else if ((m_subHouse[DirIndex(HouseRight)]==NULL) && stepsDir == HouseDirNull && (Rand()%r==0))
		{
			stepsDir = HouseRight;
			newHalfExtend.x *= 0.5f;
		}

		if (stepsDir != HouseDirNull)
		{
			//newHalfExtend -= newHalfExtend.Mult(GetDirVector(stepsDir)*0.5f);
			vec3 newPos = m_pos+GetDirVector(stepsDir).Mult(m_halfExtend + newHalfExtend);
			HouseSteps* newHouse = new HouseSteps;
			newHouse->SetParm(this,newPos,newHalfExtend,House::HouseTypeSteps,stepsDir,m_depthLevel+1,m_depthHigh);
			m_subHouse[DirIndex(stepsDir)] = newHouse;
			G_Building.PushQueue(newHouse);
		}

	}

	G_Building.AddHouse(this);
	return true;
}

bool HouseSquare::GenSelfModel()
{
	{
		vec3 newPos;
		vec3 newHalfExtend;

		//
		newPos = m_pos+GetDirVector(HouseUp).Mult(m_halfExtend*2);
		newHalfExtend = m_halfExtend*0.8f;
		Box bound(newPos,newHalfExtend);
		House* house = G_Building.CheckBound(&bound,this);
		if (house) 
		{
			//上面非台阶
			HouseSquare* houseSquare = dynamic_cast<HouseSquare*>(house);
			if (houseSquare)
			{
				m_skipFace[HouseUpIndex] = true;
				m_bWater = false;
			}
		}

		for (int f=HouseFrontIndex;f<=HouseRightIndex;f++)
		{
			HouseDir dir = (HouseDir)(1<<f);
			newPos = m_pos+GetDirVector(dir).Mult(m_halfExtend*2);
			newHalfExtend = m_halfExtend*0.8f;
			Box bound(newPos,newHalfExtend);
			House* house = G_Building.CheckBound(&bound,this);
			if (house) 
			{
				//侧面非台阶
				HouseSquare* houseSquare = dynamic_cast<HouseSquare*>(house);
				if (houseSquare && houseSquare->m_bWater==m_bWater)
				{
					m_skipFace[DirIndex(dir)] = true;
				}
			}
			if (dynamic_cast<HouseSteps*>(m_subHouse[DirIndex(dir)])) 
			{
				//派生台阶则过滤, 台阶入口
				m_skipFace[DirIndex(dir)] = true;
			}
		}
	}
	///

	HouseTemplate* boxTemplate = VertexTemplate[BoxSimple];

	static vec3 vVertexs[36];
	{
		mat4 mat = GetVertexMatrix(m_pos,m_halfExtend/*,vec3(0,RandRange(HALFPI,HALFPI)*0.1f,0)*/);
		vec3 temp;
		for (int i=0;i<boxTemplate->vertexNum;i++)
		{
			if (boxTemplate->IsVertexInDir(i,HouseFront|HouseBack|HouseLeft|HouseRight)
				&& m_houseDirFromParent!=HouseDown)//解决冲突
			{
				//侧面拉高形成栏杆
				temp = boxTemplate->VVertexs[i];
				if(temp.y == 1) temp.y = 1.8f;//2;
				vVertexs[i] = mat*temp;
			}
			else
			{
				//缩放
				vVertexs[i] = mat*boxTemplate->VVertexs[i];
			}
		}
	}

	static TVertex tVertexs[36];
	{
		mat4 matUp = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexFloor,(m_depthHigh%2));
		static mat4 matDown = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexWater,0);
		static mat4 matLeft = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexFence,2);
		vec3 tcoord;
		for (int i=0;i<boxTemplate->vertexNum;i++)
		{
			tcoord = vec3(boxTemplate->TVertexs[i].u,boxTemplate->TVertexs[i].v,boxTemplate->TVertexs[i].w);
			//每一面墙单独的纹理
			if (boxTemplate->IsVertexInDir(i,HouseUp))
			{
				tcoord = matUp*tcoord;
			}
			else if (boxTemplate->IsVertexInDir(i,HouseDown))
			{
				tcoord = matDown*tcoord;
			}
			else 
			{
				//墙
				tcoord = matLeft*tcoord;
			}
			tVertexs[i].u = tcoord.x;
			tVertexs[i].v = tcoord.y;
			tVertexs[i].w = tcoord.z;
		}
	}


	for (int i=0;i<boxTemplate->vertexNum;i++)
	{
		if (m_bWater)
		{
			//节省顶部的面
			if (boxTemplate->IsVertexInDir(i,HouseUp))
			{
				continue;
			}
		}
		else
		{
			//节省顶部的面
			if ((m_skipFace[DirIndex(HouseUp)]/*m_houseDirFromParent==HouseDown*//*m_subHouse[DirIndex(HouseUp)]!=NULL*/) 
				&& boxTemplate->IsVertexInDir(i,HouseUp))
			{
				continue;
			}
			if (boxTemplate->IsVertexInDir(i,HouseDown))
			{
				continue;
			}
		}

		if ((m_skipFace[DirIndex(HouseFront)]) && boxTemplate->IsVertexInDir(i,HouseFront))
		{
			continue;
		}
		if ((m_skipFace[DirIndex(HouseBack)]) && boxTemplate->IsVertexInDir(i,HouseBack))
		{
			continue;
		}
		if ((m_skipFace[DirIndex(HouseLeft)]) && boxTemplate->IsVertexInDir(i,HouseLeft))
		{
			continue;
		}
		if ((m_skipFace[DirIndex(HouseRight)]) && boxTemplate->IsVertexInDir(i,HouseRight))
		{
			continue;
		}

		G_Building.m_vertices[G_Building.m_vVertexNum].x = vVertexs[i].x;
		G_Building.m_vertices[G_Building.m_vVertexNum].y = vVertexs[i].y;
		G_Building.m_vertices[G_Building.m_vVertexNum].z = vVertexs[i].z;
		G_Building.m_vertices[G_Building.m_vVertexNum].u = tVertexs[i].u;
		G_Building.m_vertices[G_Building.m_vVertexNum].v = tVertexs[i].v;
		G_Building.m_vertices[G_Building.m_vVertexNum].w = 1;
		G_Building.m_indexs[G_Building.m_indexNum] = G_Building.m_vVertexNum;
		G_Building.m_indexNum++;
		G_Building.m_vVertexNum++;
	}

	/+ decal
	bool toDecal = false;
	if (m_bWater)
	{
		toDecal = Rand()%2;
	}
	else
	{
		toDecal = (Rand()%4==0);
	}
	if (toDecal)
	{
		{
			mat4 mat = GetVertexMatrix(m_pos,m_halfExtend.Mult(vec3(RandRange(0.5f,1.0f),1,RandRange(0.5f,1.0f))),vec3(0,RandRange(-HALFPI,HALFPI),0));
			vec3 temp;
			for (int i=0;i<boxTemplate->vertexNum;i++)
			{
				if (boxTemplate->IsVertexInDir(i,HouseUp)
					&& m_houseDirFromParent!=HouseDown)//解决冲突
				{
					temp = boxTemplate->VVertexs[i];
					if (m_bWater)
					{
						temp.y = - 0.5f;
					}
					else
					{
						temp.y = 1.001f;
					}
					//缩放
					vVertexs[i] = mat*temp;
				}
			}
		}
		{
			mat4 matDecal;
			if (m_bWater)
			{
				matDecal = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexDecalWater);
			}
			else
			{
				matDecal = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexDecalFloor);
			}
			vec3 tcoord;
			for (int i=0;i<boxTemplate->vertexNum;i++)
			{
				tcoord = vec3(boxTemplate->TVertexs[i].u,boxTemplate->TVertexs[i].v,boxTemplate->TVertexs[i].w);
				if (boxTemplate->IsVertexInDir(i,HouseUp))
				{
					tcoord = matDecal*tcoord;
				}
				tVertexs[i].u = tcoord.x;
				tVertexs[i].v = tcoord.y;
				tVertexs[i].w = tcoord.z;
			}
		}

		for (int i=0;i<boxTemplate->vertexNum;i++)
		{
			if (m_bWater)
			{
				//非顶部的面
				if (!boxTemplate->IsVertexInDir(i,HouseUp))
				{
					continue;
				}
			}
			else
			{
				//非顶部的面
				if ((m_skipFace[DirIndex(HouseUp)]==true) 
					|| (!boxTemplate->IsVertexInDir(i,HouseUp)))
				{
					continue;
				}
			}

			G_Building.m_vertices[G_Building.m_vVertexNum].x = vVertexs[i].x;
			G_Building.m_vertices[G_Building.m_vVertexNum].y = vVertexs[i].y;
			G_Building.m_vertices[G_Building.m_vVertexNum].z = vVertexs[i].z;
			G_Building.m_vertices[G_Building.m_vVertexNum].u = tVertexs[i].u;
			G_Building.m_vertices[G_Building.m_vVertexNum].v = tVertexs[i].v;
			G_Building.m_vertices[G_Building.m_vVertexNum].w = 1;
			G_Building.m_indexs[G_Building.m_indexNum] = G_Building.m_vVertexNum;
			G_Building.m_indexNum++;
			G_Building.m_vVertexNum++;
		}
	}






	//if((m_subHouse[DirIndex(HouseUp)]==NULL))
	//{
	//	int r = 3;
	//	HouseDir stepsDir = HouseDirNull;
	//	vec3 newHalfExtend = m_halfExtend;
	//	if ((m_subHouse[DirIndex(HouseFront)]==NULL) && stepsDir == HouseDirNull && (Rand()%r==0))
	//	{
	//		stepsDir = HouseFront;
	//		newHalfExtend.z *= 0.5f;
	//	}
	//	else if ((m_subHouse[DirIndex(HouseBack)]==NULL) && stepsDir == HouseDirNull && (Rand()%r==0))
	//	{
	//		stepsDir = HouseBack;
	//		newHalfExtend.z *= 0.5f;
	//	}
	//	else if ((m_subHouse[DirIndex(HouseLeft)]==NULL) && stepsDir == HouseDirNull && (Rand()%r==0))
	//	{
	//		stepsDir = HouseLeft;
	//		newHalfExtend.x *= 0.5f;
	//	}
	//	else if ((m_subHouse[DirIndex(HouseRight)]==NULL) && stepsDir == HouseDirNull && (Rand()%r==0))
	//	{
	//		stepsDir = HouseRight;
	//		newHalfExtend.x *= 0.5f;
	//	}

	//	if (stepsDir != HouseDirNull)
	//	{
	//		//newHalfExtend -= newHalfExtend.Mult(GetDirVector(stepsDir)*0.5f);
	//		vec3 newPos = m_pos+GetDirVector(stepsDir).Mult(m_halfExtend + newHalfExtend);
	//		HouseSteps houseSteps;
	//		houseSteps.SetParm(this,newPos,newHalfExtend,House::HouseTypeSteps,stepsDir,m_depthLevel,m_depthHigh+1);
	//		houseSteps.GenSelfModel();
	//	}

	//}
	return true;
}



void HouseSquare::Rend()
{

}

bool HouseSquare::IsGenBreak(HouseDir dir)
{
	switch(dir)
	{
	case HouseDirNull:
		break;
	case HouseDown:
	case HouseUp:
		if (m_depthHigh>=G_Building.MaxSquareDepthHeight)
		{
			return true;
		}
		break;
	default:
		if (m_depthLevel>=G_Building.MaxSquareDepthLevel*3)
		{
			return true;
		}
		else if (m_depthLevel>=G_Building.MaxSquareDepthLevel)
		{
			return (Rand()%2==0);
		}
		else
		{
			return false;
		}
		break;
	}
	return false;
}

bool HouseSquare::GenNavgation()
{
	//if (m_parentHouse)
	//{
	//	if ((m_subHouse[DirIndex(HouseUp)]==NULL))
	//	{
	//		vec3 start = m_parentHouse->m_pos;//-vec3(0,1,0)*m_parentHouse->m_halfExtend*0.9f;
	//		vec3 end = m_pos;//-vec3(0,1,0)*m_halfExtend*0.9f;
	//		G_Building.m_wayEdges[G_Building.m_wayEdgesNum].start = start;
	//		G_Building.m_wayEdges[G_Building.m_wayEdgesNum].end = end;
	//		G_Building.m_wayEdgesNum++;
	//	}
	//	return true;
	//}
	return false;
}


//==================^_^==================^_^==================^_^==================^_^
void HouseSteps::Rend()
{

}

bool HouseSteps::GenTopoBuilding()
{
	if(G_Building.CheckHousePos(this))//没有位置,中断生成
	{
		if(m_parentHouse)m_parentHouse->NotifySubCheckPosFail(this,m_houseDirFromParent);
		return false;
	}

	vec3 newHalfExtend;
	vec3 newPos;
	House* newHouse;
	if (IsGenBreak(HouseDown)==false)
	{
		//广场台阶
		//下
		HouseType houseType = House::HouseTypeSquare;
		newHalfExtend = m_halfExtend;
		newPos = m_pos+GetDirVector(HouseDown).Mult(m_halfExtend + newHalfExtend);
		if (m_houseDirFromParent==HouseFront||m_houseDirFromParent==HouseBack)
		{
			newHalfExtend.z *= 2.0f;
			newPos += m_halfExtend.Mult(GetDirVector(m_houseDirFromParent));
		}
		else if (m_houseDirFromParent==HouseLeft||m_houseDirFromParent==HouseRight)
		{
			newHalfExtend.x *= 2.0f;
			newPos += m_halfExtend.Mult(GetDirVector(m_houseDirFromParent));
		}
		newHouse = new HouseSquare;
		newHouse->SetParm(this,newPos,newHalfExtend,houseType,HouseDown,m_depthLevel,m_depthHigh+1);
		m_subHouse[DirIndex(HouseDown)] = newHouse;
		G_Building.PushQueue(newHouse);
	}

	G_Building.AddHouse(this);
	return true;
}

bool HouseSteps::GenSelfModel()
{
	enum StepsMode
	{
		HandrailNull,
		HandrailLevel,
		HandrailRise,
	};
	HouseTemplate* boxTemplate = VertexTemplate[BoxSimple];

	static vec3 vVertexs[36];
	{
		//mat4 mat = GetVertexMatrix(m_pos,m_halfExtend/*,vec3(0,RandRange(HALFPI,HALFPI)*0.1f,0)*/);
		mat4 mat = GetVertexMatrix(m_pos,m_halfExtend*0.99f); //避免冲突
		vec3 temp;
		for (int i=0;i<boxTemplate->vertexNum;i++)
		{
			temp = boxTemplate->VVertexs[i];

			if (boxTemplate->IsVertexInDir(i,m_houseDirFromParent) && boxTemplate->VVertexs[i].y==1)
			{
				//对侧面拉斜坡
				switch(m_houseDirFromParent)
				{
				case HouseFront:temp.z=-1;break;
				case HouseBack: temp.z=1;break;
				case HouseLeft: temp.x=1;break;
				case HouseRight:temp.x=-1;break;
				}
			}
			else if (boxTemplate->IsVertexInDir(i,HouseFront|HouseBack|HouseLeft|HouseRight))
			{
				//提高扶手
				//if (boxTemplate->VVertexs[i].y==1)temp.y=2;
			}

			//缩放
			vVertexs[i] = mat*temp;
		}
	}

	static TVertex tVertexs[36];
	{
		mat4 matUp = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexSteps,0);
		mat4 matLeft = G_Building.m_buildingDef->GetTextureMatrix(BuildingDef::TexFence);
		vec3 tcoord;
		for (int i=0;i<boxTemplate->vertexNum;i++)
		{
			tcoord = vec3(boxTemplate->TVertexs[i].u,boxTemplate->TVertexs[i].v,boxTemplate->TVertexs[i].w);
			if (boxTemplate->IsVertexInDir(i,m_houseDirFromParent))
			{
				tcoord = matUp*tcoord;
			}
			else 
			{
				//扶手
				tcoord = matLeft*tcoord;
			}
			tVertexs[i].u = tcoord.x;
			tVertexs[i].v = tcoord.y;
			tVertexs[i].w = tcoord.z;
		}
	}


	for (int i=0;i<boxTemplate->vertexNum;i++)
	{
		if (boxTemplate->IsVertexInDir(i,HouseDown|HouseUp))
		{
			continue;
		}
		if (boxTemplate->IsVertexInDir(i,InverseDir(m_houseDirFromParent)))
		{
			continue;
		}
		G_Building.m_vertices[G_Building.m_vVertexNum].x = vVertexs[i].x;
		G_Building.m_vertices[G_Building.m_vVertexNum].y = vVertexs[i].y;
		G_Building.m_vertices[G_Building.m_vVertexNum].z = vVertexs[i].z;
		G_Building.m_vertices[G_Building.m_vVertexNum].u = tVertexs[i].u;
		G_Building.m_vertices[G_Building.m_vVertexNum].v = tVertexs[i].v;
		G_Building.m_vertices[G_Building.m_vVertexNum].w = 1;
		G_Building.m_indexs[G_Building.m_indexNum] = G_Building.m_vVertexNum;
		G_Building.m_indexNum++;
		G_Building.m_vVertexNum++;
	}

	return true;
}

bool HouseSteps::IsGenBreak(HouseDir dir)
{
	switch(dir)
	{
	case HouseDirNull:
		break;
	case HouseDown:
	case HouseUp:
		if (m_depthHigh>=G_Building.MaxSquareDepthHeight)//+1)
		{
			return true;
		}
		break;
	default:
		return true;
		break;
	}
	return false;
}


//==================^_^==================^_^==================^_^==================^_^
typedef std::list<House*>* HouseQueue;
Building::Building()
:m_houseList(NULL)
,m_wayEdges(NULL)
{
	m_indexNum = 0;
	m_vVertexNum = 0;
	m_indexs = NULL;
	m_vertices = NULL;
	MaxDepthLevel = 5;//3;   可以分3次成为4层
	MaxDepthHeight = 5;//5;
	m_houseNum = 0;
	m_vertexBuffer = NULL;
	m_indexBuffer = NULL;
	m_HouseQueue = new std::list<House*>;
}
Building::~Building()
{
	Free();
	if (m_HouseQueue)
	{
		delete ((std::list<House*>*)m_HouseQueue);
		m_HouseQueue = NULL;
	}
}

void Building::Free()
{
	((HouseQueue)m_HouseQueue)->clear();
	for (int i=0;i<m_houseNum;i++)
	{
		if (m_houseList[i]!=NULL)
		{
			delete m_houseList[i];
		}
	}
	if (m_houseList)
	{
		delete[] m_houseList;
	}
	if (m_indexs)
	{
		delete[] m_indexs;
	}
	if (m_vertices)
	{
		delete[] m_vertices;
	}
	if (m_wayEdges)
	{
		delete[] m_wayEdges;
	}
	m_wayEdgesNum = 0;
	m_indexNum = 0;
	m_vVertexNum = 0;
	m_houseNum = 0;


	if (m_vertexBuffer)
	{
		m_vertexBuffer->Free();
		delete m_vertexBuffer;
		m_vertexBuffer = NULL;
	}
	if (m_indexBuffer)
	{
		m_indexBuffer->Free();
		delete m_indexBuffer;
		m_indexBuffer = NULL;
	}
}

void Building::SaveAsObj(const char* filename)
{
	FILE* file = fopen(filename, "wb");
	if(!file) 
	{
		return;
	}
	fprintf(file,"# exported by crapell engine!");
	fprintf(file,"\n");
	fprintf(file,"\n");

	char mtlFileName[256];
	sprintf(mtlFileName,filename);
	strcat(mtlFileName,".mtl");

	std::string mtlFileNameLocal = mtlFileName;
	size_t pos = mtlFileNameLocal.find_last_of("//\\");
	if(pos!= std::string::npos)
	{
		mtlFileNameLocal = mtlFileNameLocal.substr(pos,mtlFileNameLocal.length());
	}

	fprintf(file,"mtllib %s ",mtlFileNameLocal.c_str());
	fprintf(file,"\n");
	{
		fprintf(file,"# new object: ");
		fprintf(file,"terrain");
		fprintf(file,"\n");

		fprintf(file,"g ");
		fprintf(file,"terrain");
		fprintf(file,"\n");

		fprintf(file,"usemtl ");

		std::string texName = "terrain_complex_texture.png";
		size_t pos = texName.find_first_of("//\\");
		if(pos!= std::string::npos)
		{
			texName = texName.substr(pos,texName.length());
		}
		fprintf(file,texName.c_str());
		fprintf(file,"\n");

		int vertexNum = m_vVertexNum;
		Vertex*  vVertexs = m_vertices;
		for (int loop = 0; loop < vertexNum; loop++,vVertexs++)
		{
			fprintf(file,"v ");
			fprintf(file,"%f %f %f ",vVertexs->x,vVertexs->y,vVertexs->z);
			fprintf(file,"\n");
		}

		//vVertexs = m_vertices;
		//for (int loop = 0; loop < vertexNum; loop++,vVertexs++)
		//{
		//	fprintf(file,"vn ");
		//	fprintf(file,"%f %f %f ",vVertexs->nx,vVertexs->ny,vVertexs->nz);
		//	fprintf(file,"\n");
		//}

		Vertex*  tVertexs = m_vertices;
		for (int loop = 0; loop < vertexNum; loop++,tVertexs++)
		{
			fprintf(file,"vt ");
			fprintf(file,"%f %f %f ",tVertexs->u,tVertexs->v,0.0f);
			fprintf(file,"\n");
		}


		int value;
		int trigonNum = m_indexNum/3;
		for(int y = 0; y < trigonNum; y++)
		{
			value = y*3;
			fprintf(file,"f ");
			//v/t
			fprintf(file,"%d/%d %d/%d %d/%d ",value+1,value+1,value+2,value+2,value+3,value+3);
			//fprintf(file,"%d %d %d ",value[0]+1,value[1]+1,value[2]+1);
			fprintf(file,"\n");
		}
		fprintf(file,"\n");
	}
	fclose(file);

	材质
	FILE* mtlfile = fopen(mtlFileName, "wb");
	if(mtlfile) 
	{
		fprintf(mtlfile,"# exported by crapell engine!");
		fprintf(mtlfile,"\n");
		fprintf(mtlfile,"\n");

		fprintf(file,"newmtl ");
		std::string texName = "terrain_complex_texture.png";//src->GetTextureName();
		size_t pos = texName.find_last_of("//\\");
		if(pos!= std::string::npos)
		{
			texName = texName.substr(pos,texName.length());
		}
		fprintf(file,texName.c_str());
		fprintf(file,"\n");

		fprintf(file,"Ka 1.0 1.0 1.0 ");
		fprintf(file,"\n");

		fprintf(file,"Kd 1.0 1.0 1.0 ");
		fprintf(file,"\n");

		fprintf(file,"Ks 0.2 0.2 0.2 ");
		fprintf(file,"\n");

		fprintf(file,"Ns 32  ");
		fprintf(file,"\n");

		fprintf(file,"map_Kd %s ",texName.c_str());
		fprintf(file,"\n");

		fprintf(file,"\n");

		fclose(mtlfile);
		return;
	}
}
void Building::GenBuilding(BuildingDef* buildingDef)
{
	Free();
	G_TextureMgr->AddTexture(m_texture,"data/Environment/building/city0.png");
	House::InitTemplate();

	m_buildingDef = buildingDef;
	m_maxVertexNum = 30000;
	m_indexs = new IndexInt[m_maxVertexNum];
	m_vertices = new Vertex[m_maxVertexNum];

	m_normalHalfExtend = vec3(10,10,10);

	//m_houseMaxNum = pow((double)4,MaxDepthLevel+1)*pow((double)2,MaxDepthHeight+1)+1;
	//m_houseMaxNum += (MaxSquareDepthLevel*MaxSquareDepthLevel*MaxSquareDepthHeight);
	m_houseMaxNum = 2000;
	m_houseList = new House*[m_houseMaxNum];
	m_wayEdges = new WayEdge[m_houseMaxNum];



	//==================^_^

	//广场拓补
	int SquareNum = 1;
	MaxSquareDepthLevel =  RandRange(4,6);//4~6圈;  
	MaxSquareDepthHeight = 3;//RandRange(2,3);//2~3层;  
	m_normalSquareHalfExtend = vec3(15,10,15);
	m_houseBaseHeight = MaxSquareDepthHeight*2*m_normalSquareHalfExtend.y;
	House* mainSquare = new HouseSquare;
	mainSquare->SetParm(0,vec3(0,m_houseBaseHeight-m_normalSquareHalfExtend.y,0),m_normalSquareHalfExtend,House::HouseTypeSquare,House::HouseDirNull,DepthZero,DepthZero);
	if(mainSquare->GenTopoBuilding()==false)
	{
		delete mainSquare;
	}
	HouseQueue houseQueue = (HouseQueue)m_HouseQueue;
	//广度遍历生成广场
	while (houseQueue->empty()==false)
	{
		House* head = houseQueue->front();
		houseQueue->pop_front();
		if(head->GenTopoBuilding()==false)
		{
			delete head;
		}
	}	

	//房子拓补 建筑群数
	int BuildingNum = 6;
	for (int i=0;i<BuildingNum;i++)
	{
		vec3 newpos;
		if(i==0)
		{
			MaxDepthLevel = RandRange(4,5);//4~6圈; 
			MaxDepthHeight = RandRange(4,5);//4~6层;  
			newpos = vec3(0,m_normalHalfExtend.y,0);
		}
		else
		{
			MaxDepthLevel = RandRange(1,3); //2~3圈;  
			MaxDepthHeight = RandRange(1,2);//2~3层;  
			newpos.x = RandRange(-1.0f,1.0f);
			newpos.z = RandRange(-1.0f,1.0f);
			newpos.Normalize();
			if (newpos.Length() < _EPSILON)
			{
				newpos.x = 1;
			}
			newpos*= (m_normalHalfExtend.x*RandRange(20.0f,30.0f));
			newpos.y = m_houseBaseHeight+m_normalHalfExtend.y;
		}
		newpos.y += GetTerrainHeight(newpos);
		House* mainHouse = new HouseFourWall;
		mainHouse->SetParm(0,newpos,m_normalHalfExtend,House::HouseTypeFourWall,House::HouseDirNull,DepthZero,DepthZero);
		if(mainHouse->GenTopoBuilding()==false)
		{
			delete mainHouse;
		}

		//一幢一幢拓扑,而不是几幢一起拓补
		//广度遍历生成房子
		while (houseQueue->empty()==false)
		{
			House* head = houseQueue->front();
			houseQueue->pop_front();
			if(head->GenTopoBuilding()==false)
			{
				delete head;
			}
		}
	}

	//城墙拓补




	//==================^_^

	//构建模型
	for (int i=0;i<m_houseNum;i++)
	{
		if (m_houseList[i]!=NULL)
		{
			if(m_vVertexNum>=m_maxVertexNum-96)
			{
				MsgBox(NULL, "m_vVertexNum>=m_maxVertexNum-96", "ERROR", MB_OK);
			}
			m_houseList[i]->GenSelfModel();
		}
	}
	//构建导航网
	for (int i=0;i<m_houseNum;i++)
	{
		if (m_houseList[i]!=NULL)
		{
			m_houseList[i]->GenNavgation();
		}
	}



	m_vertexBuffer = G_RendDriver->CreateVB();
	m_vertexBuffer->Create(DYNAMIC_DRAW_ARB,FVF_XYZ|FVF_TEX0,m_vVertexNum,sizeof(Vertex));
	m_vertexBuffer->Set(0,0,m_vertices);

	m_indexBuffer =  G_RendDriver->CreateIB();
	m_indexBuffer->Create(STATIC_DRAW_ARB,m_indexNum,0);
	//int a = sizeof(Trigon);
	m_indexBuffer->Set(0,m_indexNum,m_indexs);

	if (m_vertexBuffer
		&&m_vertexBuffer->Lock())
	{
		memcpy(m_vertexBuffer->GetPtr(),m_vertices,sizeof(Vertex)*m_vVertexNum);
		m_vertexBuffer->Unlock();
	}

	if (m_indexBuffer
		&&m_indexBuffer->Lock())
	{
		memcpy(m_indexBuffer->GetPtr(),m_indexs,4*m_indexNum);
		m_indexBuffer->Unlock();
	}

	SaveAsObj("data/test/terrain/building.obj");
}

void Building::Rend()
{
	for (int i=0;i<m_houseNum;i++)
	{
		if (m_houseList[i]!=NULL)
		{
			m_houseList[i]->Render();
		}
	}

	G_RendDriver->SetRenderStateEnable(RS_DEPTH_TEST,true);
	G_RendDriver->SetRenderStateEnable(RS_TEXTURE_2D,true);
	G_RendDriver->SetRenderStateEnable(RS_ALPHA_TEST,true);
	G_RendDriver->SetRenderStateEnable(RS_BLEND,true);
	G_RendDriver->BlendFunc(RS_SRC_ALPHA,RS_ONE_MINUS_SRC_ALPHA);
	G_RendDriver->AlphaFunc(RS_GREATER,0.0f);
	G_RendDriver->Color4f(1,1,1,1);

		for (int i=0;i<8;i++)
		{
			G_RendDriver->SetSamplerState(i, SS_MINFILTER, TF_LINEAR);
			G_RendDriver->SetSamplerState(i, SS_MAGFILTER, TF_LINEAR);
		}

	if(m_texture)
		m_texture->Bind();
	if(m_vertexBuffer)
		m_vertexBuffer->Bind(0);
	if(m_indexBuffer)
	{
		m_indexBuffer->Bind(Decl1_XYZUVW);
		m_indexBuffer->Render();
	}
	if(m_vertexBuffer)m_vertexBuffer->UnBind();
	if(m_indexBuffer) m_indexBuffer->UnBind();

	//==================^_^
	RendNavgation();
}

void Building::RendNavgation()
{
	//
	G_RendDriver->DisableRendState(RS_TEXTURE_2D);
	G_RendDriver->DisableRendState(RS_DEPTH_TEST);
	G_RendDriver->Color4f(0,1,0, 0.5f);
	G_RendDriver->RendBegin(RS_LINES);
	for(int i = 0; i < m_wayEdgesNum; i++)
	{
		G_RendDriver->Vertex3f(m_wayEdges[i].start.x, m_wayEdges[i].start.y, m_wayEdges[i].start.z);
		G_RendDriver->Vertex3f(m_wayEdges[i].end.x, m_wayEdges[i].end.y, m_wayEdges[i].end.z);
	}
	G_RendDriver->RendEnd();

	//
	G_RendDriver->Color4f(0,0,1, 1);
	G_RendDriver->SetPointSize(3);
	G_RendDriver->RendBegin(RS_POINTS);
	for(int i = 0; i < m_wayEdgesNum; i++)
	{
		G_RendDriver->Vertex3f(m_wayEdges[i].start.x, m_wayEdges[i].start.y, m_wayEdges[i].start.z);
		G_RendDriver->Vertex3f(m_wayEdges[i].end.x, m_wayEdges[i].end.y, m_wayEdges[i].end.z);
	}
	G_RendDriver->RendEnd();

	//
	G_RendDriver->EnableRendState(RS_DEPTH_TEST);
	G_RendDriver->Color4f(0,1,0, 1);
	G_RendDriver->RendBegin(RS_LINES);
	for(int i = 0; i < m_wayEdgesNum; i++)
	{
		G_RendDriver->Vertex3f(m_wayEdges[i].start.x, m_wayEdges[i].start.y, m_wayEdges[i].start.z);
		G_RendDriver->Vertex3f(m_wayEdges[i].end.x, m_wayEdges[i].end.y, m_wayEdges[i].end.z);
	}
	G_RendDriver->RendEnd();
	
}

void Building::AddHouse(House* house)
{
	if (m_houseNum>=m_houseMaxNum)
	{
		MsgBox(NULL, "m_houseNum>=m_houseMaxNum", "ERROR", MB_OK);
	}
	m_houseList[m_houseNum] = house;
	m_houseNum++;
}

House* Building::CheckHousePos(House* house)
{
	float scale = 0.8f;
	if (dynamic_cast<HouseRoof*>(house))
	{
		//scale = 0.5f;
		//if (house->m_houseDirFromParent==House::HouseUp)
		{
			//屋顶不参与碰撞 屋顶横向派生的亭子顶继续参与
			return NULL;
		}
	}
	Box boxnew(house->m_pos,house->m_halfExtend*scale);
	for (int i=0;i<m_houseNum;i++)
	{
		if (m_houseList[i]!=NULL && m_houseList[i]!=house)
		{
			Box box(m_houseList[i]->m_pos,m_houseList[i]->m_halfExtend);
			if (box.isOverlap(boxnew))
			{
				return m_houseList[i];
			}
		}
	}
	return NULL;
}

House* Building::CheckBound(Box* boxnew,House* houseExcept)
{
	for (int i=0;i<m_houseNum;i++)
	{
		if (m_houseList[i]!=NULL && m_houseList[i]!=houseExcept)
		{
			Box box(m_houseList[i]->m_pos,m_houseList[i]->m_halfExtend);
			if (box.isOverlap(*boxnew))
			{
				return m_houseList[i];
			}
		}
	}
	return NULL;
}

float Building::GetTerrainHeight(const vec3& pos)
{
	Box boxnew(pos,vec3(0.0001f,1000.0f,0.0001f));
	for (int i=0;i<m_houseNum;i++)
	{
		if (m_houseList[i]!=NULL && 
			dynamic_cast<HouseSquare*>(m_houseList[i]))
		{
			Box box(m_houseList[i]->m_pos,m_houseList[i]->m_halfExtend);
			if (box.isOverlap(boxnew))
			{
				float height = m_houseList[i]->m_pos.y+m_houseList[i]->m_halfExtend.y;
				return height;
			}
		}
	}
	//最底层
	return 0;//-G_Building.m_normalSquareHalfExtend.y*(G_Building.MaxSquareDepthHeight*2-1);
}

void  Building::PushQueue(House* house)
{
	((HouseQueue)m_HouseQueue)->push_back(house);
}



bool  BuildingDef::LoadFromFile(const char* filename)
{
	for (int t=0;t<TexNum;t++)
	{
		m_textureUnits[t].unitNum = 0;
	}
	m_textureUnits[BuildingDef::TexRoof].unitNum = 4;
	m_textureUnits[BuildingDef::TexRoof].texCoordRect[0] = RectF(0,0,96,81);
	m_textureUnits[BuildingDef::TexRoof].texCoordRect[1] = RectF(96,0,128,48);
	m_textureUnits[BuildingDef::TexRoof].texCoordRect[2] = RectF(224,0,129,81);
	m_textureUnits[BuildingDef::TexRoof].texCoordRect[3] = RectF(353,0,142,138);
	m_textureUnits[BuildingDef::TexWall].unitNum = 6;
	m_textureUnits[BuildingDef::TexWall].texCoordRect[0] = RectF(0,84,128,79);
	m_textureUnits[BuildingDef::TexWall].texCoordRect[1] = RectF(129,84,127,79);
	m_textureUnits[BuildingDef::TexWall].texCoordRect[2] = RectF(0,167,128,128);
	m_textureUnits[BuildingDef::TexWall].texCoordRect[3] = RectF(256,167,128,128);
	m_textureUnits[BuildingDef::TexWall].texCoordRect[4] = RectF(384,167,128,128);
	m_textureUnits[BuildingDef::TexWall].texCoordRect[5] = RectF(0,529,128,128);

	m_textureUnits[BuildingDef::TexWallDoor].unitNum = 2;
	m_textureUnits[BuildingDef::TexWallDoor].texCoordRect[0] = RectF(256,298,128,128);
	m_textureUnits[BuildingDef::TexWallDoor].texCoordRect[1] = RectF(128,167,128,128);

	m_textureUnits[BuildingDef::TexWallColumn].unitNum = 1;
	m_textureUnits[BuildingDef::TexWallColumn].texCoordRect[0] = RectF(0,529,128,128);

	m_textureUnits[BuildingDef::TexColumn].unitNum = 2;
	m_textureUnits[BuildingDef::TexColumn].texCoordRect[0] = RectF(445,391,33,121);
	m_textureUnits[BuildingDef::TexColumn].texCoordRect[1] = RectF(478,391,33,121);
	m_textureUnits[BuildingDef::TexFence].unitNum = 3;
	m_textureUnits[BuildingDef::TexFence].texCoordRect[0] = RectF(0,448,122,64);
	m_textureUnits[BuildingDef::TexFence].texCoordRect[1] = RectF(122,448,133,64);
	m_textureUnits[BuildingDef::TexFence].texCoordRect[2] = RectF(255,448,128,64);
	m_textureUnits[BuildingDef::TexFloor].unitNum = 3;
	m_textureUnits[BuildingDef::TexFloor].texCoordRect[0] = RectF(0,298,128,128);
	m_textureUnits[BuildingDef::TexFloor].texCoordRect[1] = RectF(128,298,128,128);
	m_textureUnits[BuildingDef::TexFloor].texCoordRect[2] = RectF(256,529,128,128);

	m_textureUnits[BuildingDef::TexSteps].unitNum = 2;
	m_textureUnits[BuildingDef::TexSteps].texCoordRect[0] = RectF(0,657,105,107);
	m_textureUnits[BuildingDef::TexSteps].texCoordRect[1] = RectF(106,657,100,97);

	m_textureUnits[BuildingDef::TexWater].unitNum = 1;
	m_textureUnits[BuildingDef::TexWater].texCoordRect[0] = RectF(128,529,128,128);

	m_textureUnits[BuildingDef::TexDecalWall].unitNum = 3;
	m_textureUnits[BuildingDef::TexDecalWall].texCoordRect[0] = RectF(64,768,64,64);
	m_textureUnits[BuildingDef::TexDecalWall].texCoordRect[1] = RectF(256,768,64,64);
	m_textureUnits[BuildingDef::TexDecalWall].texCoordRect[2] = RectF(64,768,64,64);

	m_textureUnits[BuildingDef::TexDecalFloor].unitNum = 2;
	m_textureUnits[BuildingDef::TexDecalFloor].texCoordRect[0] = RectF(0,768,64,64);
	m_textureUnits[BuildingDef::TexDecalFloor].texCoordRect[1] = RectF(256,768,64,64);
	m_textureUnits[BuildingDef::TexDecalFloor].texCoordRect[2] = RectF(64,768,64,64);

	m_textureUnits[BuildingDef::TexDecalWater].unitNum = 2;
	m_textureUnits[BuildingDef::TexDecalWater].texCoordRect[0] = RectF(128,768,64,64);
	m_textureUnits[BuildingDef::TexDecalWater].texCoordRect[1] = RectF(192,768,64,64);

	float w = 512;
	float h = 1024;
	for (int t=0;t<TexNum;t++)
	{
		for (int i=0;i<m_textureUnits[t].unitNum;i++)
		{
			RectF& texRect = m_textureUnits[t].texCoordRect[i];
			texRect.x/=w;
			if(G_RendDriver->GetDriverType()==D3DDRIVER)
			{
				//texRect.y=texRect.y/h;
				//texRect.width/=w;
				//texRect.height/=h;
				texRect.y=(texRect.y+texRect.height)/h;
				texRect.width/=w;
				texRect.height/=(-h);
			}
			else
			{
				texRect.y=1-(texRect.y+texRect.height)/h;
				texRect.width/=w;
				texRect.height/=h;
			}
		}
	}

	return true;
}

RectF BuildingDef::GetTextureRect(TextureUnitType type,int index)
{
	if (index ==-1)
	{
		index = Rand()%	m_textureUnits[type].unitNum;
	}
	return m_textureUnits[type].texCoordRect[index];
}
mat4  BuildingDef::GetTextureMatrix(TextureUnitType type,int index)
{
	mat4 mats;
	RectF texRect = GetTextureRect(type,index);
	mats.FromScale(texRect.width,texRect.height,1.0f);
	mat4 mat;
	mat.FromTranslate(texRect.x,texRect.y,0.0f);
	mat = mat*mats;
	return mat;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值