00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00037 #include "collision_checking/BVH_model.h"
00038 #include "collision_checking/BV.h"
00039 #include <iostream>
00040 #include <string.h>
00041
00042 namespace collision_checking
00043 {
00044
00045
00046 template<typename BV>
00047 int BVHModel<BV>::beginModel(int num_tris_, int num_vertices_)
00048 {
00049 if(build_state != BVH_BUILD_STATE_EMPTY)
00050 {
00051 delete [] vertices; vertices = NULL;
00052 delete [] tri_indices; tri_indices = NULL;
00053 delete [] bvs; bvs = NULL;
00054 delete [] prev_vertices; prev_vertices = NULL;
00055 delete [] primitive_indices; primitive_indices = NULL;
00056
00057 num_vertices_allocated = num_vertices = num_tris_allocated = num_tris = num_bvs_allocated = num_bvs = 0;
00058 }
00059
00060 if(num_tris_ <= 0) num_tris_ = 8;
00061 if(num_vertices_ <= 0) num_vertices_ = 8;
00062
00063 num_vertices_allocated = num_vertices_;
00064 num_tris_allocated = num_tris_;
00065
00066 tri_indices = new Triangle[num_tris_allocated];
00067 vertices = new Vec3f[num_vertices_allocated];
00068
00069 if(!tri_indices)
00070 {
00071 std::cerr << "BVH Error! Out of memory for tri_indices array on BeginModel() call!" << std::endl;
00072 return BVH_ERR_MODEL_OUT_OF_MEMORY;
00073 }
00074 if(!vertices)
00075 {
00076 std::cerr << "BVH Error! Out of memory for vertices array on BeginModel() call!" << std::endl;
00077 return BVH_ERR_MODEL_OUT_OF_MEMORY;
00078 }
00079
00080 if(build_state != BVH_BUILD_STATE_EMPTY)
00081 {
00082 std::cerr << "BVH Warning! Call beginModel() on a BVHModel that is not empty. This model was cleared and previous triangles/vertices were lost." << std::endl;
00083 build_state = BVH_BUILD_STATE_EMPTY;
00084 return BVH_ERR_BUILD_OUT_OF_SEQUENCE;
00085 }
00086
00087 build_state = BVH_BUILD_STATE_BEGUN;
00088
00089 return BVH_OK;
00090 }
00091
00092
00093 template<typename BV>
00094 int BVHModel<BV>::addVertex(const Vec3f& p)
00095 {
00096 if(build_state != BVH_BUILD_STATE_UPDATE_BEGUN)
00097 {
00098 std::cerr << "BVH Warning! Call addVertex() in a wrong order. addVertex() was ignored. Must do a beginModel() to clear the model for addition of new vertices." << std::endl;
00099 return BVH_ERR_BUILD_OUT_OF_SEQUENCE;
00100 }
00101
00102 if(num_vertices >= num_vertices_allocated)
00103 {
00104 Vec3f* temp = new Vec3f[num_vertices_allocated * 2];
00105 if(!temp)
00106 {
00107 std::cerr << "BVH Error! Out of memory for vertices array on addVertex() call!" << std::endl;
00108 return BVH_ERR_MODEL_OUT_OF_MEMORY;
00109 }
00110
00111 memcpy(temp, vertices, sizeof(Vec3f) * num_vertices);
00112 delete [] vertices;
00113 vertices = temp;
00114 num_vertices_allocated *= 2;
00115 }
00116
00117 vertices[num_vertices] = p;
00118 num_vertices += 1;
00119
00120 return BVH_OK;
00121 }
00122
00123 template<typename BV>
00124 int BVHModel<BV>::addTriangle(const Vec3f& p1, const Vec3f& p2, const Vec3f& p3)
00125 {
00126 if(build_state == BVH_BUILD_STATE_PROCESSED)
00127 {
00128 std::cerr << "BVH Warning! Call addTriangle() in a wrong order. addTriangle() was ignored. Must do a beginModel() to clear the model for addition of new triangles." << std::endl;
00129 return BVH_ERR_BUILD_OUT_OF_SEQUENCE;
00130 }
00131
00132 if(num_vertices + 2 >= num_vertices_allocated)
00133 {
00134 Vec3f* temp = new Vec3f[num_vertices_allocated * 2 + 2];
00135 if(!temp)
00136 {
00137 std::cerr << "BVH Error! Out of memory for vertices array on addTriangle() call!" << std::endl;
00138 return BVH_ERR_MODEL_OUT_OF_MEMORY;
00139 }
00140
00141 memcpy(temp, vertices, sizeof(Vec3f) * num_vertices);
00142 delete [] vertices;
00143 vertices = temp;
00144 num_vertices_allocated = num_vertices_allocated * 2 + 2;
00145 }
00146
00147 int offset = num_vertices;
00148
00149 vertices[num_vertices] = p1;
00150 num_vertices++;
00151 vertices[num_vertices] = p2;
00152 num_vertices++;
00153 vertices[num_vertices] = p3;
00154 num_vertices++;
00155
00156 if(num_tris >= num_tris_allocated)
00157 {
00158 Triangle* temp = new Triangle[num_tris_allocated * 2];
00159 if(!temp)
00160 {
00161 std::cerr << "BVH Error! Out of memory for tri_indices array on addTriangle() call!" << std::endl;
00162 return BVH_ERR_MODEL_OUT_OF_MEMORY;
00163 }
00164
00165 memcpy(temp, tri_indices, sizeof(Triangle) * num_tris);
00166 delete [] tri_indices;
00167 tri_indices = temp;
00168 num_tris_allocated *= 2;
00169 }
00170
00171 tri_indices[num_tris] = Triangle(offset, offset + 1, offset + 2);
00172
00173 return BVH_OK;
00174 }
00175
00176 template<typename BV>
00177 int BVHModel<BV>::addSubModel(const std::vector<Vec3f>& ps)
00178 {
00179 if(build_state == BVH_BUILD_STATE_PROCESSED)
00180 {
00181 std::cerr << "BVH Warning! Call addSubModel() in a wrong order. addSubModel() was ignored. Must do a beginModel() to clear the model for addition of new vertices." << std::endl;
00182 return BVH_ERR_BUILD_OUT_OF_SEQUENCE;
00183 }
00184
00185 int num_vertices_to_add = ps.size();
00186
00187 if(num_vertices + num_vertices_to_add - 1 >= num_vertices_allocated)
00188 {
00189 Vec3f* temp = new Vec3f[num_vertices_allocated * 2 + num_vertices_to_add - 1];
00190 if(!temp)
00191 {
00192 std::cerr << "BVH Error! Out of memory for vertices array on addSubModel() call!" << std::endl;
00193 return BVH_ERR_MODEL_OUT_OF_MEMORY;
00194 }
00195
00196 memcpy(temp, vertices, sizeof(Vec3f) * num_vertices);
00197 delete [] vertices;
00198 vertices = temp;
00199 num_vertices_allocated = num_vertices_allocated * 2 + num_vertices_to_add - 1;
00200 }
00201
00202 for(int i = 0; i < num_vertices_to_add; ++i)
00203 {
00204 vertices[num_vertices] = ps[i];
00205 num_vertices++;
00206 }
00207
00208 return BVH_OK;
00209 }
00210
00211 template<typename BV>
00212 int BVHModel<BV>::addSubModel(const std::vector<Vec3f>& ps, const std::vector<Triangle>& ts)
00213 {
00214 if(build_state == BVH_BUILD_STATE_PROCESSED)
00215 {
00216 std::cerr << "BVH Warning! Call addSubModel() in a wrong order. addSubModel() was ignored. Must do a beginModel() to clear the model for addition of new vertices." << std::endl;
00217 return BVH_ERR_BUILD_OUT_OF_SEQUENCE;
00218 }
00219
00220 int num_vertices_to_add = ps.size();
00221
00222 if(num_vertices + num_vertices_to_add - 1 >= num_vertices_allocated)
00223 {
00224 Vec3f* temp = new Vec3f[num_vertices_allocated * 2 + num_vertices_to_add - 1];
00225 if(!temp)
00226 {
00227 std::cerr << "BVH Error! Out of memory for vertices array on addSubModel() call!" << std::endl;
00228 return BVH_ERR_MODEL_OUT_OF_MEMORY;
00229 }
00230
00231 memcpy(temp, vertices, sizeof(Vec3f) * num_vertices);
00232 delete [] vertices;
00233 vertices = temp;
00234 num_vertices_allocated = num_vertices_allocated * 2 + num_vertices_to_add - 1;
00235 }
00236
00237 int offset = num_vertices;
00238
00239 for(int i = 0; i < num_vertices_to_add; ++i)
00240 {
00241 vertices[num_vertices] = ps[i];
00242 num_vertices++;
00243 }
00244
00245
00246 int num_tris_to_add = ts.size();
00247
00248 if(num_tris + num_tris_to_add - 1 >= num_tris_allocated)
00249 {
00250 Triangle* temp = new Triangle[num_tris_allocated * 2 + num_tris_to_add - 1];
00251 if(!temp)
00252 {
00253 std::cerr << "BVH Error! Out of memory for tri_indices array on addSubModel() call!" << std::endl;
00254 return BVH_ERR_MODEL_OUT_OF_MEMORY;
00255 }
00256
00257 memcpy(temp, tri_indices, sizeof(Triangle) * num_tris);
00258 delete [] tri_indices;
00259 tri_indices = temp;
00260 num_tris_allocated = num_tris_allocated * 2 + num_tris_to_add - 1;
00261 }
00262
00263 for(int i = 0; i < num_tris_to_add; ++i)
00264 {
00265 const Triangle& t = ts[i];
00266 tri_indices[num_tris] = Triangle(t[0] + offset, t[1] + offset, t[2] + offset);
00267 num_tris++;
00268 }
00269
00270 return BVH_OK;
00271 }
00272
00273 template<typename BV>
00274 int BVHModel<BV>::endModel()
00275 {
00276 if(build_state != BVH_BUILD_STATE_BEGUN)
00277 {
00278 std::cerr << "BVH Warning! Call endModel() in wrong order. endModel() was ignored." << std::endl;
00279 return BVH_ERR_BUILD_OUT_OF_SEQUENCE;
00280 }
00281
00282 if(num_tris == 0 && num_vertices == 0)
00283 {
00284 std::cerr << "BVH Error! endModel() called on model with no triangles and vertices." << std::endl;
00285 return BVH_ERR_BUILD_EMPTY_MODEL;
00286 }
00287
00288 if(num_tris_allocated > num_tris)
00289 {
00290 Triangle* new_tris = new Triangle[num_tris];
00291 if(!new_tris)
00292 {
00293 std::cerr << "BVH Error! Out of memory for tri_indices array in endModel() call!" << std::endl;
00294 return BVH_ERR_MODEL_OUT_OF_MEMORY;
00295 }
00296 memcpy(new_tris, tri_indices, sizeof(Triangle) * num_tris);
00297 delete [] tri_indices;
00298 tri_indices = new_tris;
00299 num_tris_allocated = num_tris;
00300 }
00301
00302 if(num_vertices_allocated > num_vertices)
00303 {
00304 Vec3f* new_vertices = new Vec3f[num_vertices];
00305 if(!new_vertices)
00306 {
00307 std::cerr << "BVH Error! Out of memory for vertices array in endModel() call!" << std::endl;
00308 return BVH_ERR_MODEL_OUT_OF_MEMORY;
00309 }
00310 memcpy(new_vertices, vertices, sizeof(Vec3f) * num_vertices);
00311 delete [] vertices;
00312 vertices = new_vertices;
00313 num_vertices_allocated = num_vertices;
00314 }
00315
00316
00317 int num_bvs_to_be_allocated = 0;
00318 if(num_tris == 0)
00319 num_bvs_to_be_allocated = 2 * num_vertices - 1;
00320 else
00321 num_bvs_to_be_allocated = 2 * num_tris - 1;
00322
00323
00324 bvs = new BVNode<BV> [num_bvs_to_be_allocated];
00325 primitive_indices = new unsigned int [num_bvs_to_be_allocated];
00326 if(!bvs || !primitive_indices)
00327 {
00328 std::cerr << "BVH Error! Out of memory for BV array in endModel()!" << std::endl;
00329 return BVH_ERR_MODEL_OUT_OF_MEMORY;
00330 }
00331 num_bvs_allocated = num_bvs_to_be_allocated;
00332 num_bvs = 0;
00333
00334 buildTree();
00335
00336
00337 build_state = BVH_BUILD_STATE_PROCESSED;
00338
00339 return BVH_OK;
00340 }
00341
00342
00343
00344 template<typename BV>
00345 int BVHModel<BV>::beginReplaceModel()
00346 {
00347 if(build_state != BVH_BUILD_STATE_PROCESSED)
00348 {
00349 std::cerr << "BVH Error! Call beginReplaceModel() on a BVHModel that has no previous frame." << std::endl;
00350 return BVH_ERR_BUILD_EMPTY_PREVIOUS_FRAME;
00351 }
00352
00353 if(prev_vertices) delete [] prev_vertices; prev_vertices = NULL;
00354
00355 num_vertex_updated = 0;
00356
00357 build_state = BVH_BUILD_STATE_REPLACE_BEGUN;
00358
00359 return BVH_OK;
00360 }
00361
00362 template<typename BV>
00363 int BVHModel<BV>::replaceVertex(const Vec3f& p)
00364 {
00365 if(build_state != BVH_BUILD_STATE_REPLACE_BEGUN)
00366 {
00367 std::cerr << "BVH Warning! Call replaceVertex() in a wrong order. replaceVertex() was ignored. Must do a beginReplaceModel() for initialization." << std::endl;
00368 return BVH_ERR_BUILD_OUT_OF_SEQUENCE;
00369 }
00370
00371 vertices[num_vertex_updated] = p;
00372 num_vertex_updated++;
00373
00374 return BVH_OK;
00375 }
00376
00377 template<typename BV>
00378 int BVHModel<BV>::replaceTriangle(const Vec3f& p1, const Vec3f& p2, const Vec3f& p3)
00379 {
00380 if(build_state != BVH_BUILD_STATE_REPLACE_BEGUN)
00381 {
00382 std::cerr << "BVH Warning! Call replaceTriangle() in a wrong order. replaceTriangle() was ignored. Must do a beginReplaceModel() for initialization." << std::endl;
00383 return BVH_ERR_BUILD_OUT_OF_SEQUENCE;
00384 }
00385
00386 vertices[num_vertex_updated] = p1; num_vertex_updated++;
00387 vertices[num_vertex_updated] = p2; num_vertex_updated++;
00388 vertices[num_vertex_updated] = p3; num_vertex_updated++;
00389 return BVH_OK;
00390 }
00391
00392 template<typename BV>
00393 int BVHModel<BV>::replaceSubModel(const std::vector<Vec3f>& ps)
00394 {
00395 if(build_state != BVH_BUILD_STATE_REPLACE_BEGUN)
00396 {
00397 std::cerr << "BVH Warning! Call replaceSubModel() in a wrong order. replaceSubModel() was ignored. Must do a beginReplaceModel() for initialization." << std::endl;
00398 return BVH_ERR_BUILD_OUT_OF_SEQUENCE;
00399 }
00400
00401 for(unsigned int i = 0; i < ps.size(); ++i)
00402 {
00403 vertices[num_vertex_updated] = ps[i];
00404 num_vertex_updated++;
00405 }
00406 return BVH_OK;
00407 }
00408
00409 template<typename BV>
00410 int BVHModel<BV>::endReplaceModel(bool refit, bool bottomup)
00411 {
00412 if(build_state != BVH_BUILD_STATE_REPLACE_BEGUN)
00413 {
00414 std::cerr << "BVH Warning! Call endReplaceModel() in a wrong order. endReplaceModel() was ignored. " << std::endl;
00415 return BVH_ERR_BUILD_OUT_OF_SEQUENCE;
00416 }
00417
00418 if(num_vertex_updated != num_vertices)
00419 {
00420 std::cerr << "BVH Error! The replaced model should have the same number of vertices as the old model." << std::endl;
00421 return BVH_ERR_INCORRECT_DATA;
00422 }
00423
00424 if(refit)
00425 {
00426 refitTree(bottomup);
00427 }
00428 else
00429 {
00430 buildTree();
00431 }
00432
00433 build_state = BVH_BUILD_STATE_PROCESSED;
00434
00435 return BVH_OK;
00436 }
00437
00438
00439
00440
00441
00442 template<typename BV>
00443 int BVHModel<BV>::beginUpdateModel()
00444 {
00445 if(build_state != BVH_BUILD_STATE_PROCESSED && build_state != BVH_BUILD_STATE_UPDATED)
00446 {
00447 std::cerr << "BVH Error! Call beginUpdatemodel() on a BVHModel that has no previous frame." << std::endl;
00448 return BVH_ERR_BUILD_EMPTY_PREVIOUS_FRAME;
00449 }
00450
00451 if(prev_vertices)
00452 {
00453 Vec3f* temp = prev_vertices;
00454 prev_vertices = vertices;
00455 vertices = temp;
00456 }
00457 else
00458 {
00459 prev_vertices = vertices;
00460 vertices = new Vec3f[num_vertices];
00461 }
00462
00463 num_vertex_updated = 0;
00464
00465 build_state = BVH_BUILD_STATE_UPDATE_BEGUN;
00466
00467 return BVH_OK;
00468 }
00469
00470 template<typename BV>
00471 int BVHModel<BV>::updateVertex(const Vec3f& p)
00472 {
00473 if(build_state != BVH_BUILD_STATE_UPDATE_BEGUN)
00474 {
00475 std::cerr << "BVH Warning! Call updateVertex() in a wrong order. updateVertex() was ignored. Must do a beginUpdateModel() for initialization." << std::endl;
00476 return BVH_ERR_BUILD_OUT_OF_SEQUENCE;
00477 }
00478
00479 vertices[num_vertex_updated] = p;
00480 num_vertex_updated++;
00481
00482 return BVH_OK;
00483 }
00484
00485 template<typename BV>
00486 int BVHModel<BV>::updateTriangle(const Vec3f& p1, const Vec3f& p2, const Vec3f& p3)
00487 {
00488 if(build_state != BVH_BUILD_STATE_UPDATE_BEGUN)
00489 {
00490 std::cerr << "BVH Warning! Call updateTriangle() in a wrong order. updateTriangle() was ignored. Must do a beginUpdateModel() for initialization." << std::endl;
00491 return BVH_ERR_BUILD_OUT_OF_SEQUENCE;
00492 }
00493
00494 vertices[num_vertex_updated] = p1; num_vertex_updated++;
00495 vertices[num_vertex_updated] = p2; num_vertex_updated++;
00496 vertices[num_vertex_updated] = p3; num_vertex_updated++;
00497 return BVH_OK;
00498 }
00499
00500 template<typename BV>
00501 int BVHModel<BV>::updateSubModel(const std::vector<Vec3f>& ps)
00502 {
00503 if(build_state != BVH_BUILD_STATE_UPDATE_BEGUN)
00504 {
00505 std::cerr << "BVH Warning! Call updateSubModel() in a wrong order. updateSubModel() was ignored. Must do a beginUpdateModel() for initialization." << std::endl;
00506 return BVH_ERR_BUILD_OUT_OF_SEQUENCE;
00507 }
00508
00509 for(unsigned int i = 0; i < ps.size(); ++i)
00510 {
00511 vertices[num_vertex_updated] = ps[i];
00512 num_vertex_updated++;
00513 }
00514 return BVH_OK;
00515 }
00516
00517 template<typename BV>
00518 int BVHModel<BV>::endUpdateModel(bool refit, bool bottomup)
00519 {
00520 if(build_state != BVH_BUILD_STATE_UPDATE_BEGUN)
00521 {
00522 std::cerr << "BVH Warning! Call endUpdateModel() in a wrong order. endUpdateModel() was ignored. " << std::endl;
00523 return BVH_ERR_BUILD_OUT_OF_SEQUENCE;
00524 }
00525
00526 if(num_vertex_updated != num_vertices)
00527 {
00528 std::cerr << "BVH Error! The updated model should have the same number of vertices as the old model." << std::endl;
00529 return BVH_ERR_INCORRECT_DATA;
00530 }
00531
00532 if(refit)
00533 {
00534 refitTree(bottomup);
00535 }
00536 else
00537 {
00538 buildTree();
00539
00540
00541
00542 refitTree(bottomup);
00543 }
00544
00545
00546 build_state = BVH_BUILD_STATE_UPDATED;
00547
00548 return BVH_OK;
00549 }
00550
00551
00552
00553
00554 template<typename BV>
00555 int BVHModel<BV>::memUsage(int msg) const
00556 {
00557 int mem_bv_list = sizeof(BV) * num_bvs;
00558 int mem_tri_list = sizeof(Triangle) * num_tris;
00559 int mem_vertex_list = sizeof(Vec3f) * num_vertices;
00560
00561 int total_mem = mem_bv_list + mem_tri_list + mem_vertex_list + sizeof(BVHModel<BV>);
00562 if(msg)
00563 {
00564 std::cerr << "Total for model " << total_mem << " bytes." << std::endl;
00565 std::cerr << "BVs: " << num_bvs << " allocated." << std::endl;
00566 std::cerr << "Tris: " << num_tris << " allocated." << std::endl;
00567 std::cerr << "Vertices: " << num_vertices << " allocated." << std::endl;
00568 }
00569
00570 return BVH_OK;
00571 }
00572
00573
00574 template<typename BV>
00575 int BVHModel<BV>::buildTree()
00576 {
00577
00578 bv_fitter.set(vertices, tri_indices, getModelType());
00579
00580 bv_splitter.set(vertices, tri_indices, getModelType());
00581
00582 num_bvs = 1;
00583
00584 int num_primitives = 0;
00585 switch(getModelType())
00586 {
00587 case BVH_MODEL_TRIANGLES:
00588 num_primitives = num_tris;
00589 break;
00590 case BVH_MODEL_POINTCLOUD:
00591 num_primitives = num_vertices;
00592 break;
00593 default:
00594 std::cerr << "BVH Error: Model type not supported!" << std::endl;
00595 return BVH_ERR_UNSUPPORTED_FUNCTION;
00596 }
00597
00598 for(int i = 0; i < num_primitives; ++i)
00599 primitive_indices[i] = i;
00600
00601 recursiveBuildTree(0, 0, num_primitives);
00602
00603
00604 bv_fitter.clear();
00605 bv_splitter.clear();
00606
00607 return BVH_OK;
00608 }
00609
00610 template<typename BV>
00611 int BVHModel<BV>::recursiveBuildTree(int bv_id, int first_primitive, int num_primitives)
00612 {
00613 BVHModelType type = getModelType();
00614 BVNode<BV>* bvnode = bvs + bv_id;
00615 unsigned int* cur_primitive_indices = primitive_indices + first_primitive;
00616
00617
00618 BV bv = bv_fitter.fit(cur_primitive_indices, num_primitives);
00619 bv_splitter.computeRule(bv, cur_primitive_indices, num_primitives);
00620
00621
00622 bvnode->bv = bv;
00623 bvnode->first_primitive = first_primitive;
00624 bvnode->num_primitives = num_primitives;
00625
00626 if(num_primitives == 1)
00627 {
00628 bvnode->first_child = -((*cur_primitive_indices) + 1);
00629 }
00630 else
00631 {
00632 bvnode->first_child = num_bvs;
00633 num_bvs += 2;
00634
00635 int c1 = 0;
00636 for(int i = 0; i < num_primitives; ++i)
00637 {
00638 Vec3f p;
00639 if(type == BVH_MODEL_POINTCLOUD) p = vertices[cur_primitive_indices[i]];
00640 else if(type == BVH_MODEL_TRIANGLES)
00641 {
00642 const Triangle& t = tri_indices[cur_primitive_indices[i]];
00643 const Vec3f& p1 = vertices[t[0]];
00644 const Vec3f& p2 = vertices[t[1]];
00645 const Vec3f& p3 = vertices[t[2]];
00646 BVH_REAL x = (p1[0] + p2[0] + p3[0]) / 3;
00647 BVH_REAL y = (p1[1] + p2[1] + p3[1]) / 3;
00648 BVH_REAL z = (p1[2] + p2[2] + p3[2]) / 3;
00649 p = Vec3f(x, y, z);
00650 }
00651 else
00652 {
00653 std::cerr << "BVH Error: Model type not supported!" << std::endl;
00654 return BVH_ERR_UNSUPPORTED_FUNCTION;
00655 }
00656
00657
00658
00659
00660
00661
00662
00663
00664 if(bv_splitter(p))
00665 {
00666
00667 }
00668 else
00669 {
00670 unsigned int temp = cur_primitive_indices[i];
00671 cur_primitive_indices[i] = cur_primitive_indices[c1];
00672 cur_primitive_indices[c1] = temp;
00673 c1++;
00674 }
00675 }
00676
00677
00678 if((c1 == 0) || (c1 == num_primitives)) c1 = num_primitives / 2;
00679
00680 int num_first_half = c1;
00681
00682 recursiveBuildTree(bvnode->leftChild(), first_primitive, num_first_half);
00683 recursiveBuildTree(bvnode->rightChild(), first_primitive + num_first_half, num_primitives - num_first_half);
00684 }
00685
00686 return BVH_OK;
00687 }
00688
00689 template<typename BV>
00690 int BVHModel<BV>::refitTree(bool bottomup)
00691 {
00692 if(bottomup)
00693 return refitTree_bottomup();
00694 else
00695 return refitTree_topdown();
00696 }
00697
00698 template<typename BV>
00699 int BVHModel<BV>::refitTree_bottomup()
00700 {
00701 int res = recursiveRefitTree_bottomup(0);
00702
00703 return res;
00704 }
00705
00706
00707 template<typename BV>
00708 int BVHModel<BV>::recursiveRefitTree_bottomup(int bv_id)
00709 {
00710 BVNode<BV>* bvnode = bvs + bv_id;
00711 if(bvnode->isLeaf())
00712 {
00713 BVHModelType type = getModelType();
00714 int primitive_id = -(bvnode->first_child + 1);
00715 if(type == BVH_MODEL_POINTCLOUD)
00716 {
00717 BV bv;
00718
00719 if(prev_vertices)
00720 {
00721 Vec3f v[2];
00722 v[0] = prev_vertices[primitive_id];
00723 v[1] = vertices[primitive_id];
00724 bv = BVFitter<BV>::fit(v, 2);
00725 }
00726 else
00727 {
00728
00729
00730 bv = BVFitter<BV>::fit(vertices + primitive_id, 1);
00731 }
00732
00733 bvnode->bv = bv;
00734 }
00735 else if(type == BVH_MODEL_TRIANGLES)
00736 {
00737 BV bv;
00738 const Triangle& triangle = tri_indices[primitive_id];
00739
00740 if(prev_vertices)
00741 {
00742 Vec3f v[6];
00743 for(int i = 0; i < 3; ++i)
00744 {
00745 v[i] = prev_vertices[triangle[i]];
00746 v[i + 3] = vertices[triangle[i]];
00747 }
00748
00749 bv = BVFitter<BV>::fit(v, 6);
00750 }
00751 else
00752 {
00753 Vec3f v[3];
00754 for(int i = 0; i < 3; ++i)
00755 {
00756 v[i] = vertices[triangle[i]];
00757 }
00758
00759 bv = BVFitter<BV>::fit(v, 3);
00760 }
00761
00762 bvnode->bv = bv;
00763 }
00764 else
00765 {
00766 std::cerr << "BVH Error: Model type not supported!" << std::endl;
00767 return BVH_ERR_UNSUPPORTED_FUNCTION;
00768 }
00769 }
00770 else
00771 {
00772 recursiveRefitTree_bottomup(bvnode->leftChild());
00773 recursiveRefitTree_bottomup(bvnode->rightChild());
00774 bvnode->bv = bvs[bvnode->leftChild()].bv + bvs[bvnode->rightChild()].bv;
00775 }
00776
00777 return BVH_OK;
00778 }
00779
00780 template<typename BV>
00781 int BVHModel<BV>::refitTree_topdown()
00782 {
00783 bv_fitter.set(vertices, prev_vertices, tri_indices, getModelType());
00784 for(int i = 0; i < num_bvs; ++i)
00785 {
00786 BV bv = bv_fitter.fit(primitive_indices + bvs[i].first_primitive, bvs[i].num_primitives);
00787 bvs[i].bv = bv;
00788 }
00789
00790 bv_fitter.clear();
00791
00792 return BVH_OK;
00793 }
00794
00795
00796 template class BVHModel<KDOP<16> >;
00797 template class BVHModel<KDOP<18> >;
00798 template class BVHModel<KDOP<24> >;
00799 template class BVHModel<OBB>;
00800 template class BVHModel<AABB>;
00801 template class BVHModel<RSS>;
00802
00803 }