commit 9d6dd26e2c9eda48b18c1838f3673cefc3fc13e2
parent 62b70d8614889f1e2494203e40cbaa963629cb55
Author: Georges Dupéron <jahvascriptmaniac+github@free.fr>
Date: Tue, 17 Jan 2012 19:54:49 +0100
Structures de données pour le découpage des bâtiments (non testé).
Diffstat:
5 files changed, 126 insertions(+), 7 deletions(-)
diff --git a/all_includes.hh b/all_includes.hh
@@ -11,6 +11,8 @@ class Chose;
#include <cmath>
#include <vector>
#include <set>
+#include <map>
+#include <list>
#include <SDL/SDL.h>
#include <GL/glew.h>
diff --git a/rules/architecture/batiment.cpp b/rules/architecture/batiment.cpp
@@ -5,7 +5,8 @@ BatimentQuad_::BatimentQuad_(Quad _c) : Chose(), c(_c) {
}
bool BatimentQuad_::split() {
- //addChild()
+ Quad ch = c.offsetNormal(Dimensions::hauteurEtage);
+ //addChild(new ToitQuad(ch, Dimensions::hauteurToit));
return true;
}
diff --git a/rules/architecture/batiment.hh b/rules/architecture/batiment.hh
@@ -21,4 +21,119 @@ public:
virtual void getBoundingBoxPoints();
};
+class Wall;
+class MasterWall;
+class WallVertex {
+public:
+ Vertex vertex;
+ MasterWall* onMasterWall;
+ float posOnMasterWall;
+ std::map<WallVertex*, MasterWall*> endWall;
+public:
+ operator Vertex() { return vertex; };
+ WallVertex(Vertex _v) : vertex(_v), onMasterWall(NULL), posOnMasterWall(0) {};
+ WallVertex(Vertex _v, MasterWall* _onWall, float _posOnWall) : vertex(_v), onMasterWall(_onWall), posOnMasterWall(_posOnWall) {};
+ void addEndWall(WallVertex* v, MasterWall* w) { endWall.insert(std::pair<WallVertex*, MasterWall*>(v, w)); }
+};
+
+class MasterWall;
+class MasterWallIterator : public std::iterator<std::input_iterator_tag, MasterWall> {
+private:
+ std::map<float, WallVertex*>::iterator it;
+ bool reverse;
+public:
+ MasterWallIterator(std::map<float, WallVertex*>::iterator mwit) : it(mwit), reverse(false) {};
+ MasterWallIterator(std::map<float, WallVertex*>::iterator mwit, bool _reverse) : it(mwit), reverse(_reverse) {};
+ MasterWallIterator(std::map<float, WallVertex*>::reverse_iterator mwrit) : it(--(mwrit.base())), reverse(false) {};
+ MasterWallIterator(const MasterWallIterator& copy) : it(copy.it), reverse(copy.reverse) {};
+ bool operator==(const MasterWallIterator& mwit) const { return it == mwit.it; };
+ bool operator!=(const MasterWallIterator& mwit) const { return it != mwit.it; };
+ WallVertex* operator*() { return (*it).second; };
+ WallVertex* operator->() { return (*it).second; };
+ virtual void operator++() { if (reverse) it--; else it++; }
+};
+
+class MasterWall {
+private:
+ std::map<float, WallVertex*> vertices;
+public:
+ typedef MasterWallIterator iterator;
+ MasterWall(WallVertex* u, WallVertex* v) {
+ insert(0, u);
+ insert(1, v);
+ };
+ void insert(float position, WallVertex* u) {
+ vertices.insert(std::pair<float, WallVertex*>(position,u));
+ };
+ WallVertex* u() { return vertices.begin()->second; };
+ WallVertex* v() { return vertices.rbegin()->second; };
+ iterator begin() { return iterator(vertices.begin()); }
+ iterator end() { return iterator(vertices.end()); }
+ iterator rbegin() { return iterator(vertices.rbegin()); }
+ iterator rend() { return iterator(vertices.rend()); }
+ iterator find(float position) { return iterator(vertices.find(position)); }
+ iterator rfind(float position) { return iterator(vertices.find(position), true); }
+ iterator find(float position, bool reverse) { return iterator(vertices.find(position), reverse); }
+};
+
+class Wall {
+public:
+ WallVertex* u;
+ WallVertex* v;
+ float uPosOnMasterWall;
+ float vPosOnMasterWall;
+ MasterWall* master;
+public:
+ Wall(WallVertex* _u, WallVertex* _v) {
+ u = _u;
+ v = _v;
+ if (u->onMasterWall != NULL && u->onMasterWall == v->onMasterWall) { // u et v au milieu de master
+ master = u->onMasterWall;
+ uPosOnMasterWall = u->posOnMasterWall;
+ vPosOnMasterWall = v->posOnMasterWall;
+ } else if (u->onMasterWall != NULL && (u->onMasterWall->u() == v || u->onMasterWall->v() == v)) { // u au milieu de master, v au bord
+ master = u->onMasterWall;
+ uPosOnMasterWall = u->posOnMasterWall;
+ vPosOnMasterWall = (master->u() == v) ? 0 : 1;
+ } else if (v->onMasterWall != NULL && (v->onMasterWall->u() == u || v->onMasterWall->v() == u)) { // v au milieu de master, u au bord
+ master = v->onMasterWall;
+ uPosOnMasterWall = (master->u() == u) ? 0 : 1;
+ vPosOnMasterWall = v->posOnMasterWall;
+ } else {
+ std::map<WallVertex*, MasterWall*>::iterator it = u->endWall.find(v);
+ if (it != u->endWall.end()) { // u et v au bord d'un master existant.
+ master = it->second;
+ uPosOnMasterWall = (master->u() == u) ? 0 : 1;
+ vPosOnMasterWall = (master->u() == u) ? 1 : 0;
+ } else { // u et v au bord d'un nouveau master.
+ master = new MasterWall(u, v);
+ uPosOnMasterWall = 0;
+ vPosOnMasterWall = 1;
+ u->addEndWall(v, master);
+ v->addEndWall(u, master);
+ }
+ }
+ };
+ operator Segment () {
+ return Segment(*u, *v);
+ }
+ WallVertex* randomPos(int seed, int n, float a, float b) {
+ float width = vPosOnMasterWall - uPosOnMasterWall;
+ float pos = floatInRange(seed, n, uPosOnMasterWall + a*width, uPosOnMasterWall + b*width);
+ MasterWallIterator mwi = master->find(pos);
+ if (mwi == master->end()) { // Il n'y a pas encore de WallVertex à cette position sur master.
+ Vertex mu = *(master->u());
+ Vertex mv = *(master->v());
+ WallVertex* wv = new WallVertex(mu * pos + mv * (1-pos), master, pos);
+ master->insert(pos, wv);
+ return wv;
+ } else { // Il y a déjà un WallVertex à cette position sur master.
+ return (*mwi);
+ }
+ };
+ typedef MasterWall::iterator iterator;
+ iterator begin() { return master->find(uPosOnMasterWall, (uPosOnMasterWall > vPosOnMasterWall)); };
+ iterator end() { return master->find(vPosOnMasterWall, (uPosOnMasterWall > vPosOnMasterWall)); };
+};
+
#endif
diff --git a/rules/architecture/couleursDimensions.hh b/rules/architecture/couleursDimensions.hh
@@ -35,7 +35,7 @@ public:
static const unsigned int largeurRoute = 200;
static const unsigned int largeurTrottoir = 140;
static const unsigned int hauteurEtage = 300;
- static const unsigned int hauteurToit = 100;
+ static const unsigned int hauteurToit = 200;
static const unsigned int hauteurTrottoir = 20;
static const unsigned int hauteurMaxBatiment = hauteurTrottoir + hauteurEtage + hauteurToit;
};
diff --git a/rules/architecture/toit.cpp b/rules/architecture/toit.cpp
@@ -14,6 +14,7 @@ void ToitQuad::getBoundingBoxPoints() {
void ToitQuad::triangulation() {
switch (hash2(seed, -1) % 4) {
case 0: pointCentral(); break;
+ // TODO : deuxPoints() et deuxPointsVerticaux() ne génèrent pas des quad où les 4 points sont sur le même plan.
case 1: deuxPoints(); break;
case 2: deuxPointsVerticaux(); break;
case 3:
@@ -25,7 +26,7 @@ void ToitQuad::pointCentral() {
Quad qh = c.offsetNormal(height);
Vertex center = qh.insetNESW(qh.minLength() / 3.f).randomPoint(seed, 0);
for (int i = 0; i < 4; i++)
- addGPUTriangle(c[NE+i], center, c[SE+i], Couleurs::toit);
+ addGPUTriangle(c[SE+i], center, c[NE+i], Couleurs::toit);
}
void ToitQuad::deuxPoints() {
@@ -36,8 +37,8 @@ void ToitQuad::deuxPoints() {
Vertex e = Segment(qh[NE], qh[SE]).randomPos(seed, 1, 1.f/3.f, 2.f/3.f);
Vertex centerE = Segment(e,w).randomPos(seed, 2, 0.6f, 0.8f);
Vertex centerW = Segment(e,w).randomPos(seed, 2, 0.2f, 0.4f);
- addGPUTriangle(q[NE], centerE, q[SE], Couleurs::toit);
- addGPUTriangle(q[SW], centerW, q[NW], Couleurs::toit);
+ addGPUTriangle(q[SE], centerE, q[NE], Couleurs::toit);
+ addGPUTriangle(q[NW], centerW, q[SW], Couleurs::toit);
addGPUQuad(q[SE], q[SW], centerW, centerE, Couleurs::toit);
addGPUQuad(q[NW], q[NE], centerE, centerW, Couleurs::toit);
}
@@ -48,8 +49,8 @@ void ToitQuad::deuxPointsVerticaux() {
Quad qh = q.offsetNormal(height);
Vertex w = Segment(qh[NW], qh[SW]).randomPos(seed, 0, 1.f/3.f, 2.f/3.f);
Vertex e = Segment(qh[NE], qh[SE]).randomPos(seed, 1, 1.f/3.f, 2.f/3.f);
- addGPUTriangle(q[NE], e, q[SE], Couleurs::toit); // TODO : devrait être couleur mur.
- addGPUTriangle(q[SW], w, q[NW], Couleurs::toit); // TODO : devrait être couleur mur.
+ addGPUTriangle(q[SE], e, q[NE], Couleurs::mur);
+ addGPUTriangle(q[NW], w, q[SW], Couleurs::mur);
addGPUQuad(q[SE], q[SW], w, e, Couleurs::toit);
addGPUQuad(q[NW], q[NE], e, w, Couleurs::toit);
}