Tas pour le LOD.
This commit is contained in:
parent
d171be9892
commit
46189836f5
|
@ -25,6 +25,7 @@ class Chose;
|
|||
|
||||
#include "hash.hh"
|
||||
#include "view.hh"
|
||||
// LOD must be included before chose.hh
|
||||
#include "lod.hh"
|
||||
|
||||
#include "rules/chose.hh"
|
||||
|
|
132
lod.cpp
132
lod.cpp
|
@ -33,9 +33,6 @@ Chose* Abr::popIfLessThan(int key) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#define NegateEven(v, i) ((v)*(((i)&1) ? 1 : -1))
|
||||
|
||||
Lod::Lod(){};
|
||||
|
@ -109,3 +106,132 @@ void Lod::addSplitCube(Chose* chose, int limits[6]) {
|
|||
split[2*i+1].insert(NegateEven(limits[i],i+1), chose);
|
||||
}
|
||||
}
|
||||
|
||||
Heap::Heap(int id)
|
||||
: id(id), buckets(new HeapNode*[1]), lastAllocatedBucket(-1),
|
||||
bucketArraySize(1), lastNode(-1) {
|
||||
}
|
||||
|
||||
void Heap::insert(int key, Chose* value) {
|
||||
++lastNode;
|
||||
if (getBucket(lastNode) > lastAllocatedBucket) {
|
||||
allocateBucket();
|
||||
}
|
||||
buckets[getBucket(lastNode)][getIndex(lastNode)].key = key;
|
||||
buckets[getBucket(lastNode)][getIndex(lastNode)].value = value;
|
||||
siftUp(lastNode);
|
||||
}
|
||||
|
||||
void Heap::remove(int node) {
|
||||
--lastNode;
|
||||
|
||||
if (node > lastNode) { // On a supprimé le dernier noeud.
|
||||
// + 1 pour garder au moins un bucket "en cache".
|
||||
if (getBucket(lastNode) + 1 < lastAllocatedBucket)
|
||||
freeBucket();
|
||||
return;
|
||||
}
|
||||
|
||||
buckets[getBucket(node)][getIndex(node)] = \
|
||||
buckets[getBucket(lastNode)][getIndex(lastNode)];
|
||||
|
||||
// + 1 pour garder au moins un bucket "en cache".
|
||||
if (getBucket(lastNode) + 1 < lastAllocatedBucket) {
|
||||
freeBucket();
|
||||
}
|
||||
|
||||
siftDown(node);
|
||||
}
|
||||
|
||||
Chose* Heap::popIfLessThan(int key) {
|
||||
if (lastNode >= 0 && buckets[0][0].key < key) {
|
||||
Chose* ret = buckets[0][0].value;
|
||||
remove(0);
|
||||
return ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Heap::siftUp(int node) {
|
||||
HeapNode* n;
|
||||
HeapNode* np;
|
||||
while (true) {
|
||||
n = &(buckets[getBucket(node)][getIndex(node)]);
|
||||
if (node <= 0)
|
||||
break;
|
||||
int p = parent(node);
|
||||
np = &(buckets[getBucket(p)][getIndex(p)]);
|
||||
if (n->key >= np->key)
|
||||
break;
|
||||
HeapNode temp = *n;
|
||||
*n = *np;
|
||||
*np = temp;
|
||||
// mettre à jour le champ lod.heaps[id] de l'ancien parent qu'on
|
||||
// vient de descendre.
|
||||
n->value->lod.heaps[id] = node;
|
||||
node = p;
|
||||
}
|
||||
// après les break; qui sortent de la boucle, on a déjà actualisé
|
||||
// le pointeur `n` vers buckets[getBucket(node)][getIndex(node)].
|
||||
n->value->lod.heaps[id] = node;
|
||||
}
|
||||
|
||||
void Heap::siftDown(int node) {
|
||||
HeapNode* n;
|
||||
HeapNode* nlc;
|
||||
HeapNode* nrc;
|
||||
while (true) {
|
||||
n = &(buckets[getBucket(node)][getIndex(node)]);
|
||||
int lc = leftchild(node);
|
||||
int rc = rightchild(node);
|
||||
nlc = &(buckets[getBucket(lc)][getIndex(lc)]);
|
||||
nrc = &(buckets[getBucket(rc)][getIndex(rc)]);
|
||||
// exchLeft et exchRight peuvent être tout deux true. Dans ce
|
||||
// cas, c'est exchRight qui gagne.
|
||||
bool exchLeft = (lc <= lastNode) && (n->key > nlc->key);
|
||||
bool exchRight = (rc <= lastNode) && (n->key > nrc->key) && (nlc->key > nrc->key);
|
||||
if ((!exchLeft) && (!exchRight))
|
||||
break;
|
||||
HeapNode temp = *n;
|
||||
if (exchRight) {
|
||||
*n = *nrc;
|
||||
*nrc = temp;
|
||||
} else {
|
||||
*n = *nlc;
|
||||
*nlc = temp;
|
||||
}
|
||||
// mettre à jour le champ lod.heaps[id] de l'ancien fils qu'on
|
||||
// vient de remonter.
|
||||
n->value->lod.heaps[id] = node;
|
||||
node = (exchRight ? rc : lc);
|
||||
}
|
||||
// après les break; qui sortent de la boucle, on a déjà actualisé
|
||||
// le pointeur `n` vers buckets[getBucket(node)][getIndex(node)].
|
||||
n->value->lod.heaps[id] = node;
|
||||
}
|
||||
|
||||
void Heap::allocateBucket() {
|
||||
++lastAllocatedBucket;
|
||||
if (lastAllocatedBucket >= bucketArraySize) {
|
||||
HeapNode** old = buckets;
|
||||
buckets = new HeapNode*[bucketArraySize*2];
|
||||
for (int i = 0; i < lastAllocatedBucket; i++)
|
||||
buckets[i] = old[i];
|
||||
delete[] old;
|
||||
bucketArraySize *= 2;
|
||||
}
|
||||
buckets[lastAllocatedBucket] = new HeapNode[bucketSize];
|
||||
}
|
||||
|
||||
void Heap::freeBucket() {
|
||||
delete[] buckets[lastAllocatedBucket];
|
||||
--lastAllocatedBucket;
|
||||
if (lastAllocatedBucket * 4 < bucketArraySize && bucketArraySize > 1) {
|
||||
HeapNode** old = buckets;
|
||||
buckets = new HeapNode*[bucketArraySize/2];
|
||||
for (int i = 0; i <= lastAllocatedBucket; i++)
|
||||
buckets[i] = old[i];
|
||||
delete[] old;
|
||||
bucketArraySize /= 2;
|
||||
}
|
||||
}
|
||||
|
|
44
lod.hh
44
lod.hh
|
@ -28,4 +28,48 @@ class Lod {
|
|||
void setCamera(float camera[3]);
|
||||
};
|
||||
|
||||
struct HeapNode {
|
||||
int key;
|
||||
Chose* value;
|
||||
};
|
||||
|
||||
class Heap {
|
||||
private:
|
||||
int id;
|
||||
static const int log2BucketSize = 9; // 2^9 = 512
|
||||
static const int bucketSize = (1 << log2BucketSize);
|
||||
HeapNode** buckets;
|
||||
int lastAllocatedBucket;
|
||||
int bucketArraySize;
|
||||
int lastNode;
|
||||
private:
|
||||
inline int getBucket(int node) {
|
||||
return (node >> log2BucketSize);
|
||||
}
|
||||
inline int getIndex(int node) {
|
||||
return (node & (bucketSize - 1));
|
||||
}
|
||||
void allocateBucket(); // Allocate into last+1
|
||||
void freeBucket(); // free last
|
||||
void siftUp(int node);
|
||||
void siftDown(int node);
|
||||
inline int parent(int node) { return (node - 1)/2; }
|
||||
inline int leftchild(int node) { return node * 2 + 1; }
|
||||
inline int rightchild(int node) { return node * 2 + 2; }
|
||||
public:
|
||||
Heap(int id);
|
||||
void insert(int key, Chose* value);
|
||||
void remove(int node);
|
||||
Chose* popIfLessThan(int key);
|
||||
};
|
||||
|
||||
class LodNode {
|
||||
public:
|
||||
int heaps[18];
|
||||
int aabb[6];
|
||||
int inCounter;
|
||||
HeapNode* splitCube[12];
|
||||
HeapNode* mergeCube[6];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
12
main.cpp
12
main.cpp
|
@ -29,12 +29,20 @@ int main() {
|
|||
Chose* c = QuartierQuad::factory(Chose::initialSeed, 0, ne, se, sw, nw);
|
||||
// c->subdivide();
|
||||
recursiveSubdivide(c);
|
||||
|
||||
|
||||
Heap h(1);
|
||||
(void)h;
|
||||
h.insert(43,c);
|
||||
h.insert(42,c->children[0]);
|
||||
h.popIfLessThan(42); // NULL
|
||||
h.popIfLessThan(43); // c->children[0]
|
||||
h.popIfLessThan(44); // c
|
||||
h.popIfLessThan(44); // NULL
|
||||
|
||||
View *v = new View(c);
|
||||
Vertex cc = v->camera.cameraCenter;
|
||||
float camera[3] = {cc.x, cc.y, cc.z};
|
||||
camera[0] = camera[0];
|
||||
Lod lod(camera);
|
||||
// tile.subdivide tant qu'on n'a pas le niveau de détail désiré.
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2,23 +2,16 @@
|
|||
|
||||
Chose::Chose() : seed(initialSeed), children() {}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Chose* r) {
|
||||
return os << *r;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Chose& r) {
|
||||
(void)r; // unused
|
||||
return os << "Chose";
|
||||
}
|
||||
|
||||
void Chose::addChild(Chose* c) {
|
||||
children.push_back(c);
|
||||
// TODO : Ajouter c dans une file d'attente des éléments pouvant être split.
|
||||
}
|
||||
|
||||
void Chose::addTriangle(Triangle* t) {
|
||||
triangles.push_back(t);
|
||||
// TODO : Ajouter t dans la liste des triangles à envoyer au GPU.
|
||||
}
|
||||
|
||||
void Chose::merge() {
|
||||
triangles.clear();
|
||||
}
|
||||
|
||||
void Chose::display() {
|
||||
|
|
|
@ -10,6 +10,7 @@ class Chose {
|
|||
unsigned int seed;
|
||||
std::vector<Chose*> children;
|
||||
std::vector<Triangle*> triangles;
|
||||
LodNode lod;
|
||||
int inCounter;
|
||||
int splitCube[6];
|
||||
int mergeCube[6];
|
||||
|
@ -17,25 +18,38 @@ class Chose {
|
|||
public :
|
||||
void display();
|
||||
virtual bool subdivide() = 0;
|
||||
virtual void merge();
|
||||
|
||||
protected :
|
||||
Chose();
|
||||
inline void addEntropy(unsigned int x1) { seed = hash2(seed, x1); }
|
||||
inline void addEntropy(unsigned int x1, unsigned int x2) { addEntropy(x1); addEntropy(x2); }
|
||||
inline void addEntropy(unsigned int x1, unsigned int x2, unsigned int x3) { addEntropy(x1, x2); addEntropy(x3); }
|
||||
inline void addEntropy(unsigned int x1, unsigned int x2, unsigned int x3, unsigned int x4) { addEntropy(x1, x2); addEntropy(x3, x4); }
|
||||
inline void addEntropy(Vertex v1) { addEntropy(v1.x, v1.y); }
|
||||
inline void addEntropy(Vertex v1, Vertex v2) { addEntropy(v1); addEntropy(v2); }
|
||||
inline void addEntropy(Vertex v1, Vertex v2, Vertex v3) { addEntropy(v1, v2); addEntropy(v3); }
|
||||
inline void addEntropy(Vertex v1, Vertex v2, Vertex v3, Vertex v4) { addEntropy(v1, v2); addEntropy(v3, v4); }
|
||||
inline void addEntropy(unsigned int x1) {
|
||||
seed = hash2(seed, x1);
|
||||
}
|
||||
inline void addEntropy(unsigned int x1, unsigned int x2) {
|
||||
addEntropy(x1); addEntropy(x2);
|
||||
}
|
||||
inline void addEntropy(unsigned int x1, unsigned int x2, unsigned int x3) {
|
||||
addEntropy(x1, x2); addEntropy(x3);
|
||||
}
|
||||
inline void addEntropy(unsigned int x1, unsigned int x2, unsigned int x3, unsigned int x4) {
|
||||
addEntropy(x1, x2); addEntropy(x3, x4);
|
||||
}
|
||||
inline void addEntropy(Vertex v1) {
|
||||
addEntropy(v1.x, v1.y);
|
||||
}
|
||||
inline void addEntropy(Vertex v1, Vertex v2) {
|
||||
addEntropy(v1); addEntropy(v2);
|
||||
}
|
||||
inline void addEntropy(Vertex v1, Vertex v2, Vertex v3) {
|
||||
addEntropy(v1, v2); addEntropy(v3);
|
||||
}
|
||||
inline void addEntropy(Vertex v1, Vertex v2, Vertex v3, Vertex v4) {
|
||||
addEntropy(v1, v2); addEntropy(v3, v4);
|
||||
}
|
||||
void addChild(Chose* c);
|
||||
void addTriangle(Triangle* t);
|
||||
virtual void triangulation() = 0;
|
||||
virtual std::vector<Vertex*> getBoundingBoxPoints() const = 0;
|
||||
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Chose& r);
|
||||
std::ostream& operator<<(std::ostream& os, const Chose* r);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue
Block a user