diff --git a/rules/architecture/arbre.cpp b/rules/architecture/arbre.cpp index a1aea6c..00804b0 100644 --- a/rules/architecture/arbre.cpp +++ b/rules/architecture/arbre.cpp @@ -102,6 +102,10 @@ void Arbre::feuille() { Vertex lFeuillage = rotation.l * limitLength() / 2.f; Vertex startFeuillage = end(1.f); + unsigned int c = Couleurs::feuillage; + if (length < 20 && proba(seed, 12345, 0.04)) + c = Couleurs::pomme; + Quad cFeuillage(startFeuillage +uFeuillage +lFeuillage, startFeuillage -uFeuillage +lFeuillage, startFeuillage -uFeuillage -lFeuillage, startFeuillage +uFeuillage -lFeuillage); - addGPUOcto(cFeuillage, cFeuillage + hFeuillage, Couleurs::feuillage); + addGPUOcto(cFeuillage, cFeuillage + hFeuillage, c); } diff --git a/rules/architecture/batiment.cpp b/rules/architecture/batiment.cpp index 7458b11..b56a968 100644 --- a/rules/architecture/batiment.cpp +++ b/rules/architecture/batiment.cpp @@ -8,44 +8,77 @@ BatimentQuad_::BatimentQuad_(Quad _c, bool _isSub, QuadBool _w) } bool BatimentQuad_::split() { - int minSurface = 100 * 100 * 100; - Quad q = c << c.maxLengthSide(); - QuadBool qb = w << c.maxLengthSide(); - - if (qb[N] || qb[E] || qb[S] || qb[W]) { - if (q.surface() > 2 * minSurface) { - Vertex n = Segment(q[NW], q[NE]).randomPos(seed, 0, 1.f/3.f, 1.f/2.f); - Vertex s = Segment(q[SE], q[SW]).randomPos(seed, 1, 1.f/3.f, 1.f/2.f); - - if (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]))); - } else if (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 TerrainQuad(Quad(q[NW], n, s, q[SW]))); + if (!isSub) { + bordureRouteTrottoir(); + } else { + if (w[N] || w[E] || w[S] || w[W]) { + if (c.surface() > 2 * Dimensions::minSurfaceSousBatiment) { + sousBatiments(); } 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]))); + etages(); } } else { - 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++) { - qh = q.offsetNormal(floatInRange(seed, 1+i, Dimensions::hauteurEtage*0.9f, Dimensions::hauteurEtage*1.1f)); - addChild(new EtageQuad(q,qh)); - q = qh; - } - addChild(new ToitQuad(qh, Dimensions::hauteurToit)); + addChild(new TerrainQuad(c)); } - } else { - addChild(new TerrainQuad(c)); } return true; } +void BatimentQuad_::bordureRouteTrottoir() { + Quad qtrottoir = c.insetNESW(Dimensions::largeurRoute); + Quad qinterieur = qtrottoir.insetNESW(Dimensions::largeurTrottoir); + Quad qbatiments = qinterieur.offsetNormal(Dimensions::hauteurTrottoir); + + for (int i = 0; i < 4; i++) { + addChild(new RouteQuad(Quad(c[NE+i],c[SE+i],qtrottoir[SE+i],qtrottoir[NE+i]))); + addChild(new TrottoirQuad(Quad(qtrottoir[NE+i],qtrottoir[SE+i],qinterieur[SE+i],qinterieur[NE+i]))); + } + + 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)); + } else { + addChild(new TerrainQuad(qbatiments)); + } +} + +void BatimentQuad_::sousBatiments() { + Quad q = c << c.maxLengthSide(); + QuadBool qb = w << c.maxLengthSide(); + + Vertex n = Segment(q[NW], q[NE]).randomPos(seed, 0, 1.f/3.f, 1.f/2.f); + Vertex s = Segment(q[SE], q[SW]).randomPos(seed, 1, 1.f/3.f, 1.f/2.f); + + bool small = q.surface() < 4 * Dimensions::minSurfaceSousBatiment; + + 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]))); + } 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 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]))); + } +} + +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++) { + qh = q.offsetNormal(floatInRange(seed, 1+i, Dimensions::hauteurEtage*0.9f, Dimensions::hauteurEtage*1.1f)); + addChild(new EtageQuad(q,qh)); + q = qh; + } + addChild(new ToitQuad(qh, Dimensions::hauteurToit)); +} + void BatimentQuad_::triangulation() { Quad ch = c.offsetNormal(Dimensions::hauteurEtage + Dimensions::hauteurToit); addGPUQuad(ch, Couleurs::toit); diff --git a/rules/architecture/batiment.hh b/rules/architecture/batiment.hh index 189456f..df6c51e 100644 --- a/rules/architecture/batiment.hh +++ b/rules/architecture/batiment.hh @@ -4,12 +4,16 @@ #include "all_includes.hh" class BatimentQuad_ : public Chose { +private: Quad c; - bool isSub; - QuadBool w; + bool isSub; + QuadBool w; + void bordureRouteTrottoir(); + void sousBatiments(); + void etages(); - public: - BatimentQuad_(Quad _c, bool _isSub=false, QuadBool _w = QuadBool(true, true, true, true)); +public: + BatimentQuad_(Quad _c, bool _isSub = false, QuadBool _w = QuadBool(true, true, true, true)); virtual bool split(); virtual void triangulation(); virtual void getBoundingBoxPoints(); @@ -19,7 +23,7 @@ class BatimentQuad_ : public Chose { class BatimentTri_ : public Chose { Triangle c; - public: +public: BatimentTri_(Triangle _c); virtual bool split(); virtual void triangulation(); diff --git a/rules/architecture/couleursDimensions.hh b/rules/architecture/couleursDimensions.hh index fd4f40a..8c56d52 100644 --- a/rules/architecture/couleursDimensions.hh +++ b/rules/architecture/couleursDimensions.hh @@ -28,6 +28,7 @@ public: static const unsigned int bordureTrottoir = 0xAAAAAA; static const unsigned int herbe = 0x0c4010; static const unsigned int feuillage = 0x11AA22; + static const unsigned int pomme = 0xAA2211; static const unsigned int tronc = 0x906050; static const unsigned int cielHaut = 0x3c14ff; static const unsigned int cielBas = 0x7F7FFF; @@ -43,6 +44,7 @@ public: static const unsigned int hauteurToit = 200; static const unsigned int hauteurTrottoir = 20; static const unsigned int hauteurMaxBatiment = hauteurTrottoir + hauteurEtage + hauteurToit; + static const unsigned int minSurfaceSousBatiment = 100 * 100*100; // 100 m² // Qualité // TODO : devrait être 5.f et 6.f diff --git a/rules/architecture/quartier.cpp b/rules/architecture/quartier.cpp index f1d4d4b..8ecc641 100644 --- a/rules/architecture/quartier.cpp +++ b/rules/architecture/quartier.cpp @@ -31,7 +31,7 @@ bool QuartierQuad::split() { else if (!small) carre(); else - batiments(); + addChild(new BatimentQuad_(c)); return true; } @@ -119,25 +119,6 @@ void QuartierQuad::longueRue() { addChild(new BatimentQuad_(Quad(qn[SE], qs[SW], qs[SE], qn[SW]))); // TODO } -void QuartierQuad::batiments() { - Quad qtrottoir = c.insetNESW(Dimensions::largeurRoute); - Quad qinterieur = qtrottoir.insetNESW(Dimensions::largeurTrottoir); - Quad qbatiments = qinterieur.offsetNormal(Dimensions::hauteurTrottoir); - - for (int i = 0; i < 4; i++) { - addChild(new RouteQuad(Quad(c[NE+i],c[SE+i],qtrottoir[SE+i],qtrottoir[NE+i]))); - addChild(new TrottoirQuad(Quad(qtrottoir[NE+i],qtrottoir[SE+i],qinterieur[SE+i],qinterieur[NE+i]))); - } - - 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)); - } else { - addChild(new TerrainQuad(qbatiments)); - } -} - QuartierTri::QuartierTri(Triangle _c) : Chose(), c(_c) { addEntropy(c); } @@ -156,7 +137,7 @@ bool QuartierTri::split() { bool angleAigu = minAngle < Angle::d2r(30); bool anglesAcceptable = !angleAigu && !angleObtus; if (!big && proba(seed, -1, 0.05f)) { - batiments(); + batiments(); // TODO : addChild(new BatimentTri_(c)); } else if (big && anglesAcceptable) { switch (hash2(seed, -2) % 3) { case 0: centre(); break; @@ -171,7 +152,7 @@ bool QuartierTri::split() { } else if (!small) { trapeze(); } else { - batiments(); + batiments(); // TODO : addChild(new BatimentTri_(c)); } return true; } diff --git a/rules/architecture/quartier.hh b/rules/architecture/quartier.hh index 633aa42..583326e 100644 --- a/rules/architecture/quartier.hh +++ b/rules/architecture/quartier.hh @@ -19,7 +19,6 @@ private: void rect(); void carre(); void longueRue(); - void batiments(); }; class QuartierTri: public Chose {