版本一

随机生成游戏建筑和导航网格。使用房屋四壁扩张生长的方式生成。.
存在的缺陷,有机会重构一下:
模型细致度不够,模板顶点数据直接通过程序生成使得算法变的复杂,扩展功能也变得复杂,可以试试将模板在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个boxclass 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=64vec3     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);//!返回位置冲突的houseHouse* 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;    //起始层为1int 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=36TVertex 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=36TVertex 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=36float 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=64for (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){//栅栏式屋顶 剔除upif (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++;}/+ decalbool 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/tfprintf(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;
}

随机生成游戏建筑物的算法相关推荐

  1. 随机生成游戏角色昵称(使用Excel配置XML文件)上

    在游戏开发中,基本上每一个游戏都有 随机生成游戏角色昵称的模块儿,游戏昵称这个东西是由策划来进行完成的,而策划一般情况下是不会写代码的,如果他写的不好还行,如果写好了咱们就失业了,so 咱们都是让策划 ...

  2. 随机生成植物生长及舞动算法

    几年前写过一套随机树木的生成算法,其中使用了分形和放样建模.那时候还不知道有speedtree这款软件,写的比较粗糙,最近看了speedtree的演示把原算法改进了一下,算是一个speedtree的简 ...

  3. 随机生成游戏用户昵称(nodejs版本)(含机器人头像,金币等)

    1 前言 有时需要生成随机的用户(或机器人)昵称,头像,金币等,但又不想太生硬,可以现在网上爬一些常见昵称到文本中,然后读取出来,随机使用即可. 2 代码 var nickNameArr = [];f ...

  4. 随机生成游戏角色昵称(在Unity中解析XML配置文件)下

    上一篇文章我们说到了,配置文件的生成,接下来继续,也就是 1.Unity中,使用资源加载系统去 加载配置文件(客户端) 2.在C# 文件 IO 接口加载文件(服务器) 所以这里直接就上源代码了:上代码 ...

  5. 随机生成编号与按规则生成编号

    1.随机生成编号(雪花算法) int month = Calendar.getInstance().get(Calendar.MONTH);Snowflake snowflake = IdUtil.c ...

  6. [Qt] 迷宫随机生成和自动寻路算法、布局管理器、动态效果、界面切换、播放音频【迷宫、魔塔、超级玛丽】 -C++课程设计:Qt实现的迷宫与地牢游戏

    基于QT的迷宫与地牢小游戏开发 首先贴出链接: 完整Qt源码:点击进入https://download.csdn.net/download/qq_43365825/11852112 发布可执行程序:点 ...

  7. java推箱子随机地图的产生_为什么没有人研究推箱子地图自动生成算法?算法随机生成地图,不需要地图库!?...

    其实是有的,可以参考 Ty Taylor 的 The Art and Science of Procedural Puzzle Generation,https://www.youtube.com/w ...

  8. C语言随机生成连连看地图,MFC实现连连看游戏之地图显示

    MFC实现连连看游戏前期过程中遇到的一大问题是如何将地图显示出来,最后还是看了其他人的源码才搞定. 首先是地图数组的生成,这个网上找有很多,我用的是随机生成地图的种类,然后将其放在两个连续的位置,最后 ...

  9. 技术贴:如何简单地做游戏随机生成地图

    转自:http://www.gamelook.com.cn/2015/12/239245 Gamelook报道/对于大多数的游戏来说,内容的消耗都是开发商非常棘手的问题,而随机生成地图的做法则大大增加 ...

  10. Dataset之图片数据增强:设计自动生成汽车车牌图片算法(cv2+PIL)根据随机指定七个字符生成逼真车牌图片数据集(自然场景下+各种噪声效果)可视化

    Dataset之图片数据增强:设计自动生成汽车车牌图片算法(cv2+PIL)根据随机指定七个字符生成逼真车牌图片数据集(自然场景下+各种噪声效果)可视化 导读 设计自动生成汽车车牌图片算法,基于cv2 ...

最新文章

  1. 用递归来判断输入的字符串是否是回文
  2. web程序前后台功能实现_微信定制开发、小程序定制开发可以实现哪些功能?
  3. python循环语句for求和_for循环简介
  4. Expected MultipartHttpServletRequest: is a MultipartResolver configured方案。
  5. LeetCode刷题(Python)——在排序数组中查找元素的第一个和最后一个位置
  6. [设计模式] javascript 之 建造者模式
  7. 第三次握手为什么没有序列号_“三次握手,四次挥手”你真的懂吗?
  8. micropython按键控制流水灯_【MicroPython】LAB01 - 流水灯
  9. lamp搭建wordpress后升级安装主题,提示输入ftp账号密码
  10. 《应用商务统计分析》前言
  11. coreldraw sp2精简版 x4_coreldraw x4 sp2 精简版
  12. 浅谈toB交付质量体系建设
  13. 可行性分析与需求分析
  14. 情感分析学习笔记(3)——情感传播(sentiment propagation)
  15. 无惧断电 小苏云“同城三机房”容灾演练成功
  16. re.sub()用法的详细介绍
  17. C++ 类中的static成员的使用及单例设计示例
  18. pfamscan 的使用_科学网—[转载]InterProScan的使用教程 - 黄顺谋的博文
  19. 对redis的keys方法替换
  20. 1198:逆波兰表达式(递归)

热门文章

  1. 非门芯片 74AHC1G08 74AHC1G04 74AHC1G02的区别
  2. SpringBoot项目实现微信小程序登录步骤
  3. 查看电脑连接的wifi密码
  4. android面试题之四(红黑联盟)
  5. js layui 模板属性 添加_layui模板引擎如何使用 - layim
  6. HashData:守护数据安全 筑牢数字经济底座
  7. 路由守卫 AJAX,vue路由传参与路由守卫
  8. 数据盘点各城市公积金排名,你能拿多少?
  9. 美团实习| 周记(一)
  10. uniapp得到用户当前定位以及用户选择位置