www

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

commit 60a49d96a1233b27564f8d5a9b83ba0dcd9e5be9
parent 86c862658666b2ef73fdac3a6b2d791293851f65
Author: Georges Dupéron <jahvascriptmaniac+github@free.fr>
Date:   Mon, 28 Nov 2011 07:41:41 +0100

Revert "Zut"

This reverts commit 86c862658666b2ef73fdac3a6b2d791293851f65.

Diffstat:
MMakefile | 2+-
Mall_includes.hh | 10+++++++---
Dgputriangles.cpp | 44--------------------------------------------
Dgputriangles.hh | 30------------------------------
Aio.cpp | 3+++
Aio.hh | 13+++++++++++++
Mmain.cpp | 63++++++++++++++++++++++++++++++---------------------------------
Mrules/batiment.cpp | 14+-------------
Mrules/carrefour.cpp | 4+---
Mrules/carrefour.hh | 2+-
Mrules/chose.cpp | 60+++++++++++++++++++++++++++++++-----------------------------
Mrules/chose.hh | 16++++++----------
Mrules/rectangleroutes.cpp | 4+---
Mrules/rectangleroutes.hh | 2+-
Mrules/route.cpp | 4+---
Mrules/route.hh | 2+-
Mtriangle.cpp | 6+-----
Mtriangle.hh | 1-
18 files changed, 99 insertions(+), 181 deletions(-)

diff --git a/Makefile b/Makefile @@ -4,7 +4,7 @@ CCWARN=-Wall -Wextra -Werror # -flto (nécessite GCC 4.5) -m32 ou -m64 CFLAGS=-O3 -g3 -I. $(CCWARN) -OBJECTS = main.o hash.o segment.o vertex.o triangle.o gputriangles.o rules/chose.o rules/rectangleroutes.o rules/route.o rules/carrefour.o rules/batiment.o +OBJECTS = main.o hash.o segment.o vertex.o triangle.o io.o rules/chose.o rules/rectangleroutes.o rules/route.o rules/carrefour.o rules/batiment.o EXECUTABLE = city .PHONY: test diff --git a/all_includes.hh b/all_includes.hh @@ -6,14 +6,18 @@ #include <cmath> #include <vector> -class Chose; - #include "vertex.hh" #include "segment.hh" #include "triangle.hh" #include "directions.hh" +#include "io.hh" #include "hash.hh" -#include "gputriangles.hh" + +class Chose; +// class Batiment; +// class Carrefour; +// class Route; +// class RectangleRoutes; #include "rules/chose.hh" #include "rules/batiment.hh" diff --git a/gputriangles.cpp b/gputriangles.cpp @@ -1,44 +0,0 @@ -#include "all_includes.hh" - -// TODO : Lorsque le GPU est suffisemment puissant pour qu'on puisse envoyer plus de maxSize triangles, -// Tout supprimer et repartir avec un GPUTriangles vide, avec i, maxSize plus grand. -GPUTriangles::GPUTriangles(int maxSize) : current(0), aim(std::min(100, maxSize)), maxSize(maxSize) { - triangles = static_cast<Triangle*>(operator new[](maxSize * sizeof(Triangle))); - - nToAdd = 0; - nTrianglesToAdd = 0; - cToAdd = new Chose*[maxSize]; - - nToRemove = 0; - nTrianglesToRemove = 0; - cToRemove = new Chose*[maxSize]; -} - -void GPUTriangles::add(Chose* c) { - cToAdd[nToAdd++] = c; - nTrianglesToAdd += c->triangles.size(); -} - -void GPUTriangles::remove(Chose* c) { - cToRemove[nToRemove++] = c; - nTrianglesToRemove += c->triangles.size(); -} - -bool GPUTriangles::canAdd(Chose* c) { - return (current + nTrianglesToAdd + ((int)c->triangles.size()) - nTrianglesToRemove <= aim); -} - -bool GPUTriangles::canCommit() { - return (current + nTrianglesToAdd - nTrianglesToRemove <= aim); -} - -void GPUTriangles::commit() { - // Supprimer les triangles du tableau, en les insérant dans une freelist - // Trier la freelist pour insérer les nouveaux triangles au début. - // Ajouter les triangles en consommant de la freelist - // Compacter la fin du tableau. - nToAdd = 0; - nTrianglesToAdd = 0; - nToRemove = 0; - nTrianglesToRemove = 0; -} diff --git a/gputriangles.hh b/gputriangles.hh @@ -1,30 +0,0 @@ -#ifndef _GPUTRIANGLES_HH_ -#define _GPUTRIANGLES_HH_ - -#include "all_includes.hh" - -class GPUTriangles { -private: - int current; - int aim; - int maxSize; - Triangle* triangles; - - int nToAdd; - int nTrianglesToAdd; - Chose** cToAdd; - - int nTrianglesToRemove; - int nToRemove; - Chose** cToRemove; -public: - GPUTriangles(int maxSize); - void add(Chose*); - void remove(Chose*); - void commit(); - // Renvoie true si on peut commit, false s'il y a trop de triangles. - bool canCommit(); - bool canAdd(Chose* c); -}; - -#endif diff --git a/io.cpp b/io.cpp @@ -0,0 +1,3 @@ +#include "io.hh" + +IO::IO(): in(0), out(0) {} diff --git a/io.hh b/io.hh @@ -0,0 +1,13 @@ +#ifndef _IO_HH_ +#define _IO_HH_ + +class IO { +public: + int in; + int out; +public: + IO(); + //IO(int in, int out); +}; + +#endif diff --git a/main.cpp b/main.cpp @@ -23,46 +23,43 @@ int main() { // mettre à jour la triangulation de notre tile. // Invariants : - // * tile.errorVolume < somme(tile.children.errorVolume) // TODO : pour ordonner deux tiles égales, on prend en compte leur profondeur. + // * tile.errorVolume ≤ somme(tile.children.errorVolume) // * tile.nbTriangles < somme(tile.children.nbTriangles) + // Pour calculer le gain d'une Chose : + // Lorsqu'on utilise une Chose c, on la split d'abbord (on n'utilisera pas les fils tout de suite, donc pas de récursion), + // Calculer c.errorVolume dans le constructeur (idem pour chaque fils donc). + // // Calcul d'une approximation de la surface d'erreur, en considérant que l'objet est plaqué sur un plan perpendiculaire au sol. + // gainVolumeErreurParTriangle = (c.errorVolume / c.nbTriangles) - sum(x in c.children : x.errorVolume / x.nbTriangles) + // c.gainSurfaceErreurParTriangle = pow(volumeErreurParTriangle, 2.f/3.f); + // Pour calculer son gain : + // int gainParTriangle(distance) + // // Calcul de la surface de la projection de la surface d'erreur sur l'écran : + // return c.gainSurfaceErreurParTriangle * (frontFrustumDist * frontFrustumDist) / (dist * dist) + // Pour trouver le split() qui rapportera le plus : - // findMaxSplit(Vertex camera) { - // std::set<Chose*> ensemble(); // TODO : mettre un comparateur qui trie les éléments selon leur gain max, en ordre décroissant. - // std::set<Chose*>::iterator it; - // ensemble.insert(this); - // for (it = ensemble.begin(); it != ensemble.end(); it++) { - // // TODO : Calculer le gain min et max des fils de toutes les Chose d'ensemble. - // // Pour cela, écrire et utiliser int Chose::gainMinScreenSurfacePerTriangle(Vertex camera) - // // et int Chose::gainMax… qui calculeront le gain en utilisant la distance - // // du point le plus proche et le plus éloigné de la chose et de ses children. - // gainScreenSurfacePerTriangle(camera); - // } - // Chose* best = ensemble.begin(); // la Chose avec le plus grand gain max - // if (best->isLeafNode) return best; - // - // ensemble = std::set<Chose*>(ensemble.begin(), ensemble.upper_bound(best->gainMin)); // { c | c.max ≥ best.min } // TODO : comparateur - // } + // Set<Chose*> ensemble = { racine } + // Calculer le gain min et max des fils de toutes les Chose d'ensemble. + // Chose* best = la Chose avec le plus grand gain max + // if (best est une feuille) return best; + // ensemble = { c | c.max ≥ best.min } // Pour optimiser les Chose : - // GPUTriangles* gpu = new GPUTriangles(10); - // while(!gpu->canCommit()) { - // gpu->remove(findMinMerge()); - // gpu->commit(); - // } // while (42) { - // gpu->add(findMaxSplit()); - // while(!gpu->canCommit()) { - // gpu->remove(findMinMerge()); - // } - // while ((s = findMaxSplit()) && gpu->canAdd(s)) { - // gpu->add(s); - // } - // if (gpu->isImprovement()) { - // gpu->commit(); - // } else { - // break; // while (42) + // Trouver la Chose dont le split() rapportera le plus + // if (GPUTriangles::current + nbNewTriangles > GPUTriangles::aim) { + // Trouver les choses avec le merge() qui coûtera le moins, + // En ayant suffisemment de triangles pour que + // (GPUTriangles::current + nbNewTriangles - nbDeleteTriangles <= GPUTriangles::aim) + // Faire autant de split() (qui rapportent le plus) que possible sans dépasser le nombre de triangles autorisés + // => De cette manière, si on a dû faire un gros merge() qui coûte cher, il sera peut-être compensé par plein de petits split(). + // if (somme des coûts >= gain) { + // break; // while (42) + // } // } + // Supprimer les triangles du tableau, en les insérant dans une freelist + // Ajouter les triangles en consommant de la freelist // } + // Consommer la freeList en créant des triangles "bidon" (les trois sommets en (0,0,0) par ex.) return 0; } diff --git a/rules/batiment.cpp b/rules/batiment.cpp @@ -1,11 +1,6 @@ #include "all_includes.hh" -Batiment::Batiment(Vertex ne, Vertex sw) : Chose(), ne(ne), sw(sw) { - triangulation(); - // TODO : cet errorVolume est celui d'un bâtiment non détaillé - // (juste un cube), donc il nous faut un niveau de détail - // supplémentaire pour la triangulation actuelle. - setErrorVolume((std::abs(ne.x - sw.x)) * (std::abs(ne.y - sw.y)) * (6 + 6/5)); // l*L*h +Batiment::Batiment(Vertex ne, Vertex sw) : ne(ne), sw(sw) { std::cout << this << std::endl; } @@ -53,10 +48,3 @@ std::ostream& operator<<(std::ostream& os, const Batiment* r) { std::ostream& operator<<(std::ostream& os, const Batiment& r) { return os << "Batiment " << r.ne << "-" << r.sw; } - -virtual float distanceMin(Vertex v) { - -} - -virtual float distanceMax(Vertex v) { -} diff --git a/rules/carrefour.cpp b/rules/carrefour.cpp @@ -1,12 +1,10 @@ #include "carrefour.hh" -Carrefour::Carrefour(Vertex ne, Vertex se, Vertex sw, Vertex nw) : Chose() { +Carrefour::Carrefour(Vertex ne, Vertex se, Vertex sw, Vertex nw) { corners[NE]=ne; corners[SE]=se; corners[SW]=sw; corners[NW]=nw; - triangulation(); - setErrorVolume(0); std::cout << this << std::endl; } diff --git a/rules/carrefour.hh b/rules/carrefour.hh @@ -3,7 +3,7 @@ #include "all_includes.hh" -class Carrefour : public Chose { +class Carrefour : Chose { public: Vertex corners[4]; public: diff --git a/rules/chose.cpp b/rules/chose.cpp @@ -2,12 +2,12 @@ Chose::Chose() : seed(initialSeed) {} -std::ostream& operator<<(std::ostream& os, const Chose* c) { - return os << *c; +std::ostream& operator<<(std::ostream& os, const Chose* r) { + return os << *r; } -std::ostream& operator<<(std::ostream& os, const Chose& c) { - (void)c; // unused +std::ostream& operator<<(std::ostream& os, const Chose& r) { + (void)r; // unused return os << "Chose"; } @@ -23,36 +23,38 @@ void Chose::addChild(Chose* c) { children.push_back(c); } -void Chose::use() { - // Lorsqu'on utilise une Chose c, on la split d'abbord (on - // n'utilisera pas les fils tout de suite, donc pas de récursion). - subdivide(); - gainErrorSurfacePerTriangle = errorSurfacePerTriangle; - std::vector<Chose*>::iterator it; - for (it = children.begin(); it != children.end(); ++it) { - gainErrorSurfacePerTriangle -= it->errorSurfacePerTriangle); - } - // TODO : isLeaf = true; -} - -void Chose::unuse() { - // TODO : isLeaf = false; +void Chose::useTriangles() { + // TODO + // Ajouter t dans la liste des triangles à envoyer au GPU. + + + // Maintenir une liste "add" et une liste "delete". + // Quand on flush les triangles, s'il y a plus de delete que de add : + // * trier la liste delete. + // * Choisir l'extrémité (début ou fin) vers laquelle on va rappatrier les éléments de l'autre extrémité. + // * Écraser les delete avec les add en partant du côté vers lequel on rappatrie. + // * Copier des éléments de l'extrémité vers les cases libres. + // * Enregistrer l'indice min et l'indice max. + // Problème : Pas real-time : on ne peut pas arrêter le processus n'importe quand… } void Chose::addTriangle(Triangle* t) { triangles.push_back(t); } -void Chose::setErrorVolume(int errorVolume) { - // Calcul d'une approximation de la surface d'erreur à l'écran, en - // considérant que l'objet est en fait juste une texture plaquée - // sur un plan perpendiculaire au sol et parallèle à l'écran. - errorSurfacePerTriangle = pow((float)errorVolume / (float)triangles.size(), 2.f/3.f); -} +/* TODO : quand on se rend compte qu'on peut utiliser plus de + triangles (le GPU suit sans problème au FPS voulu), allouer un + autre tableau plus grand, vers lequel on déplacera les triangles + petit à petit (pour rester real-time). -// int Chose::gainScreenSurfacePerTriangle(Vertex camera) { -int Chose::gainScreenSurfacePerTriangle(Vertex camera) { - int frontFrustumDist = 1; // TODO : valeur bidon. - // Surface de la projection à l'écran de la surface d'erreur : - return (int)(gainErrorSurfacePerTriangle * (frontFrustumDist * frontFrustumDist) / (distance * distance)); + Pour l'instant, on alloue simplement un tableau suffisemment grand. + */ + +Triangle* Chose::resetGPUTriangles(int n) { + Chose::GPUTriangles = static_cast<Triangle*>(operator new[](n * sizeof(Triangle))); + return Chose::GPUTriangles; } + +int Chose::nGPUTriangles = 1000; +// http://stackoverflow.com/questions/4754763/c-object-array-initialization-without-default-constructor +Triangle* Chose::GPUTriangles = Chose::resetGPUTriangles(Chose::nGPUTriangles); diff --git a/rules/chose.hh b/rules/chose.hh @@ -10,8 +10,9 @@ public: unsigned int seed; std::vector<Chose*> children; std::vector<Triangle*> triangles; - float errorSurfacePerTriangle; - float gainErrorSurfacePerTriangle; + static Triangle* resetGPUTriangles(int n); + static int nGPUTriangles; + static Triangle* GPUTriangles; public: Chose(); inline void addEntropy(unsigned int x1) { seed = hash2(seed, x1); } @@ -26,17 +27,12 @@ public: void initTriangles(int n); void addChild(Chose* c); void addTriangle(Triangle* t); - void setErrorVolume(int errorVolume); - int gainScreenSurfacePerTriangle(Vertex camera); - void use(); // triangulation() doit déjà avoir été appelé. - void unuse(); + void useTriangles(); // triangulation() doit déjà avoir été appelé. virtual void subdivide() = 0; virtual void triangulation() = 0; - virtual float distanceMin(Vertex v); - virtual float distanceMax(Vertex v); }; -std::ostream& operator<<(std::ostream& os, const Chose& c); -std::ostream& operator<<(std::ostream& os, const Chose* c); +std::ostream& operator<<(std::ostream& os, const Chose& r); +std::ostream& operator<<(std::ostream& os, const Chose* r); #endif diff --git a/rules/rectangleroutes.cpp b/rules/rectangleroutes.cpp @@ -1,10 +1,8 @@ #include "all_includes.hh" -RectangleRoutes::RectangleRoutes(Vertex ne, Vertex sw) : Chose(), ne(ne), sw(sw) { +RectangleRoutes::RectangleRoutes(Vertex ne, Vertex sw) : ne(ne), sw(sw) { addEntropy(ne); addEntropy(sw); - triangulation(); - setErrorVolume((std::abs(ne.x - sw.x)) * (std::abs(ne.y - sw.y)) * 20); // l*L*h, 20=hauteur max d'un bâtiment. std::cout << this << std::endl; } diff --git a/rules/rectangleroutes.hh b/rules/rectangleroutes.hh @@ -4,7 +4,7 @@ #include "all_includes.hh" // RectangleRoutes est un quadrilatère de routes avec des angles aux coins égaux à 90°. -class RectangleRoutes : public Chose { +class RectangleRoutes : Chose { public: Vertex ne; Vertex sw; diff --git a/rules/route.cpp b/rules/route.cpp @@ -2,13 +2,11 @@ #include "../vertex.hh" #include "../directions.hh" -Route::Route(Vertex ne, Vertex se, Vertex sw, Vertex nw) : Chose() { +Route::Route(Vertex ne, Vertex se, Vertex sw, Vertex nw) { corners[NE]=ne; corners[SE]=se; corners[SW]=sw; corners[NW]=nw; - triangulation(); - setErrorVolume(0); std::cout << this << std::endl; } diff --git a/rules/route.hh b/rules/route.hh @@ -3,7 +3,7 @@ #include "all_includes.hh" -class Route : public Chose { +class Route : Chose { public: Vertex corners[4]; public: diff --git a/triangle.cpp b/triangle.cpp @@ -1,11 +1,7 @@ #include "all_includes.hh" Triangle::Triangle(Vertex a, Vertex b, Vertex c): a(a), b(b), c(c) { - // TODO : calcul de la normale. -} - -std::ostream& operator<<(std::ostream& os, const Triangle* t) { - return os << *t; + std::cout << this << std::endl; } std::ostream& operator<<(std::ostream& os, const Triangle& t) { diff --git a/triangle.hh b/triangle.hh @@ -11,7 +11,6 @@ public: public: Triangle(Vertex a, Vertex b, Vertex c); public: - friend std::ostream& operator<<(std::ostream& os, const Triangle* t); friend std::ostream& operator<<(std::ostream& os, const Triangle& t); };