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

View File

@ -2,3 +2,19 @@
float Angle::r2d(float rad) { return rad / Pi * 180; }
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_
#define _GEOMETRY_ANGLE_HH_
#include "all_includes.hh"
namespace Angle {
const double dPi = 3.141592653589793238462643383279;
const float Pi = (float)(dPi);
@ -8,4 +10,16 @@ namespace Angle {
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

View File

@ -243,3 +243,11 @@ Quad Quad::offsetNormal(float offset) const {
Vertex Quad::normal() const {
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 offsetNormal(float offset) 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());
}
Vertex Vertex::normalize() const {
return (*this / norm());
}
float Vertex::cosAngle(Vertex v) const {
// 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()));

View File

@ -15,6 +15,7 @@ class Vertex {
float norm() const;
Vertex projectOn(Vertex v) const;
Vertex setNorm(float n) const;
Vertex normalize() const;
float cosAngle(Vertex v) const; // cosinus de l'angle entre this et v.
float angle(Vertex v) const; // Angle entre this et v.
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& 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& 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() {
int minSurface = 100 * 100 * 10;
int minSurface = 100 * 100 * 100;
Quad q = c;
//Quad q = c << c.maxLengthSide();
if(c.maxLengthNS() < c.maxLengthEW()) {

View File

@ -24,7 +24,9 @@ public:
static const unsigned int route = 0x363636;
static const unsigned int trottoir = 0x666666;
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 cielBas = 0x7F7FFF;
static const unsigned int fog; // définie dans couleurs.cpp .

View File

@ -135,6 +135,18 @@ void QuartierQuad::batiments() {
addChild(new BatimentQuad_(qbatiments));
} else {
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() {
switch (hash2(seed, -1) % 4) {
switch (hash2(seed, -1) % 5) {
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: deuxPoints(); break;
case 2: deuxPointsVerticaux(); break;
case 3:
case 1: quatrePoints(); break;
case 2: deuxPoints(); break;
case 3: deuxPointsVerticaux(); break;
case 4:
default: plat(); break;
}
}
@ -29,6 +29,13 @@ void ToitQuad::pointCentral() {
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() {
// Orienter c dans le sens de la longueur d'est en ouest.
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);
addGPUTriangle(th, Couleurs::toit);
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() {

View File

@ -13,6 +13,7 @@ public:
virtual void getBoundingBoxPoints();
private:
void pointCentral();
void quatrePoints();
void deuxPoints();
void deuxPointsVerticaux();
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);
}
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,
Vertex neh, Vertex seh, Vertex swh, Vertex nwh, unsigned int 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() {
float splitFactor = 5.f;
float mergeFactor = 6.f;
float splitFactor = 5.f * LODFactor();
float mergeFactor = 6.f * LODFactor();
float nonFacingFactor = 2.f/3.f;
lod.firstBBPoint = true;
getBoundingBoxPoints();
@ -153,6 +158,10 @@ void Chose::updateAABB() {
}
}
float Chose::LODFactor() {
return 1.f;
}
// DEBUG
void Chose::drawAABB() {
addGPUOcto(

View File

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