diff --git a/geometry/triangle.cpp b/geometry/triangle.cpp index d474e8b..d1e7345 100644 --- a/geometry/triangle.cpp +++ b/geometry/triangle.cpp @@ -103,7 +103,7 @@ Triangle Triangle::offsetNormal(float offset) const { Triangle Triangle::insetProportionnal(float prop) { Triangle rTriangle = *this; //ibc : isobarycentre. - Vertex ibc = Segment(c[TOP],Segment(c[LEFT],c[RIGHT]).center()).at(2./3.); + Vertex ibc = Segment(c[TOP],Segment(c[LEFT],c[RIGHT]).center()).at(2.f/3.f); prop = prop; rTriangle[TOP] = Segment(ibc,c[TOP]).at(prop); diff --git a/heap.hh b/heap.hh index fb9d0d2..438f2b4 100644 --- a/heap.hh +++ b/heap.hh @@ -9,7 +9,7 @@ public: float key; Chose* value; friend bool operator< (const HeapNode &a, const HeapNode &b) { - return (a.key < b.key || (a.key == b.key && a.value < b.value)); + return (a.key < b.key || (a.key >= b.key && a.key <= b.key && a.value < b.value)); } }; diff --git a/main.cpp b/main.cpp index 6e3d76d..fbcf6cb 100644 --- a/main.cpp +++ b/main.cpp @@ -7,10 +7,10 @@ int main(int argc, char* argv[]) { std::cout << "Initial seed = " << Chose::initialSeed << std::endl; float size = 200 * 100; - Vertex ne(size, size, 0); - Vertex se(size, 0, 0); - Vertex sw(0, 0, 0); - Vertex nw(0, size, 0); + Vertex ne(+size/2.f, +size/2.f, 0); + Vertex se(+size/2.f, -size/2.f, 0); + Vertex sw(-size/2.f, -size/2.f, 0); + Vertex nw(-size/2.f, +size/2.f, 0); Chose* c = new QuartierQuad(Quad(ne, se, sw, nw)); c->triangulation(); diff --git a/rules/arbre.cpp b/rules/arbre.cpp index 00804b0..79e500c 100644 --- a/rules/arbre.cpp +++ b/rules/arbre.cpp @@ -26,7 +26,7 @@ Arbre::Arbre(Vertex _start, Quad plane) { Arbre::Arbre(Vertex _start, Angle3D _rotation, float _length, Type _type) : start(_start), rotation(_rotation), length(_length), type(_type) { addEntropy(start, rotation.h, rotation.l, rotation.u); - addEntropy(length); + addEntropyf(length); addEntropy((int)(type)); } @@ -36,7 +36,7 @@ bool Arbre::split() { for (int i = 0; i < nbBranches; i++) { Vertex bStart = end(floatInRange(seed, 4*i, 0.7f, 0.9f)); Angle3D rot = rotation; - rot = rot.rotateH(Angle::d2r(floatInRange(seed, 4*i+1, 25.f, 37.f) + i*(360.f / (float)nbBranches))); + rot = rot.rotateH(Angle::d2r(floatInRange(seed, 4*i+1, 25.f, 37.f) + (float)i*(360.f / (float)nbBranches))); rot = rot.rotateU(Angle::d2r(floatInRange(seed, 4*i+2, 35.f, 55.f))); float len = length * floatInRange(seed, 4*i+3, tauxMax()*2.f/3.f, tauxMax()); addChild(new Arbre(bStart, rot, len, ARBRE)); @@ -103,7 +103,7 @@ void Arbre::feuille() { Vertex startFeuillage = end(1.f); unsigned int c = Couleurs::feuillage; - if (length < 20 && proba(seed, 12345, 0.04)) + if (length < 20 && proba(seed, 12345, 0.04f)) c = Couleurs::pomme; Quad cFeuillage(startFeuillage +uFeuillage +lFeuillage, startFeuillage -uFeuillage +lFeuillage, startFeuillage -uFeuillage -lFeuillage, startFeuillage +uFeuillage -lFeuillage); diff --git a/rules/arche.cpp b/rules/arche.cpp index dcc49bf..5010e46 100644 --- a/rules/arche.cpp +++ b/rules/arche.cpp @@ -3,7 +3,7 @@ ArcheQuad::ArcheQuad(Quad _c, float _height, float _start, float _end, Type _type) : Chose(), c(_c), height(_height), start(_start), end(_end), type(_type) { if (type == RANDOM) { addEntropy(c); - addEntropy(height); + addEntropyf(height); switch (hash2(seed, 0) % 3) { case 0: type = OGIVE; break; case 1: type = BERCEAU; break; @@ -28,8 +28,8 @@ bool ArcheQuad::split() { void ArcheQuad::triangulation() { Quad ch = c.offsetNormal(height); - Quad che = c.offsetNormal(f(end) * height * 0.9); - Quad chw = c.offsetNormal(f(start) * height * 0.9); + Quad che = c.offsetNormal(f(end) * height * 0.9f); + Quad chw = c.offsetNormal(f(start) * height * 0.9f); addGPUQuad(Quad(ch[NW], chw[NW], che[NE], ch[NE]), Couleurs::mur); addGPUQuad(Quad(ch[SE], che[SE], chw[SW], ch[SW]), Couleurs::mur); addGPUQuad(Quad(che[SE], che[NE], chw[NW], chw[SW]), Couleurs::mur); diff --git a/rules/batiment.cpp b/rules/batiment.cpp index 36b012c..7959ef8 100644 --- a/rules/batiment.cpp +++ b/rules/batiment.cpp @@ -1,13 +1,13 @@ #include "all_includes.hh" -BatimentQuad_::BatimentQuad_(Quad _c, bool _isSub, QuadBool _w) +BatimentQuad::BatimentQuad(Quad _c, bool _isSub, QuadBool _w) : Chose(), c(_c), isSub(_isSub), w(_w) { addEntropy(c); for (int i = 0; i < 4; i++) addEntropy(w[N+i] ? 0 : 1); } -bool BatimentQuad_::split() { +bool BatimentQuad::split() { if (!isSub) { bordureRouteTrottoir(); } else { @@ -25,7 +25,7 @@ bool BatimentQuad_::split() { return true; } -void BatimentQuad_::bordureRouteTrottoir() { +void BatimentQuad::bordureRouteTrottoir() { Quad qtrottoir = c.insetNESW(Dimensions::largeurRoute); Quad qinterieur = qtrottoir.insetNESW(Dimensions::largeurTrottoir); Quad qbatiments = qinterieur.offsetNormal(Dimensions::hauteurTrottoir); @@ -38,13 +38,13 @@ void BatimentQuad_::bordureRouteTrottoir() { bool anglesAcceptable = c.minAngle() > Angle::d2r(90-60) && c.maxAngle() < Angle::d2r(90+60); if (anglesAcceptable && proba(seed, 0, 0.95f)) { - addChild(new BatimentQuad_(qbatiments, true)); + addChild(new BatimentQuad(qbatiments, true)); } else { addChild(new TerrainQuad(qbatiments)); } } -void BatimentQuad_::sousBatiments() { +void BatimentQuad::sousBatiments() { Quad q = c << c.maxLengthSide(); QuadBool qb = w << c.maxLengthSide(); @@ -56,37 +56,31 @@ void BatimentQuad_::sousBatiments() { if (small && qb[E] && proba(seed, 2, 0.3f)) { addChild(new TerrainQuad(Quad(q[SE], s, n, q[NE]))); - addChild(new BatimentQuad_(Quad(q[NW], n, s, q[SW]), true, QuadBool(qb[W],qb[N],true,qb[S]))); + addChild(new BatimentQuad(Quad(q[NW], n, s, q[SW]), true, QuadBool(qb[W],qb[N],true,qb[S]))); } else if (small && qb[W] && proba(seed, 2, 0.5f)) { - addChild(new BatimentQuad_(Quad(q[SE], s, n, q[NE]), true, QuadBool(qb[E],qb[S],true,qb[N]))); + addChild(new BatimentQuad(Quad(q[SE], s, n, q[NE]), true, QuadBool(qb[E],qb[S],true,qb[N]))); addChild(new TerrainQuad(Quad(q[NW], n, s, q[SW]))); } else { - addChild(new BatimentQuad_(Quad(q[SE], s, n, q[NE]), true, QuadBool(qb[E],qb[S],false,qb[N]))); - addChild(new BatimentQuad_(Quad(q[NW], n, s, q[SW]), true, QuadBool(qb[W],qb[N],false,qb[S]))); + addChild(new BatimentQuad(Quad(q[SE], s, n, q[NE]), true, QuadBool(qb[E],qb[S],false,qb[N]))); + addChild(new BatimentQuad(Quad(q[NW], n, s, q[SW]), true, QuadBool(qb[W],qb[N],false,qb[S]))); } } -void BatimentQuad_::etages() { +void BatimentQuad::etages() { // TODO : indiquer aux bâtiments où est-ce qu'ils peuvent faire des fenêtres. float randEtages = floatInRange(seed, 0, 0.f, 1.f); int nbEtages = 1 + (int)(randEtages * randEtages * (Dimensions::maxEtages - 1)); Quad q = c; // c.insetNESW(30) Quad qh; for (int i = 0; i < nbEtages; i++) { - if (nbEtages > 1 && i == 0 && w[N] && w[S]) { - float h = floatInRange(seed, 1+i, Dimensions::hauteurEtage*1.4f, Dimensions::hauteurEtage*1.6f); - qh = q.offsetNormal(h); - addChild(new ArcheQuad(q, h)); - } else { - qh = q.offsetNormal(floatInRange(seed, 1+i, Dimensions::hauteurEtage*0.9f, Dimensions::hauteurEtage*1.1f)); - addChild(new EtageQuad(q, qh, w)); - } + qh = q.offsetNormal(floatInRange(seed, 1+i, Dimensions::hauteurEtage*0.9f, Dimensions::hauteurEtage*1.1f)); + addChild(new EtageQuad(q, qh, w, i, nbEtages)); q = qh; } addChild(new ToitQuad(qh, Dimensions::hauteurToit)); } -void BatimentQuad_::triangulation() { +void BatimentQuad::triangulation() { if (w[N] || w[E] || w[S] || w[W]) { Quad ch = c.offsetNormal(Dimensions::hauteurEtage * 2 + Dimensions::hauteurToit); addGPUQuad(ch, Couleurs::toit); @@ -97,7 +91,7 @@ void BatimentQuad_::triangulation() { } } -void BatimentQuad_::getBoundingBoxPoints() { +void BatimentQuad::getBoundingBoxPoints() { addBBPoints(c, Dimensions::hauteurEtage * 2 + Dimensions::hauteurToit); } diff --git a/rules/batiment.hh b/rules/batiment.hh index 3d73d76..0c7bf69 100644 --- a/rules/batiment.hh +++ b/rules/batiment.hh @@ -3,7 +3,7 @@ #include "all_includes.hh" -class BatimentQuad_ : public Chose { +class BatimentQuad : public Chose { private: Quad c; bool isSub; @@ -13,11 +13,11 @@ private: void etages(); public: - BatimentQuad_(Quad _c, bool _isSub = false, QuadBool _w = QuadBool(true, true, true, true)); + BatimentQuad(Quad _c, bool _isSub = false, QuadBool _w = QuadBool(true, true, true, true)); virtual bool split(); virtual void triangulation(); virtual void getBoundingBoxPoints(); - BatimentQuad_* isSubdivision(bool val); + BatimentQuad* isSubdivision(bool val); }; class BatimentTri_ : public Chose { diff --git a/rules/chose.hh b/rules/chose.hh index 6bd4cbd..838e59a 100644 --- a/rules/chose.hh +++ b/rules/chose.hh @@ -34,6 +34,9 @@ protected : inline void addEntropy(unsigned int x1) { seed = hash2(seed, x1); } + inline void addEntropyf(float f) { + addEntropy(float2uint(f)); + } inline void addEntropy(unsigned int x1, unsigned int x2) { addEntropy(x1); addEntropy(x2); } diff --git a/rules/couleursDimensions.cpp b/rules/couleursDimensions.cpp index 836a1ed..01d9d37 100644 --- a/rules/couleursDimensions.cpp +++ b/rules/couleursDimensions.cpp @@ -2,5 +2,7 @@ const unsigned int Couleurs::fog = mix(cielHaut, cielBas, 0.5); -const float Dimensions::frontFrustum = 1; +const float Dimensions::splitFactor = 5.f; +const float Dimensions::mergeFactor = 6.f; +const float Dimensions::frontFrustum = 1.f; const float Dimensions::backFrustum = 4000 * 100; // 4km diff --git a/rules/couleursDimensions.hh b/rules/couleursDimensions.hh index adbff64..0b6460c 100644 --- a/rules/couleursDimensions.hh +++ b/rules/couleursDimensions.hh @@ -14,14 +14,14 @@ public: static unsigned int mix(unsigned int colorA, unsigned int colorB, float mixA) { float mixB = 1 - mixA; return rgb( - r(colorA) * mixA + r(colorB) * mixB, - g(colorA) * mixA + g(colorB) * mixB, - b(colorA) * mixA + b(colorB) * mixB + (unsigned char)(r(colorA) * mixA + r(colorB) * mixB), + (unsigned char)(g(colorA) * mixA + g(colorB) * mixB), + (unsigned char)(b(colorA) * mixA + b(colorB) * mixB) ); }; static const unsigned int mur = 0xF1E3AD; - static const unsigned int plafond = mur; - static const unsigned int plancher = mur; + static const unsigned int plafond = 0xA39E8B; + static const unsigned int plancher = 0xA5A079; static const unsigned int toit = 0x961618; static const unsigned int route = 0x363636; static const unsigned int trottoir = 0x666666; @@ -47,9 +47,8 @@ public: static const unsigned int minSurfaceSousBatiment = 100 * 100*100; // 100 m² // Qualité - // TODO : devrait être 5.f et 6.f - static const unsigned int splitFactor = 2.f; - static const unsigned int mergeFactor = 3.f; + static const float splitFactor; + static const float mergeFactor; static const unsigned int windowWidth = 1024; static const unsigned int windowHeight = 768; static const float frontFrustum; diff --git a/rules/etage.cpp b/rules/etage.cpp index 316905c..6ae3ed0 100644 --- a/rules/etage.cpp +++ b/rules/etage.cpp @@ -1,6 +1,6 @@ #include "all_includes.hh" -EtageQuad::EtageQuad(Quad _c, Quad _ch, QuadBool _w) : Chose(), c(_c), ch(_ch), w(_w) { +EtageQuad::EtageQuad(Quad _c, Quad _ch, QuadBool _w, int _etage, int _nbEtages) : Chose(), c(_c), ch(_ch), w(_w), etage(_etage), nbEtages(_nbEtages) { addEntropy(c); addEntropy(ch); for (int i = 0; i < 4; i++) @@ -13,20 +13,45 @@ void EtageQuad::getBoundingBoxPoints() { } bool EtageQuad::split() { - Quad me = c.insetOpp(E,28); - Quad ms = c.inset(E,28).inset(W,28).insetOpp(S,28); - Quad mw = c.insetOpp(W,28); - Quad mn = c.inset(E,28).inset(W,28).insetOpp(N,28); - Quad meh = ch.insetOpp(E,28); - Quad msh = ch.inset(E,28).inset(W,28).insetOpp(S,28); - Quad mwh = ch.insetOpp(W,28); - Quad mnh = ch.inset(E,28).inset(W,28).insetOpp(N,28); - - addChild(new MurQuad(me << 1,meh << 1,w[E])); - addChild(new MurQuad(mw >> 1,mwh >> 1,w[W])); - addChild(new MurQuad(mn,mnh,w[N])); - addChild(new MurQuad(ms >> 2,msh >> 2,w[S])); + if (nbEtages > 1 && etage == 0 && ((w[N] && w[S]) || (w[E] && w[W])) && c.minLengthEW() > 800 && proba(seed, 0, 0.4)) { + Quad q = c << ((w[N] && w[S]) ? 0 : 1); + Quad qh = ch << ((w[N] && w[S]) ? 0 : 1); + Vertex n = (q[NW] + q[NE]) / 2.f; + Vertex s = (q[SE] + q[SW]) / 2.f; + Vertex nh = (qh[NW] + qh[NE]) / 2.f; + Vertex sh = (qh[SE] + qh[SW]) / 2.f; + Quad e = Quad(q[NE], q[SE], s, n).inset(W, 200); + Quad w = Quad(n, s, q[SW], q[NW]).inset(E, 200); + Quad eh = Quad(qh[NE], qh[SE], sh, nh).inset(W, 200); + Quad wh = Quad(nh, sh, qh[SW], qh[NW]).inset(E, 200); + Quad ei = e.insetNESW(28, 28, 28, 0); + Quad wi = w.insetNESW(28, 0, 28, 28); + Quad eih = eh.insetNESW(28, 28, 28, 0); + Quad wih = wh.insetNESW(28, 0, 28, 28); + // TODO : ArcheQuad(q, q); + addChild(new ArcheQuad(Quad(e[NW], e[SW], w[SE], w[NE]), Segment(qh[NE], q[NE]).length())); + // Mur sur e[N], e[E], e[S], w[S], w[W], w[N]; + for (int i = 0; i < 3; i++) { + addChild(new MurQuad(Quad(e[NE+i], ei[NE+i], ei[NW+i], e[NW+i]), Quad(eh[NE+i], eih[NE+i], eih[NW+i], eh[NW+i]))); + addChild(new MurQuad(Quad(w[SE+i], w[SW+i], wi[SW+i], wi[SE+i]), Quad(wh[SE+i], wh[SW+i], wih[SW+i], wih[SE+i]))); + } + } else { + Quad me = c.insetOpp(E,28); + Quad ms = c.inset(E,28).inset(W,28).insetOpp(S,28); + Quad mw = c.insetOpp(W,28); + Quad mn = c.inset(E,28).inset(W,28).insetOpp(N,28); + Quad meh = ch.insetOpp(E,28); + Quad msh = ch.inset(E,28).inset(W,28).insetOpp(S,28); + Quad mwh = ch.insetOpp(W,28); + Quad mnh = ch.inset(E,28).inset(W,28).insetOpp(N,28); + addChild(new MurQuad(me << 1,meh << 1,w[E])); + addChild(new MurQuad(mw >> 1,mwh >> 1,w[W])); + addChild(new MurQuad(mn,mnh,w[N])); + addChild(new MurQuad(ms >> 2,msh >> 2,w[S])); + } + addChild(new PlancherPlafond(c, PlancherPlafond::PLANCHER)); + addChild(new PlancherPlafond(ch.offsetNormal(-10), PlancherPlafond::PLAFOND)); return true; } diff --git a/rules/etage.hh b/rules/etage.hh index cb1c5fe..15952db 100644 --- a/rules/etage.hh +++ b/rules/etage.hh @@ -9,9 +9,11 @@ class EtageQuad : public Chose { Quad c; Quad ch; QuadBool w; + int etage; + int nbEtages; public : - EtageQuad(Quad c, Quad ch, QuadBool _w); + EtageQuad(Quad c, Quad ch, QuadBool _w, int _etage, int _nbEtages); virtual bool split(); virtual void triangulation(); virtual void getBoundingBoxPoints(); diff --git a/rules/mur.cpp b/rules/mur.cpp index fa1d444..c0e4dcb 100644 --- a/rules/mur.cpp +++ b/rules/mur.cpp @@ -14,7 +14,7 @@ void MurQuad::getBoundingBoxPoints() { void MurQuad::setWindow() { Quad q = Quad(ch[NE],c[NE],c[NW],ch[NW]); - int lr = (q.length(S) - 120)/2; + float lr = (q.length(S) - 120)/2.f; Quad wFront = q.insetNESW(40,lr,120,lr); Quad wBack = wFront.offsetNormal(28); @@ -54,5 +54,21 @@ bool MurQuad::split() { } void MurQuad::triangulation() { - addGPUOcto(c, ch, Couleurs::mur); + addGPUFourQuads(c, ch, Couleurs::mur); +} + +PlancherPlafond::PlancherPlafond(Quad _c, Type _type) : Chose(), c(_c), type(_type) { + addEntropy(c); + addEntropy((int)type); +} + +void PlancherPlafond::triangulation() { + unsigned int clr = Couleurs::plancher; + if (type == PLAFOND) + clr = Couleurs::plafond; + addGPUQuad(c, clr); +} + +void PlancherPlafond::getBoundingBoxPoints() { + addBBPoints(c); } diff --git a/rules/mur.hh b/rules/mur.hh index cadd436..92a23c9 100644 --- a/rules/mur.hh +++ b/rules/mur.hh @@ -4,14 +4,14 @@ #include "all_includes.hh" class MurQuad: public Chose { - private : +private : Quad c; Quad ch; bool window; // Contient une fenêtre ou non. Quad windowPos; Quad windowPosh; - public : +public : MurQuad(Quad c, Quad ch, bool _window=false); virtual void triangulation(); @@ -20,5 +20,21 @@ class MurQuad: public Chose { void setWindow(); }; +class PlancherPlafond: public Chose { +public: + enum Type { + PLANCHER, + PLAFOND + }; +private: + Quad c; + Type type; + +public: + PlancherPlafond(Quad _c, Type _type); + virtual void triangulation(); + virtual void getBoundingBoxPoints(); +}; + #endif diff --git a/rules/quartier.cpp b/rules/quartier.cpp index 8ecc641..c164226 100644 --- a/rules/quartier.cpp +++ b/rules/quartier.cpp @@ -31,7 +31,7 @@ bool QuartierQuad::split() { else if (!small) carre(); else - addChild(new BatimentQuad_(c)); + addChild(new BatimentQuad(c)); return true; } @@ -116,7 +116,7 @@ void QuartierQuad::longueRue() { addChild(new QuartierQuad(qn)); addChild(new QuartierQuad(qs)); - addChild(new BatimentQuad_(Quad(qn[SE], qs[SW], qs[SE], qn[SW]))); // TODO + addChild(new BatimentQuad(Quad(qn[SE], qs[SW], qs[SE], qn[SW]))); // TODO } QuartierTri::QuartierTri(Triangle _c) : Chose(), c(_c) { diff --git a/rules/terrain.cpp b/rules/terrain.cpp index fbf7dc5..3e7118a 100644 --- a/rules/terrain.cpp +++ b/rules/terrain.cpp @@ -9,12 +9,12 @@ bool TerrainQuad::split() { addChild(new TerrainQuad(c, false)); + Vertex p[10]; int maxNArbres = std::min(10, (int)(c.surface() / (7.f*7.f*100.f*100.f))); - Vertex p[maxNArbres]; int pi = 0; int nArbres = hash2(seed, -1) % (maxNArbres + 1); for (int essai = 0; essai < nArbres * 2 && pi < nArbres; essai++) { - p[pi] = c.insetProportionnal(0.7).randomPoint(seed, essai); + p[pi] = c.insetProportionnal(0.7f).randomPoint(seed, essai); bool success = true; for (int j = 0; j < pi; j++) { if (Segment(p[j], p[pi]).length() < 3 * 100) { diff --git a/rules/toit.hh b/rules/toit.hh index 66e50be..e20cc45 100644 --- a/rules/toit.hh +++ b/rules/toit.hh @@ -17,9 +17,6 @@ private: void deuxPoints(); void deuxPointsVerticaux(); void plat(); - static const char r = 0xF1; - static const char g = 0xE0; - static const char b = 0xE0; }; class ToitTri : public Chose { diff --git a/view.cpp b/view.cpp index 1531044..61c3f4b 100644 --- a/view.cpp +++ b/view.cpp @@ -2,7 +2,7 @@ View::View(Chose* _root) : root(_root), - camera(Camera(Vertex(2980,1567,16012), 45, 150, 10000, 0.6f)), + camera(Camera(Vertex(0,0,5000), 45, 100, 10000, 0.6f)), lod(camera.cameraCenter, _root) { fogColor[0] = Couleurs::r(Couleurs::fog) / 255.f; @@ -49,8 +49,8 @@ void View::initWindow() { glEnable (GL_FOG); glFogi (GL_FOG_MODE, GL_LINEAR); glFogfv (GL_FOG_COLOR, fogColor); - glFogf (GL_FOG_START, Dimensions::backFrustum / sqrt(3) / 2.f); - glFogf (GL_FOG_END, Dimensions::backFrustum / sqrt(3) * 0.9); + glFogf (GL_FOG_START, Dimensions::backFrustum / std::sqrt(3.f) / 2.f); + glFogf (GL_FOG_END, Dimensions::backFrustum / std::sqrt(3.f) * 0.9f); //glHint (GL_FOG_HINT, GL_NICEST); } @@ -94,7 +94,7 @@ void View::displayAxes() { void View::setSkybox() { //int z = 40000; - float d = Dimensions::backFrustum / std::sqrt(3) * 0.9; + float d = Dimensions::backFrustum / std::sqrt(3.f) * 0.9f; glDisable(GL_FOG); glDisable(GL_LIGHTING); glPushMatrix();