This commit is contained in:
Yoann 2012-01-19 10:50:17 +01:00
commit 6b692b48a5
16 changed files with 222 additions and 12 deletions

View File

@ -20,9 +20,9 @@ class Chose;
#include <GL/glu.h> #include <GL/glu.h>
#include <GL/gl.h> #include <GL/gl.h>
#include "geometry/angle.hh"
#include "geometry/directions.hh" #include "geometry/directions.hh"
#include "geometry/vertex.hh" #include "geometry/vertex.hh"
#include "geometry/angle.hh"
#include "geometry/segment.hh" #include "geometry/segment.hh"
#include "geometry/triangle.hh" #include "geometry/triangle.hh"
#include "geometry/quad.hh" #include "geometry/quad.hh"
@ -38,6 +38,7 @@ class Chose;
#include "rules/chose.hh" #include "rules/chose.hh"
#include "rules/architecture/couleursDimensions.hh" #include "rules/architecture/couleursDimensions.hh"
#include "rules/architecture/arbre.hh"
#include "rules/architecture/arche.hh" #include "rules/architecture/arche.hh"
#include "rules/architecture/batiment.hh" #include "rules/architecture/batiment.hh"
#include "rules/architecture/quartier.hh" #include "rules/architecture/quartier.hh"

View File

@ -2,3 +2,19 @@
float Angle::r2d(float rad) { return rad / Pi * 180; } float Angle::r2d(float rad) { return rad / Pi * 180; }
float Angle::d2r(float deg) { return deg / 180 * Pi; } float Angle::d2r(float deg) { return deg / 180 * Pi; }
Angle3D::Angle3D() : h(Vertex(1,0,0)), l(Vertex(0,1,0)), u(Vertex(0,0,1)) {}
Angle3D::Angle3D(Vertex _h, Vertex _l, Vertex _u) : h(_h), l(_l), u(_u) {}
// Formules : http://www.nbb.cornell.edu/neurobio/land/OldStudentProjects/cs490-94to95/hwchen/
Angle3D Angle3D::rotateH(float angle) const {
return Angle3D(h, l*std::cos(angle) + u*std::sin(angle), l*-std::sin(angle) + u*std::cos(angle));
}
Angle3D Angle3D::rotateL(float angle) const {
return Angle3D(h*std::cos(angle) + u*std::sin(angle), l, h*-std::sin(angle) + u*std::cos(angle));
}
Angle3D Angle3D::rotateU(float angle) const {
return Angle3D(h*std::cos(angle) + l*-std::sin(angle), h*std::sin(angle) + l*std::cos(angle), u);
}

View File

@ -1,6 +1,8 @@
#ifndef _GEOMETRY_ANGLE_HH_ #ifndef _GEOMETRY_ANGLE_HH_
#define _GEOMETRY_ANGLE_HH_ #define _GEOMETRY_ANGLE_HH_
#include "all_includes.hh"
namespace Angle { namespace Angle {
const double dPi = 3.141592653589793238462643383279; const double dPi = 3.141592653589793238462643383279;
const float Pi = (float)(dPi); const float Pi = (float)(dPi);
@ -8,4 +10,16 @@ namespace Angle {
float d2r(float deg); float d2r(float deg);
} }
class Angle3D {
public:
Vertex h;
Vertex l;
Vertex u;
Angle3D();
Angle3D(Vertex _h, Vertex _l, Vertex _u);
Angle3D rotateH(float angle) const;
Angle3D rotateL(float angle) const;
Angle3D rotateU(float angle) const;
};
#endif #endif

View File

@ -243,3 +243,11 @@ Quad Quad::offsetNormal(float offset) const {
Vertex Quad::normal() const { Vertex Quad::normal() const {
return Triangle(c[NE], c[SE], c[SW]).normal(); return Triangle(c[NE], c[SE], c[SW]).normal();
} }
Vertex Quad::normalizedNormal() const {
return Triangle(c[NE], c[SE], c[SW]).normalizedNormal();
}
Vertex Quad::moyenne() const {
return ((c[NE] + c[SE] + c[SW] + c[NW]) / 4.f);
}

View File

@ -51,6 +51,8 @@ class Quad {
Quad insetProportionnal(float prop); Quad insetProportionnal(float prop);
Quad offsetNormal(float offset) const; Quad offsetNormal(float offset) const;
Vertex normal() const; Vertex normal() const;
Vertex normalizedNormal() const;
Vertex moyenne() const;
}; };

View File

@ -21,6 +21,10 @@ Vertex Vertex::setNorm(float n) const {
return (*this * n / norm()); return (*this * n / norm());
} }
Vertex Vertex::normalize() const {
return (*this / norm());
}
float Vertex::cosAngle(Vertex v) const { float Vertex::cosAngle(Vertex v) const {
// http://www.developpez.net/forums/d202580/applications/developpement-2d-3d-jeux/contribuez/faq-mat-quat-ajout-calculs-vectoriels/ // http://www.developpez.net/forums/d202580/applications/developpement-2d-3d-jeux/contribuez/faq-mat-quat-ajout-calculs-vectoriels/
return ((this->x*v.x + this->y*v.y + this->z*v.z) / (norm()*v.norm())); return ((this->x*v.x + this->y*v.y + this->z*v.z) / (norm()*v.norm()));

View File

@ -15,6 +15,7 @@ class Vertex {
float norm() const; float norm() const;
Vertex projectOn(Vertex v) const; Vertex projectOn(Vertex v) const;
Vertex setNorm(float n) const; Vertex setNorm(float n) const;
Vertex normalize() const;
float cosAngle(Vertex v) const; // cosinus de l'angle entre this et v. float cosAngle(Vertex v) const; // cosinus de l'angle entre this et v.
float angle(Vertex v) const; // Angle entre this et v. float angle(Vertex v) const; // Angle entre this et v.
static Vertex fromSpherical(float r, float xAngle, float yAngle); static Vertex fromSpherical(float r, float xAngle, float yAngle);
@ -24,7 +25,7 @@ class Vertex {
friend Vertex operator+(const Vertex& u, const Vertex& v); friend Vertex operator+(const Vertex& u, const Vertex& v);
friend Vertex operator-(const Vertex& u, const Vertex& v); friend Vertex operator-(const Vertex& u, const Vertex& v);
friend Vertex operator-(const Vertex& v); friend Vertex operator-(const Vertex& v);
friend Vertex operator*(const Vertex& v, const float n); friend Vertex operator*(const Vertex& v, const float n); // Cross product
friend Vertex operator*(const Vertex& u, const Vertex& v); friend Vertex operator*(const Vertex& u, const Vertex& v);
friend Vertex operator/(const Vertex& v, const float f); friend Vertex operator/(const Vertex& v, const float f);
}; };

View File

@ -0,0 +1,97 @@
#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);
}

View File

@ -0,0 +1,34 @@
#ifndef _RULES_ARCHITECTURE_ARBRE_HH_
#define _RULES_ARCHITECTURE_ARBRE_HH_
#include "all_includes.hh"
class Arbre : public Chose {
public:
enum Type {
ARBRE,
TRONC
};
private:
Vertex start;
Angle3D rotation;
float length;
Type type;
Vertex end(float position) const;
float limitLength() const;
static float tauxMax();
static float calcLimitLengthFactor();
static const float limitLengthFactor;
public:
static float maxRadius(float length);
Arbre(Vertex _start, Triangle plane);
Arbre(Vertex _start, Angle3D _rotation, float _length, Type _type = ARBRE);
virtual bool split();
virtual void triangulation();
virtual void getBoundingBoxPoints();
virtual float LODFactor();
void tronc();
void feuille();
};
#endif

View File

@ -6,7 +6,7 @@ BatimentQuad_::BatimentQuad_(Quad _c, bool _isSub, bool _we, bool _ws, bool _ww,
} }
bool BatimentQuad_::split() { bool BatimentQuad_::split() {
int minSurface = 100 * 100 * 10; int minSurface = 100 * 100 * 100;
Quad q = c; Quad q = c;
//Quad q = c << c.maxLengthSide(); //Quad q = c << c.maxLengthSide();
if(c.maxLengthNS() < c.maxLengthEW()) { if(c.maxLengthNS() < c.maxLengthEW()) {

View File

@ -24,7 +24,9 @@ public:
static const unsigned int route = 0x363636; static const unsigned int route = 0x363636;
static const unsigned int trottoir = 0x666666; static const unsigned int trottoir = 0x666666;
static const unsigned int bordureTrottoir = 0xAAAAAA; static const unsigned int bordureTrottoir = 0xAAAAAA;
static const unsigned int herbe = 0x0c4010; // 11AA22 static const unsigned int herbe = 0x0c4010;
static const unsigned int feuillage = 0x11AA22;
static const unsigned int tronc = 0x906050;
static const unsigned int cielHaut = 0x3c14ff; static const unsigned int cielHaut = 0x3c14ff;
static const unsigned int cielBas = 0x7F7FFF; static const unsigned int cielBas = 0x7F7FFF;
static const unsigned int fog; // définie dans couleurs.cpp . static const unsigned int fog; // définie dans couleurs.cpp .

View File

@ -135,6 +135,18 @@ void QuartierQuad::batiments() {
addChild(new BatimentQuad_(qbatiments)); addChild(new BatimentQuad_(qbatiments));
} else { } else {
addChild(new TerrainQuad(qbatiments)); addChild(new TerrainQuad(qbatiments));
Vertex p1 = qbatiments.insetProportionnal(0.7).randomPoint(seed, 1);
Vertex p2 = qbatiments.insetProportionnal(0.7).randomPoint(seed, 2);
Vertex p3 = qbatiments.insetProportionnal(0.7).randomPoint(seed, 3);
if (proba(seed, 4, 3, 4)) {
addChild(new Arbre(p1, Triangle(qbatiments[NE], qbatiments[SE], qbatiments[SW])));
if (proba(seed, 5, 3, 4) && Segment(p1,p2).length() > 3 * 100) {
addChild(new Arbre(p2, Triangle(qbatiments[NE], qbatiments[SE], qbatiments[SW])));
if (proba(seed, 6, 3, 4) && Segment(p2,p3).length() > 3 * 100 && Segment(p1,p3).length() > 3 * 100) {
addChild(new Arbre(p3, Triangle(qbatiments[NE], qbatiments[SE], qbatiments[SW])));
}
}
}
} }
} }

View File

@ -12,12 +12,12 @@ void ToitQuad::getBoundingBoxPoints() {
} }
void ToitQuad::triangulation() { void ToitQuad::triangulation() {
switch (hash2(seed, -1) % 4) { switch (hash2(seed, -1) % 5) {
case 0: pointCentral(); break; case 0: pointCentral(); break;
// TODO : deuxPoints() et deuxPointsVerticaux() ne génèrent pas des quad où les 4 points sont sur le même plan. case 1: quatrePoints(); break;
case 1: deuxPoints(); break; case 2: deuxPoints(); break;
case 2: deuxPointsVerticaux(); break; case 3: deuxPointsVerticaux(); break;
case 3: case 4:
default: plat(); break; default: plat(); break;
} }
} }
@ -29,6 +29,13 @@ void ToitQuad::pointCentral() {
addGPUTriangle(c[SE+i], center, c[NE+i], Couleurs::toit); addGPUTriangle(c[SE+i], center, c[NE+i], Couleurs::toit);
} }
void ToitQuad::quatrePoints() {
Quad ch = c.offsetNormal(height).insetNESW(c.minLength() / 3.f); // TODO : insetProportional
addGPUQuad(ch, Couleurs::toit);
for (int i = 0; i < 4; i++)
addGPUQuad(ch[NE+i], c[NE+i], c[SE+i], ch[SE+i], Couleurs::toit);
}
void ToitQuad::deuxPoints() { void ToitQuad::deuxPoints() {
// Orienter c dans le sens de la longueur d'est en ouest. // Orienter c dans le sens de la longueur d'est en ouest.
Quad q = c >> ((c.maxLengthNS() > c.maxLengthEW()) ? 1 : 0); Quad q = c >> ((c.maxLengthNS() > c.maxLengthEW()) ? 1 : 0);
@ -111,7 +118,7 @@ void ToitTri::troisPoints() {
Triangle th = c.offsetNormal(height).insetLTR(c.minLength() / 3.f); Triangle th = c.offsetNormal(height).insetLTR(c.minLength() / 3.f);
addGPUTriangle(th, Couleurs::toit); addGPUTriangle(th, Couleurs::toit);
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
addGPUQuad(c[LEFT], c[TOP], th[TOP], th[LEFT], Couleurs::toit); addGPUQuad(c[LEFT+i], c[TOP+i], th[TOP+i], th[LEFT+i], Couleurs::toit);
} }
void ToitTri::unPointVertical() { void ToitTri::unPointVertical() {

View File

@ -13,6 +13,7 @@ public:
virtual void getBoundingBoxPoints(); virtual void getBoundingBoxPoints();
private: private:
void pointCentral(); void pointCentral();
void quatrePoints();
void deuxPoints(); void deuxPoints();
void deuxPointsVerticaux(); void deuxPointsVerticaux();
void plat(); void plat();

View File

@ -48,6 +48,11 @@ void Chose::addGPUQuad(Quad q, unsigned int rgb) {
addGPUQuad(q[NE], q[SE], q[SW], q[NW], rgb); addGPUQuad(q[NE], q[SE], q[SW], q[NW], rgb);
} }
void Chose::addGPUFourQuads(Quad q, Quad qh, unsigned int rgb) {
for (int i = 0; i < 4; i++)
addGPUQuad(Quad(qh[NE+i], q[NE+i], q[SE+i], qh[SE+i]), rgb);
}
void Chose::addGPUOcto(Vertex ne, Vertex se, Vertex sw, Vertex nw, void Chose::addGPUOcto(Vertex ne, Vertex se, Vertex sw, Vertex nw,
Vertex neh, Vertex seh, Vertex swh, Vertex nwh, unsigned int rgb) { Vertex neh, Vertex seh, Vertex swh, Vertex nwh, unsigned int rgb) {
addGPUOcto(Quad(ne,se,sw,nw), Quad(neh,seh,swh,nwh), rgb); addGPUOcto(Quad(ne,se,sw,nw), Quad(neh,seh,swh,nwh), rgb);
@ -131,8 +136,8 @@ void Chose::addBBPoints(const Quad q, float height) {
} }
void Chose::updateAABB() { void Chose::updateAABB() {
float splitFactor = 5.f; float splitFactor = 5.f * LODFactor();
float mergeFactor = 6.f; float mergeFactor = 6.f * LODFactor();
float nonFacingFactor = 2.f/3.f; float nonFacingFactor = 2.f/3.f;
lod.firstBBPoint = true; lod.firstBBPoint = true;
getBoundingBoxPoints(); getBoundingBoxPoints();
@ -153,6 +158,10 @@ void Chose::updateAABB() {
} }
} }
float Chose::LODFactor() {
return 1.f;
}
// DEBUG // DEBUG
void Chose::drawAABB() { void Chose::drawAABB() {
addGPUOcto( addGPUOcto(

View File

@ -28,6 +28,7 @@ protected :
void addBBPoints(const Quad q); void addBBPoints(const Quad q);
void addBBPoints(const Quad q, float height); void addBBPoints(const Quad q, float height);
virtual void getBoundingBoxPoints() = 0; virtual void getBoundingBoxPoints() = 0;
virtual float LODFactor();
Chose(); Chose();
~Chose(); ~Chose();
inline void addEntropy(unsigned int x1) { inline void addEntropy(unsigned int x1) {
@ -66,6 +67,7 @@ protected :
void addGPUTriangle(Triangle t, unsigned int rgb); void addGPUTriangle(Triangle t, unsigned int rgb);
void addGPUQuad(Vertex ne, Vertex se, Vertex sw, Vertex nw, unsigned int rgb); void addGPUQuad(Vertex ne, Vertex se, Vertex sw, Vertex nw, unsigned int rgb);
void addGPUQuad(Quad q, unsigned int rgb); void addGPUQuad(Quad q, unsigned int rgb);
void addGPUFourQuads(Quad q, Quad qh, unsigned int rgb);
void addGPUOcto(Vertex ne, Vertex se, Vertex sw, Vertex nw, void addGPUOcto(Vertex ne, Vertex se, Vertex sw, Vertex nw,
Vertex neh, Vertex seh, Vertex swh, Vertex nwh, Vertex neh, Vertex seh, Vertex swh, Vertex nwh,
unsigned int rgb); unsigned int rgb);