clray

annotate src/scene.cc @ 25:58642a8316b7

continuing with the kdtree
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 14 Aug 2010 07:00:04 +0100
parents 13091c00d7ca
children c740ae431d51
rev   line source
John@15 1 #include <math.h>
nuclear@25 2 #include <float.h>
nuclear@22 3 #include "scene.h"
nuclear@6 4
John@15 5 #define FEQ(a, b) (fabs((a) - (b)) < 1e-8)
John@15 6 bool Face::operator ==(const Face &f) const
John@15 7 {
John@15 8 for(int i=0; i<3; i++) {
John@15 9 for(int j=0; j<3; j++) {
John@15 10 if(!FEQ(v[i].pos[j], f.v[i].pos[j])) {
John@15 11 return false;
John@15 12 }
John@15 13 if(!FEQ(v[i].normal[j], f.v[i].normal[j])) {
John@15 14 return false;
John@15 15 }
John@15 16 }
John@15 17 if(!FEQ(normal[i], f.normal[i])) {
John@15 18 return false;
John@15 19 }
John@15 20 }
John@15 21 return true;
John@15 22 }
John@15 23
nuclear@25 24 float AABBox::calc_surface_area() const
nuclear@25 25 {
nuclear@25 26 float area1 = (max[0] - min[0]) * (max[1] - min[1]);
nuclear@25 27 float area2 = (max[3] - min[3]) * (max[1] - min[1]);
nuclear@25 28 float area3 = (max[0] - min[0]) * (max[3] - min[3]);
nuclear@25 29
nuclear@25 30 return 2.0f * (area1 + area2 + area3);
nuclear@25 31 }
nuclear@25 32
nuclear@25 33
nuclear@24 34 Scene::Scene()
nuclear@24 35 {
nuclear@24 36 facebuf = 0;
nuclear@24 37 num_faces = -1;
nuclear@24 38 kdtree = 0;
nuclear@24 39 }
nuclear@24 40
nuclear@24 41 Scene::~Scene()
nuclear@24 42 {
nuclear@24 43 delete [] facebuf;
nuclear@24 44 }
nuclear@24 45
nuclear@13 46 bool Scene::add_mesh(Mesh *m)
nuclear@13 47 {
nuclear@13 48 // make sure triangles have material ids
nuclear@13 49 for(size_t i=0; i<m->faces.size(); i++) {
nuclear@13 50 m->faces[i].matid = m->matid;
nuclear@13 51 }
nuclear@24 52
nuclear@24 53 try {
nuclear@24 54 meshes.push_back(m);
nuclear@24 55 }
nuclear@24 56 catch(...) {
nuclear@24 57 return false;
nuclear@24 58 }
nuclear@24 59
nuclear@24 60 // invalidate facebuffer and count
nuclear@24 61 delete [] facebuf;
nuclear@24 62 facebuf = 0;
nuclear@24 63 num_faces = -1;
nuclear@24 64
nuclear@13 65 return true;
nuclear@13 66 }
nuclear@13 67
John@14 68 int Scene::get_num_meshes() const
John@14 69 {
John@14 70 return (int)meshes.size();
John@14 71 }
John@14 72
nuclear@13 73 int Scene::get_num_faces() const
nuclear@13 74 {
nuclear@24 75 if(num_faces >= 0) {
nuclear@24 76 return num_faces;
nuclear@24 77 }
nuclear@24 78
nuclear@24 79 num_faces = 0;
nuclear@13 80 for(size_t i=0; i<meshes.size(); i++) {
nuclear@13 81 num_faces += meshes[i]->faces.size();
nuclear@13 82 }
nuclear@13 83 return num_faces;
nuclear@13 84 }
nuclear@13 85
John@14 86 int Scene::get_num_materials() const
John@14 87 {
John@14 88 return (int)matlib.size();
John@14 89 }
John@14 90
John@14 91 Material *Scene::get_materials()
John@14 92 {
John@14 93 if(matlib.empty()) {
John@14 94 return 0;
John@14 95 }
John@14 96 return &matlib[0];
John@14 97 }
John@14 98
John@14 99 const Material *Scene::get_materials() const
John@14 100 {
John@14 101 if(matlib.empty()) {
John@14 102 return 0;
John@14 103 }
John@14 104 return &matlib[0];
John@14 105 }
nuclear@24 106
nuclear@24 107 const Face *Scene::get_face_buffer() const
nuclear@24 108 {
nuclear@24 109 if(facebuf) {
nuclear@24 110 return facebuf;
nuclear@24 111 }
nuclear@24 112
nuclear@24 113 int num_meshes = get_num_meshes();
nuclear@24 114
nuclear@24 115 printf("constructing face buffer with %d faces (out of %d meshes)\n", get_num_faces(), num_meshes);
nuclear@24 116 facebuf = new Face[num_faces];
nuclear@24 117 Face *fptr = facebuf;
nuclear@24 118
nuclear@24 119 for(int i=0; i<num_meshes; i++) {
nuclear@24 120 for(size_t j=0; j<meshes[i]->faces.size(); j++) {
nuclear@24 121 *fptr++ = meshes[i]->faces[j];
nuclear@24 122 }
nuclear@24 123 }
nuclear@24 124 return facebuf;
nuclear@24 125 }
nuclear@24 126
nuclear@25 127 static int build_kdtree(KDNode *kd);
nuclear@25 128 static void free_kdtree(KDNode *node);
nuclear@24 129
nuclear@24 130 void Scene::build_kdtree()
nuclear@24 131 {
nuclear@24 132 const Face *faces = get_face_buffer();
nuclear@24 133 int num_faces = get_num_faces();
nuclear@24 134
nuclear@25 135 printf("Constructing kd-tree out of %d faces ...\n", num_faces);
nuclear@25 136
nuclear@25 137 free_kdtree(kdtree);
nuclear@25 138 kdtree = new KDNode;
nuclear@25 139 kdtree->left = kdtree->right = 0;
nuclear@25 140
nuclear@25 141 /* Start the construction of the kdtree by adding all faces of the scene
nuclear@25 142 * to the new root node. At the same time calculate the root's AABB.
nuclear@25 143 */
nuclear@25 144 kdtree->aabb.min[0] = kdtree->aabb.min[1] = kdtree->aabb.min[2] = FLT_MAX;
nuclear@25 145 kdtree->aabb.max[0] = kdtree->aabb.max[1] = kdtree->aabb.max[2] = -FLT_MAX;
nuclear@25 146
nuclear@24 147 for(int i=0; i<num_faces; i++) {
nuclear@25 148 const Face *face = faces + i;
nuclear@25 149
nuclear@25 150 // for each vertex of the face ...
nuclear@25 151 for(int j=0; j<3; j++) {
nuclear@25 152 const float *pos = face->v[j].pos;
nuclear@25 153
nuclear@25 154 // for each element (xyz) of the position vector ...
nuclear@25 155 for(int k=0; k<3; k++) {
nuclear@25 156 if(pos[k] < kdtree->aabb.min[k]) {
nuclear@25 157 kdtree->aabb.min[k] = pos[k];
nuclear@25 158 }
nuclear@25 159 if(pos[k] > kdtree->aabb.max[k]) {
nuclear@25 160 kdtree->aabb.max[k] = pos[k];
nuclear@25 161 }
nuclear@25 162 }
nuclear@25 163 }
nuclear@25 164
nuclear@25 165 kdtree->faces.push_back(face); // add the face
nuclear@24 166 }
nuclear@24 167
nuclear@25 168 // now proceed splitting the root recursively
nuclear@25 169 ::build_kdtree(kdtree);
nuclear@24 170 }
nuclear@24 171
nuclear@25 172 static int build_kdtree(KDNode *kd)
nuclear@24 173 {
nuclear@25 174 if(kd->faces.empty()) {
nuclear@25 175 return 0;
nuclear@25 176 }
nuclear@25 177
nuclear@25 178 // XXX cont.
nuclear@25 179 return -1;
nuclear@24 180 }
nuclear@25 181
nuclear@25 182 static void free_kdtree(KDNode *node)
nuclear@25 183 {
nuclear@25 184 if(node) {
nuclear@25 185 free_kdtree(node->left);
nuclear@25 186 free_kdtree(node->right);
nuclear@25 187 delete node;
nuclear@25 188 }
nuclear@25 189 }