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 } |