diff --git a/all_includes.hh b/all_includes.hh index a22cdf5..b973029 100644 --- a/all_includes.hh +++ b/all_includes.hh @@ -11,6 +11,8 @@ class Chose; #include #include #include +#include +#include #include #include diff --git a/rules/architecture/batiment.cpp b/rules/architecture/batiment.cpp index d75c9a8..16bddec 100644 --- 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 index 79499bc..7be367e 100644 --- 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 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(v, w)); } +}; + +class MasterWall; +class MasterWallIterator : public std::iterator { +private: + std::map::iterator it; + bool reverse; +public: + MasterWallIterator(std::map::iterator mwit) : it(mwit), reverse(false) {}; + MasterWallIterator(std::map::iterator mwit, bool _reverse) : it(mwit), reverse(_reverse) {}; + MasterWallIterator(std::map::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 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(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::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 index acafdf0..06e7c56 100644 --- 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 index 78c52ad..4c64235 100644 --- 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); }