版本一
随机生成游戏建筑和导航网格。使用房屋四壁扩张生长的方式生成。.
存在的缺陷,有机会重构一下:
模型细致度不够,模板顶点数据直接通过程序生成使得算法变的复杂,扩展功能也变得复杂,可以试试将模板在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;
}