2011-m2s3-city-builder/rules/architecture/arbre.cpp
2012-01-19 10:48:50 +01:00

98 lines
3.1 KiB
C++

#include "all_includes.hh"
Arbre::Arbre(Vertex _start, Triangle plane) : start(_start), type(ARBRE) {
addEntropy(start);
addEntropy(plane);
Vertex h = plane.normalizedNormal();
Vertex l = (plane[TOP] - plane[LEFT]).normalize();
Vertex u = h * l;
rotation = Angle3D(h, l, u);
rotation = rotation.rotateH(floatInRange(seed, -3, 0, 2*Angle::Pi));
rotation = rotation.rotateU(floatInRange(seed, -4, Angle::d2r(-10), Angle::d2r(10)));
length = floatInRange(seed, -5, 3*100, 4*100);
}
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);
addEntropy((int)(type));
}
bool Arbre::split() {
if (type == ARBRE && length > floatInRange(seed, -1, 10, 20)) {
int nbBranches = 2 + (hash2(seed, -2) % 3);
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.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));
}
addChild(new Arbre(start, rotation, length, TRONC));
}
return true;
}
void Arbre::triangulation() {
if (type == ARBRE || type == TRONC) tronc();
if (type == ARBRE) feuille();
}
void Arbre::getBoundingBoxPoints() {
// TODO
Vertex u = rotation.u * limitLength() / 2.f;
Vertex l = rotation.l * limitLength() / 2.f;
Quad c(start +u +l, start -u +l, start -u -l, start +u -l);
addBBPoints(c, length + limitLength());
}
float Arbre::LODFactor() {
return 4.f;
}
Vertex Arbre::end(float position) const {
return (start + rotation.h * length * position);
}
float Arbre::tauxMax() {
return 0.6f;
}
const float Arbre::limitLengthFactor = calcLimitLengthFactor();
float Arbre::calcLimitLengthFactor() {
float limit = 0;
for (float i = 1; i > 0.001; i = i * tauxMax())
limit += i;
return limit - 1;
}
float Arbre::limitLength() const {
return length * limitLengthFactor;
}
float Arbre::maxRadius(float length) {
return length * (1+limitLengthFactor);
}
void Arbre::tronc() {
float radius = length/16;
Vertex hTronc = end(1.f) - start;
Vertex uTronc = rotation.u * radius;
Vertex lTronc = rotation.l * radius;
Quad cTronc(start +uTronc +lTronc, start -uTronc +lTronc, start -uTronc -lTronc, start +uTronc -lTronc);
addGPUQuad(cTronc + hTronc, Couleurs::tronc);
addGPUFourQuads(cTronc, cTronc + hTronc, Couleurs::tronc);
}
void Arbre::feuille() {
Vertex hFeuillage = rotation.h * limitLength();
Vertex uFeuillage = rotation.u * limitLength() / 2.f;
Vertex lFeuillage = rotation.l * limitLength() / 2.f;
Vertex startFeuillage = end(1.f);
Quad cFeuillage(startFeuillage +uFeuillage +lFeuillage, startFeuillage -uFeuillage +lFeuillage, startFeuillage -uFeuillage -lFeuillage, startFeuillage +uFeuillage -lFeuillage);
addGPUOcto(cFeuillage, cFeuillage + hFeuillage, Couleurs::feuillage);
}