www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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 }