# HG changeset patch # User Radek Brich # Date 1198969907 -3600 # Node ID 0b8b968b42d1159e382125c0322ac5f7a3e9e07c # Parent fbdeb3e04543f04f3e76420a15651f03c4ba4d2b memory optimization for octree fixed some visual artifacts in textures C++ demo and set ambient occlussion for rendering (-r) diff -r fbdeb3e04543 -r 0b8b968b42d1 ccdemos/textures.cc --- a/ccdemos/textures.cc Sat Dec 29 13:53:33 2007 +0100 +++ b/ccdemos/textures.cc Sun Dec 30 00:11:47 2007 +0100 @@ -27,7 +27,7 @@ void texture2D(Float u, Float v, Float &r, Float &g, Float &b) { // checkers - r = fabs((int)(u*4.4)%2 + (int)(v*4.4)%2 - 1); + r = fabs((int)(u*4.2)%2 + (int)(v*4.2)%2 - 1); g=r; b=r; } @@ -60,12 +60,18 @@ { if (fabs(point.x) > fabs(point.z)) { - u = point.y; + if (point.x < 0) + u = -point.y; + else + u = point.y; v = point.z; } else { - u = point.x; + if (point.z < 0) + u = -point.x; + else + u = point.x; v = point.y; } } @@ -73,12 +79,18 @@ { if (fabs(point.y) > fabs(point.z)) { - u = point.x; + if (point.y < 0) + u = -point.x; + else + u = point.x; v = point.z; } else { - u = point.x; + if (point.z < 0) + u = -point.x; + else + u = point.x; v = point.y; } } @@ -266,6 +278,7 @@ Float *fdata = (Float *) malloc(w*h*3*sizeof(Float)); rt.setOversample(2); rt.setSubsample(1); + rt.ambientocclusion(300, 5.0, 0.5); rt.render(w, h, fdata); struct image *img; diff -r fbdeb3e04543 -r 0b8b968b42d1 include/octree.h --- a/include/octree.h Sat Dec 29 13:53:33 2007 +0100 +++ b/include/octree.h Sun Dec 30 00:11:47 2007 +0100 @@ -12,22 +12,35 @@ #include "vector.h" #include "scene.h" +#include + using namespace std; class OctreeNode { - OctreeNode *children; // pointer to first of eight children + union { + OctreeNode *children; // pointer to first of eight children + ShapeList *shapes; // pointer to shape array, if this is leaf + off_t leaf; // leaf indicator (bit 0) + }; public: - ShapeList *shapes; // pointer to shape array, if this is leaf - - OctreeNode() : children(NULL) { shapes = new ShapeList(); }; + OctreeNode() + { + shapes = new ShapeList(); + assert(sizeof(off_t)==sizeof(void*) && !isLeaf()); + setLeaf(); + }; ~OctreeNode(); - bool isLeaf() { return shapes != NULL; }; + bool isLeaf() { return leaf & 1; }; + void setLeaf() { leaf = leaf | 1; }; - OctreeNode *getChild(const int num) { return children+num; }; + void makeChildren() { children = new OctreeNode[8]; assert(!isLeaf()); }; // this also cleans leaf bit + OctreeNode *getChild(const int num) { assert(!isLeaf()); return children + num; }; - void addShape(Shape* aShape) { shapes->push_back(aShape); }; + void addShape(Shape* aShape) { getShapes()->push_back(aShape); }; + ShapeList *getShapes() { return (ShapeList*)((off_t)shapes & ~(off_t)1); }; + void setShapes(ShapeList *const ashapes) { shapes = ashapes; assert(!isLeaf()); setLeaf(); }; void subdivide(BBox bbox, int maxdepth); }; diff -r fbdeb3e04543 -r 0b8b968b42d1 src/octree.cc --- a/src/octree.cc Sat Dec 29 13:53:33 2007 +0100 +++ b/src/octree.cc Sun Dec 30 00:11:47 2007 +0100 @@ -9,16 +9,21 @@ OctreeNode::~OctreeNode() { - if (shapes != NULL) + if (isLeaf()) + { + leaf = leaf^1; // zero leaf bit delete shapes; + } else delete[] children; } void OctreeNode::subdivide(BBox bbox, int maxdepth) { - // make children - children = new OctreeNode[8]; + ShapeList *l_shapes = getShapes(); + + // prepare children (this also sets this node as non-leaf) + makeChildren(); // evaluate centres for axes const Float xsplit = (bbox.L.x + bbox.H.x)*0.5; @@ -42,7 +47,7 @@ // distribute shapes to children ShapeList::iterator sh; unsigned int shapenum = 0; - for (sh = shapes->begin(); sh != shapes->end(); sh++) + for (sh = l_shapes->begin(); sh != l_shapes->end(); sh++) { for (int i = 0; i < 8; i++) if ((*sh)->intersect_bbox(childbb[i])) @@ -52,21 +57,21 @@ } } - if ((shapes->size() <= 8 && shapenum > 2*shapes->size()) - || shapenum >= 6*shapes->size()) + if ((l_shapes->size() <= 8 && shapenum > 2*l_shapes->size()) + || shapenum >= 6*l_shapes->size()) { // bad subdivision, revert delete[] children; + setShapes(l_shapes); return; } // remove shapes and set this node to non-leaf - delete shapes; - shapes = NULL; + delete l_shapes; // recursive subdivision for (int i = 0; i < 8; i++) - if (maxdepth > 1 && getChild(i)->shapes->size() > 4) + if (maxdepth > 1 && getChild(i)->getShapes()->size() > 4) children[i].subdivide(childbb[i], maxdepth-1); } @@ -196,7 +201,7 @@ ShapeList::iterator shape; //register Float mindist = max3(tx0,ty0,tz0); register Float dist = min(nearest_distance, min3(tx1,ty1,tz1)); - for (shape = node->shapes->begin(); shape != node->shapes->end(); shape++) + for (shape = node->getShapes()->begin(); shape != node->getShapes()->end(); shape++) if (*shape != origin_shape && (*shape)->intersect(ray, dist)) { nearest_shape = *shape;