batiment.cpp (6342B)
1 #include "all_includes.hh" 2 3 BatimentQuad::BatimentQuad(Quad _c, bool _isSub, QuadBool _w) 4 : Chose(), c(_c), isSub(_isSub), w(_w) { 5 addEntropy(c); 6 for (int i = 0; i < 4; i++) 7 addEntropy(w[N+i] ? 0 : 1); 8 } 9 10 void BatimentQuad::split() { 11 if (!isSub) { 12 bordureRouteTrottoir(); 13 } else { 14 if (w[N] || w[E] || w[S] || w[W]) { 15 if (c.surface() > 2 * Dimensions::minSurfaceSousBatiment) { 16 sousBatiments(); 17 } else { 18 etages(); 19 } 20 } else { 21 addChild(new TerrainQuad(c)); 22 } 23 } 24 } 25 26 void BatimentQuad::bordureRouteTrottoir() { 27 Quad qinterieur = c.insetNESW(Dimensions::largeurRoute + Dimensions::largeurTrottoir); 28 Quad qbatiments = qinterieur.offsetNormal(Dimensions::hauteurTrottoir); 29 30 for (int i = 0; i < 4; i++) { 31 addChild(new RouteTrottoirQuad(Quad(c[NE+i],c[SE+i],qinterieur[SE+i],qinterieur[NE+i]))); 32 } 33 34 bool anglesAcceptable = c.minAngle() > Angle::d2r(90-60) && c.maxAngle() < Angle::d2r(90+60); 35 36 if (anglesAcceptable && proba(seed, 0, 0.95f)) { 37 addChild(new BatimentQuad(qbatiments, true)); 38 } else { 39 addChild(new TerrainQuad(qbatiments)); 40 } 41 } 42 43 void BatimentQuad::sousBatiments() { 44 Quad q = c << c.maxLengthSide(); 45 QuadBool qb = w << c.maxLengthSide(); 46 47 float posDelta = std::min(1.f/6.f, q.minLengthEW() / q.length(N) * 0.2f); 48 Vertex n = Segment(q[NW], q[NE]).randomPos(seed, 0, 0.5f - posDelta, 0.5f + posDelta); 49 Vertex s = Segment(q[SE], q[SW]).randomPos(seed, 1, 0.5f - posDelta, 0.5f + posDelta); 50 51 bool small = q.surface() < 4 * Dimensions::minSurfaceSousBatiment; 52 53 if (small && qb[E] && proba(seed, 2, 0.3f)) { 54 addChild(new TerrainQuad(Quad(q[SE], s, n, q[NE]))); 55 addChild(new BatimentQuad(Quad(q[NW], n, s, q[SW]), true, QuadBool(qb[W],qb[N],true,qb[S]))); 56 } else if (small && qb[W] && proba(seed, 2, 0.5f)) { 57 addChild(new BatimentQuad(Quad(q[SE], s, n, q[NE]), true, QuadBool(qb[E],qb[S],true,qb[N]))); 58 addChild(new TerrainQuad(Quad(q[NW], n, s, q[SW]))); 59 } else { 60 addChild(new BatimentQuad(Quad(q[SE], s, n, q[NE]), true, QuadBool(qb[E],qb[S],false,qb[N]))); 61 addChild(new BatimentQuad(Quad(q[NW], n, s, q[SW]), true, QuadBool(qb[W],qb[N],false,qb[S]))); 62 } 63 } 64 65 void BatimentQuad::etages() { 66 float randEtages = floatInRange(seed, 0, 0.f, 1.f); 67 int nbEtages = 1 + (int)(randEtages * randEtages * (Dimensions::maxEtages - 1)); 68 Quad q = c; // c.insetNESW(30) 69 Quad qh; 70 for (int i = 0; i < nbEtages; i++) { 71 qh = q.offsetNormal(floatInRange(seed, 1+i, Dimensions::hauteurEtage*0.9f, Dimensions::hauteurEtage*1.1f)); 72 addChild(new EtageQuad(q, qh, w, i, nbEtages)); 73 q = qh; 74 } 75 addChild(new ToitQuad(qh, Dimensions::hauteurToit)); 76 } 77 78 void BatimentQuad::triangulation() { 79 if (w[N] || w[E] || w[S] || w[W]) { 80 Quad ch = c.offsetNormal(Dimensions::hauteurEtage * 2 + Dimensions::hauteurToit); 81 addGPUQuad(ch, Couleurs::toit); 82 for (int i = 0; i < 4; i++) 83 addGPUQuad(Quad(c[NE+i], c[SE+i], ch[SE+i], ch[NE+i]), Couleurs::mur); 84 } else { 85 addGPUQuad(c, Couleurs::herbe); 86 } 87 } 88 89 void BatimentQuad::getBoundingBoxPoints() { 90 addBBPoints(c, Dimensions::hauteurEtage * 2 + Dimensions::hauteurToit); 91 } 92 93 BatimentTri::BatimentTri(Triangle _c, bool _isSub, TriBool _w) 94 : Chose(), c(_c), isSub(_isSub), w(_w) { 95 addEntropy(c); 96 for (int i = 0; i < 3; i++) 97 addEntropy(w[LEFTSIDE+i] ? 0 : 1); 98 } 99 100 void BatimentTri::split() { 101 if (!isSub) { 102 bordureRouteTrottoir(); 103 } else { 104 if (w[LEFTSIDE] || w[RIGHTSIDE] || w[BASE]) { 105 if (c.surface() > 2 * Dimensions::minSurfaceSousBatiment) { 106 sousBatiments(); 107 } else { 108 etages(); 109 } 110 } else { 111 addChild(new TerrainTri(c)); 112 } 113 } 114 } 115 116 void BatimentTri::triangulation() { 117 Triangle th = c.offsetNormal(Dimensions::hauteurEtage * 2 + Dimensions::hauteurToit); 118 addGPUTriangle(th, Couleurs::toit); 119 for (int i = 0; i < 3; i++) 120 addGPUQuad(Quad(c[LEFT+i], c[TOP+i], th[TOP+i], th[LEFT+i]), Couleurs::mur); 121 } 122 123 void BatimentTri::getBoundingBoxPoints() { 124 addBBPoints(c, Dimensions::hauteurEtage * 2 + Dimensions::hauteurToit); 125 } 126 127 void BatimentTri::bordureRouteTrottoir() { 128 Triangle tinterieur = c.insetLTR(Dimensions::largeurRoute + Dimensions::largeurTrottoir); 129 Triangle tbatiments = tinterieur.offsetNormal(Dimensions::hauteurTrottoir); 130 131 for (int i = 0; i < 4; i++) { 132 addChild(new RouteTrottoirQuad(Quad(c[LEFT+i],c[TOP+i],tinterieur[TOP+i],tinterieur[LEFT+i]))); 133 } 134 135 bool anglesAcceptable = c.minAngle() > Angle::d2r(90-60) && c.maxAngle() < Angle::d2r(90+60); 136 137 if (anglesAcceptable && proba(seed, 0, 0.95f)) { 138 addChild(new BatimentTri(tbatiments, true)); 139 } else { 140 addChild(new TerrainTri(tbatiments)); 141 } 142 } 143 144 void BatimentTri::sousBatiments() { 145 Triangle t = c << c.minAngleCorner(); 146 TriBool tb = w << c.minAngleCorner(); 147 148 Vertex left = Segment(t[LEFT], t[TOP]).randomPos(seed, 0, 1.f/3.f, 2.f/3.f); 149 float dLeft = Segment(t[LEFT], left).length(); 150 float posBase = dLeft / Segment(t[LEFT], t[RIGHT]).length(); 151 if (posBase < 0.3f) posBase = 0.2f; 152 else if (posBase > 0.7f) posBase = 0.8f; 153 Vertex base = Segment(t[RIGHT], t[LEFT]).randomPos(seed, 1, posBase - 0.1f, posBase + 0.1f); 154 155 bool small = t.surface() < 4 * Dimensions::minSurfaceSousBatiment; 156 157 if (small && (tb[LEFTSIDE] || tb[RIGHTSIDE]) && proba(seed, 2, 0.3f)) { 158 addChild(new TerrainTri(Triangle(base, t[LEFT], left))); 159 addChild(new BatimentQuad(Quad(base, left, t[TOP], t[RIGHT]), true, QuadBool(true, w[LEFTSIDE], w[RIGHTSIDE], w[BASE]))); 160 } else if (small && (tb[LEFTSIDE] || tb[RIGHTSIDE] || tb[BASE]) && proba(seed, 2, 0.3f)) { 161 addChild(new BatimentTri(Triangle(base, t[LEFT], left), true, TriBool(w[BASE], w[LEFTSIDE], true))); 162 addChild(new TerrainQuad(Quad(base, left, t[TOP], t[RIGHT]))); 163 } else { 164 addChild(new BatimentTri(Triangle(base, t[LEFT], left), true, TriBool(w[BASE], w[LEFTSIDE], false))); 165 addChild(new BatimentQuad(Quad(base, left, t[TOP], t[RIGHT]), true, QuadBool(false, w[LEFTSIDE], w[RIGHTSIDE], w[BASE]))); 166 } 167 } 168 169 void BatimentTri::etages() { 170 float randEtages = floatInRange(seed, 0, 0.f, 1.f); 171 int nbEtages = 1 + (int)(randEtages * randEtages * (Dimensions::maxEtages - 1)); 172 Triangle t = c; // c.insetNESW(30) 173 Triangle th; 174 for (int i = 0; i < nbEtages; i++) { 175 th = t.offsetNormal(floatInRange(seed, 1+i, Dimensions::hauteurEtage*0.9f, Dimensions::hauteurEtage*1.1f)); 176 addChild(new EtageTri(t, th, w, i, nbEtages)); 177 t = th; 178 } 179 addChild(new ToitTri(th, Dimensions::hauteurToit)); 180 }