$search
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Copyright (c) 2011, Willow Garage, Inc. 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * * Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * * Redistributions in binary form must reproduce the above 00014 * copyright notice, this list of conditions and the following 00015 * disclaimer in the documentation and/or other materials provided 00016 * with the distribution. 00017 * * Neither the name of Willow Garage, Inc. nor the names of its 00018 * contributors may be used to endorse or promote products derived 00019 * from this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00024 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00025 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00026 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00027 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00028 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00031 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 * POSSIBILITY OF SUCH DAMAGE. 00033 */ 00034 00037 #ifndef COLLISION_CHECKING_COLLISION_GEOM_H 00038 #define COLLISION_CHECKING_COLLISION_GEOM_H 00039 00040 #include <fstream> 00041 #include <vector> 00042 #include <boost/math/constants/constants.hpp> 00043 #include <LinearMath/btTransform.h> 00044 #include "collision_checking/collision.h" 00045 00046 namespace collision_checking 00047 { 00048 00049 inline void saveOBjFile(const std::string& name, const std::vector<Vec3f>& points, const std::vector<Triangle>& tri_indices) 00050 { 00051 std::ofstream file(name.c_str()); 00052 file << points.size() << " " << tri_indices.size() << std::endl; 00053 for(unsigned int i = 0; i < points.size(); ++i) 00054 { 00055 file << "v " << points[i][0] << " " << points[i][1] << " " << points[i][2] << std::endl; 00056 } 00057 for(unsigned int i = 0; i < tri_indices.size(); ++i) 00058 { 00059 file << "f " << tri_indices[i][0] + 1 << " " << tri_indices[i][1] + 1 << " " << tri_indices[i][2] + 1 << std::endl; 00060 } 00061 } 00062 00063 struct CollisionGeom 00064 { 00065 CollisionGeom() 00066 { 00067 ccd = false; 00068 t1.setIdentity(); 00069 t2.setIdentity(); 00070 } 00071 00072 virtual ~CollisionGeom() 00073 {} 00074 00075 virtual BVH_CollideResult collide(CollisionGeom* other, int num_contacts = 0) { BVH_CollideResult res; return res; } 00076 00077 virtual void applyTransform(const btTransform& pose, bool refit = true, bool bottomup = true) 00078 { 00079 t2 = t1; 00080 t1 = pose; 00081 } 00082 00083 virtual void computeAABB() {} 00084 00085 bool ccd; 00086 btTransform t1; // current 00087 btTransform t2; // previous 00088 00089 AABB aabb; 00090 }; 00091 00092 00093 00094 template<typename BV> 00095 struct CollisionMesh; 00096 template<typename BV> 00097 CollisionMesh<BV>* makeMesh(const std::vector<Vec3f>& points, const std::vector<Triangle>& tri_indices); 00098 template<typename BV> 00099 CollisionMesh<BV>* makeBox(double a, double b, double c); 00100 template<typename BV> 00101 CollisionMesh<BV>* makeCylinder(double r, double h, unsigned int tot = 16); 00102 template<typename BV> 00103 CollisionMesh<BV>* makeSphere(double r, unsigned int seg = 16, unsigned int ring = 16); 00104 00105 template<typename BV> 00106 struct CollisionMesh : public CollisionGeom 00107 { 00108 private: 00109 CollisionMesh() : CollisionGeom() 00110 { 00111 } 00112 00113 public: 00114 friend CollisionMesh<BV>* makeMesh<>(const std::vector<Vec3f>& points, const std::vector<Triangle>& tri_indices); 00115 friend CollisionMesh<BV>* makeBox<>(double a, double b, double c); 00116 friend CollisionMesh<BV>* makeCylinder<>(double r, double h, unsigned int tot); 00117 friend CollisionMesh<BV>* makeSphere<>(double r, unsigned int seg, unsigned int ring); 00118 00119 // TODO: get rid of dynamic_cast<> :( 00120 BVH_CollideResult collide(CollisionGeom* other, int num_max_contacts = 0) 00121 { 00122 BVH_CollideResult res; 00123 res.num_max_contacts = num_max_contacts; 00124 CollisionMesh<BV>* othermesh = dynamic_cast<CollisionMesh<BV>* >(other); 00125 if(othermesh) 00126 { 00127 collision_checking::collide(model, othermesh->model, &res); 00128 } 00129 00130 return res; 00131 } 00132 00133 void applyTransform(const btTransform& pose, bool refit = false, bool bottomup = true) 00134 { 00135 t2 = t1; 00136 t1 = pose; 00137 00138 std::vector<Vec3f> points; 00139 for(int i = 0; i < model.num_vertices; ++i) 00140 { 00141 const Vec3f& p = model.vertices[i]; 00142 btVector3 v(p[0], p[1], p[2]); 00143 v = pose * v; 00144 points[i] = Vec3f(v.x(), v.y(), v.z()); 00145 } 00146 00147 if(ccd) 00148 { 00149 model.beginUpdateModel(); 00150 model.updateSubModel(points); 00151 model.endUpdateModel(refit, bottomup); 00152 } 00153 else 00154 { 00155 model.beginReplaceModel(); 00156 model.replaceSubModel(points); 00157 model.endReplaceModel(refit, bottomup); 00158 } 00159 00160 computeAABB(); 00161 } 00162 00163 void computeAABB() 00164 { 00165 AABB aabb_; 00166 if(ccd) 00167 { 00168 for(int i = 0; i < model.num_vertices; ++i) 00169 { 00170 aabb_ += model.vertices[i]; 00171 aabb_ += model.prev_vertices[i]; 00172 } 00173 } 00174 else 00175 { 00176 for(int i = 0; i < model.num_vertices; ++i) 00177 { 00178 aabb_ += model.vertices[i]; 00179 } 00180 } 00181 00182 aabb = aabb_; 00183 } 00184 00185 00186 BVHModel<BV> model; 00187 }; 00188 00189 00191 template<> 00192 struct CollisionMesh<OBB> : public CollisionGeom 00193 { 00194 private: 00195 CollisionMesh() : CollisionGeom() 00196 { 00197 } 00198 00199 public: 00200 friend CollisionMesh<OBB>* makeMesh<>(const std::vector<Vec3f>& points, const std::vector<Triangle>& tri_indices); 00201 friend CollisionMesh<OBB>* makeBox<>(double a, double b, double c); 00202 friend CollisionMesh<OBB>* makeCylinder<>(double r, double h, unsigned int tot); 00203 friend CollisionMesh<OBB>* makeSphere<>(double r, unsigned int seg, unsigned int ring); 00204 00205 // TODO: get rid of dynamic_cast<> :( 00206 BVH_CollideResult collide(CollisionGeom* other, int num_max_contacts = 0) 00207 { 00208 BVH_CollideResult res; 00209 res.num_max_contacts = num_max_contacts; 00210 CollisionMesh<OBB>* othermesh = dynamic_cast<CollisionMesh<OBB>* >(other); 00211 if(othermesh) 00212 { 00213 Vec3f R1[3]; 00214 Vec3f R2[3]; 00215 Vec3f T1; 00216 Vec3f T2; 00217 btVector3 t = t1.getOrigin(); 00218 T1 = Vec3f(t.x(), t.y(), t.z()); 00219 btMatrix3x3 r = t1.getBasis(); 00220 for(int i = 0; i < 3; ++i) 00221 R1[i] = Vec3f(r[i].x(), r[i].y(), r[i].z()); 00222 00223 t = othermesh->t1.getOrigin(); 00224 T2 = Vec3f(t.x(), t.y(), t.z()); 00225 r = othermesh->t1.getBasis(); 00226 for(int i = 0; i < 3; ++i) 00227 R2[i] = Vec3f(r[i].x(), r[i].y(), r[i].z()); 00228 00229 collision_checking::collide(model, R1, T1, othermesh->model, R2, T2, &res); 00230 } 00231 00232 return res; 00233 } 00234 00235 void applyTransform(const btTransform& pose, bool refit = true, bool bottomup = true) 00236 { 00237 t2 = t1; 00238 t1 = pose; 00239 00240 computeAABB(); 00241 } 00242 00243 void computeAABB() 00244 { 00245 AABB aabb_; 00246 00247 /* Compute an exact AABB from vertices, slow :( 00248 if(ccd) 00249 { 00250 for(int i = 0; i < model.num_vertices; ++i) 00251 { 00252 Vec3f p = model.vertices[i]; 00253 btVector3 v(p[0], p[1], p[2]); 00254 btVector3 v1 = t1 * v; 00255 btVector3 v2 = t2 * v; 00256 00257 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00258 aabb_ += Vec3f(v2.x(), v2.y(), v2.z()); 00259 } 00260 } 00261 else 00262 { 00263 for(int i = 0; i < model.num_vertices; ++i) 00264 { 00265 Vec3f p = model.vertices[i]; 00266 btVector3 v(p[0], p[1], p[2]); 00267 btVector3 v1 = t1 * v; 00268 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00269 } 00270 } 00271 */ 00272 00273 /* So we only compute a rough AABB from rotated OBB */ 00274 00275 if(ccd) 00276 { 00277 BVNode<OBB>* obb = model.bvs; 00278 Vec3f p; 00279 btVector3 v; 00280 btVector3 v1; 00281 00282 Vec3f& axis0 = obb->bv.axis[0]; 00283 Vec3f& axis1 = obb->bv.axis[1]; 00284 Vec3f& axis2 = obb->bv.axis[2]; 00285 Vec3f& To = obb->bv.To; 00286 Vec3f& extent = obb->bv.extent; 00287 00288 p = To + axis0 * extent[0] + axis1 * extent[1] + axis2 * extent[2]; 00289 v = btVector3(p[0], p[1], p[2]); 00290 v1 = t1 * v; 00291 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00292 v1 = t2 * v; 00293 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00294 00295 p = To + axis0 * extent[0] + axis1 * extent[1] + axis2 * (-extent[2]); 00296 v = btVector3(p[0], p[1], p[2]); 00297 v1 = t1 * v; 00298 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00299 v1 = t2 * v; 00300 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00301 00302 p = To + axis0 * extent[0] + axis1 * (-extent[1]) + axis2 * extent[2]; 00303 v = btVector3(p[0], p[1], p[2]); 00304 v1 = t1 * v; 00305 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00306 v1 = t2 * v; 00307 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00308 00309 p = To + axis0 * extent[0] + axis1 * (-extent[1]) + axis2 * (-extent[2]); 00310 v = btVector3(p[0], p[1], p[2]); 00311 v1 = t1 * v; 00312 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00313 v1 = t2 * v; 00314 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00315 00316 p = To + axis0 * (-extent[0]) + axis1 * extent[1] + axis2 * extent[2]; 00317 v = btVector3(p[0], p[1], p[2]); 00318 v1 = t1 * v; 00319 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00320 v1 = t2 * v; 00321 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00322 00323 p = To + axis0 * (-extent[0]) + axis1 * extent[1] + axis2 * (-extent[2]); 00324 v = btVector3(p[0], p[1], p[2]); 00325 v1 = t1 * v; 00326 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00327 v1 = t2 * v; 00328 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00329 00330 p = To + axis0 * (-extent[0]) + axis1 * (-extent[1]) + axis2 * extent[2]; 00331 v = btVector3(p[0], p[1], p[2]); 00332 v1 = t1 * v; 00333 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00334 v1 = t2 * v; 00335 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00336 00337 p = To + axis0 * (-extent[0]) + axis1 * (-extent[1]) + axis2 * (-extent[2]); 00338 v = btVector3(p[0], p[1], p[2]); 00339 v1 = t1 * v; 00340 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00341 v1 = t2 * v; 00342 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00343 } 00344 else 00345 { 00346 BVNode<OBB>* obb = model.bvs; 00347 Vec3f p; 00348 btVector3 v; 00349 btVector3 v1; 00350 00351 Vec3f& axis0 = obb->bv.axis[0]; 00352 Vec3f& axis1 = obb->bv.axis[1]; 00353 Vec3f& axis2 = obb->bv.axis[2]; 00354 Vec3f& To = obb->bv.To; 00355 Vec3f& extent = obb->bv.extent; 00356 00357 p = To + axis0 * extent[0] + axis1 * extent[1] + axis2 * extent[2]; 00358 v = btVector3(p[0], p[1], p[2]); 00359 v1 = t1 * v; 00360 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00361 00362 p = To + axis0 * extent[0] + axis1 * extent[1] + axis2 * (-extent[2]); 00363 v = btVector3(p[0], p[1], p[2]); 00364 v1 = t1 * v; 00365 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00366 00367 p = To + axis0 * extent[0] + axis1 * (-extent[1]) + axis2 * extent[2]; 00368 v = btVector3(p[0], p[1], p[2]); 00369 v1 = t1 * v; 00370 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00371 00372 p = To + axis0 * extent[0] + axis1 * (-extent[1]) + axis2 * (-extent[2]); 00373 v = btVector3(p[0], p[1], p[2]); 00374 v1 = t1 * v; 00375 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00376 00377 p = To + axis0 * (-extent[0]) + axis1 * extent[1] + axis2 * extent[2]; 00378 v = btVector3(p[0], p[1], p[2]); 00379 v1 = t1 * v; 00380 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00381 00382 p = To + axis0 * (-extent[0]) + axis1 * extent[1] + axis2 * (-extent[2]); 00383 v = btVector3(p[0], p[1], p[2]); 00384 v1 = t1 * v; 00385 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00386 00387 p = To + axis0 * (-extent[0]) + axis1 * (-extent[1]) + axis2 * extent[2]; 00388 v = btVector3(p[0], p[1], p[2]); 00389 v1 = t1 * v; 00390 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00391 00392 p = To + axis0 * (-extent[0]) + axis1 * (-extent[1]) + axis2 * (-extent[2]); 00393 v = btVector3(p[0], p[1], p[2]); 00394 v1 = t1 * v; 00395 aabb_ += Vec3f(v1.x(), v1.y(), v1.z()); 00396 } 00397 00398 aabb = aabb_; 00399 } 00400 00401 BVHModel<OBB> model; 00402 }; 00403 00404 00405 template<typename BV> 00406 inline CollisionMesh<BV>* makeMesh(const std::vector<Vec3f>& points, const std::vector<Triangle>& tri_indices) 00407 { 00408 CollisionMesh<BV>* m = new CollisionMesh<BV>; 00409 m->model.beginModel(); 00410 m->model.addSubModel(points, tri_indices); 00411 m->model.endModel(); 00412 m->computeAABB(); 00413 00414 return m; 00415 } 00416 00417 template<typename BV> 00418 inline CollisionMesh<BV>* makeBox(double a, double b, double c) 00419 { 00420 std::vector<Vec3f> points(8); 00421 std::vector<Triangle> tri_indices(12); 00422 points[0] = Vec3f(0.5 * a, -0.5 * b, 0.5 * c); 00423 points[1] = Vec3f(0.5 * a, 0.5 * b, 0.5 * c); 00424 points[2] = Vec3f(-0.5 * a, 0.5 * b, 0.5 * c); 00425 points[3] = Vec3f(-0.5 * a, -0.5 * b, 0.5 * c); 00426 points[4] = Vec3f(0.5 * a, -0.5 * b, -0.5 * c); 00427 points[5] = Vec3f(0.5 * a, 0.5 * b, -0.5 * c); 00428 points[6] = Vec3f(-0.5 * a, 0.5 * b, -0.5 * c); 00429 points[7] = Vec3f(-0.5 * a, -0.5 * b, -0.5 * c); 00430 00431 tri_indices[0] = Triangle(0, 4, 1); 00432 tri_indices[1] = Triangle(1, 4, 5); 00433 tri_indices[2] = Triangle(2, 5, 3); 00434 tri_indices[3] = Triangle(3, 6, 7); 00435 tri_indices[4] = Triangle(3, 0, 2); 00436 tri_indices[5] = Triangle(2, 0, 1); 00437 tri_indices[6] = Triangle(6, 5, 7); 00438 tri_indices[7] = Triangle(7, 5, 4); 00439 tri_indices[8] = Triangle(1, 5, 2); 00440 tri_indices[9] = Triangle(2, 5, 6); 00441 tri_indices[10] = Triangle(3, 7, 0); 00442 tri_indices[11] = Triangle(0, 7, 4); 00443 00444 00445 CollisionMesh<BV>* m = new CollisionMesh<BV>; 00446 m->model.beginModel(); 00447 m->model.addSubModel(points, tri_indices); 00448 m->model.endModel(); 00449 m->computeAABB(); 00450 00451 return m; 00452 } 00453 00454 template<typename BV> 00455 inline CollisionMesh<BV>* makeCylinder(double r, double h, unsigned int tot) 00456 { 00457 std::vector<Vec3f> points; 00458 std::vector<Triangle> tri_indices; 00459 00460 double phi, phid; 00461 const double pi = boost::math::constants::pi<double>(); 00462 phid = pi * 2 / tot; 00463 phi = 0; 00464 00465 double circle_edge = phid * r; 00466 //unsigned int h_num = ceil(h / circle_edge); 00467 unsigned int h_num = 1; 00468 double hd = h / h_num; 00469 00470 for(unsigned int i = 0; i < tot; ++i) 00471 points.push_back(Vec3f(r * cos(phi + phid * i), r * sin(phi + phid * i), h / 2)); 00472 00473 for(unsigned int i = 0; i < h_num - 1; ++i) 00474 { 00475 for(unsigned int j = 0; j < tot; ++j) 00476 { 00477 points.push_back(Vec3f(r * cos(phi + phid * j), r * sin(phi + phid * j), h / 2 - (i + 1) * hd)); 00478 } 00479 } 00480 00481 for(unsigned int i = 0; i < tot; ++i) 00482 points.push_back(Vec3f(r * cos(phi + phid * i), r * sin(phi + phid * i), - h / 2)); 00483 00484 points.push_back(Vec3f(0, 0, h / 2)); 00485 points.push_back(Vec3f(0, 0, -h / 2)); 00486 00487 for(unsigned int i = 0; i < tot; ++i) 00488 { 00489 Triangle tmp((h_num + 1) * tot, i, ((i == tot - 1) ? 0 : (i + 1))); 00490 tri_indices.push_back(tmp); 00491 } 00492 00493 for(unsigned int i = 0; i < tot; ++i) 00494 { 00495 Triangle tmp((h_num + 1) * tot + 1, h_num * tot + i, h_num * tot + ((i == tot - 1) ? 0 : (i + 1))); 00496 tri_indices.push_back(tmp); 00497 } 00498 00499 for(unsigned int i = 0; i < h_num; ++i) 00500 { 00501 for(unsigned int j = 0; j < tot; ++j) 00502 { 00503 int a, b, c, d; 00504 a = j; 00505 b = (j == tot - 1) ? 0 : (j + 1); 00506 c = j + tot; 00507 d = (j == tot - 1) ? tot : (j + 1 + tot); 00508 00509 int start = i * tot; 00510 tri_indices.push_back(Triangle(start + b, start + a, start + c)); 00511 tri_indices.push_back(Triangle(start + b, start + c, start + d)); 00512 } 00513 } 00514 00515 CollisionMesh<BV>* m = new CollisionMesh<BV>; 00516 m->model.beginModel(); 00517 m->model.addSubModel(points, tri_indices); 00518 m->model.endModel(); 00519 m->computeAABB(); 00520 00521 return m; 00522 } 00523 00524 template<typename BV> 00525 inline CollisionMesh<BV>* makeSphere(double r, unsigned int seg, unsigned int ring) 00526 { 00527 std::vector<Vec3f> points; 00528 std::vector<Triangle> tri_indices; 00529 00530 double phi, phid; 00531 const double pi = boost::math::constants::pi<double>(); 00532 phid = pi * 2 / seg; 00533 phi = 0; 00534 00535 double theta, thetad; 00536 thetad = pi / (ring + 1); 00537 theta = 0; 00538 00539 for(unsigned int i = 0; i < ring; ++i) 00540 { 00541 double theta_ = theta + thetad * (i + 1); 00542 for(unsigned int j = 0; j < seg; ++j) 00543 { 00544 points.push_back(Vec3f(r * sin(theta_) * cos(phi + j * phid), r * sin(theta_) * sin(phi + j * phid), r * cos(theta_))); 00545 } 00546 } 00547 points.push_back(Vec3f(0, 0, r)); 00548 points.push_back(Vec3f(0, 0, -r)); 00549 00550 for(unsigned int i = 0; i < ring - 1; ++i) 00551 { 00552 for(unsigned int j = 0; j < seg; ++j) 00553 { 00554 unsigned int a, b, c, d; 00555 a = i * seg + j; 00556 b = (j == seg - 1) ? (i * seg) : (i * seg + j + 1); 00557 c = (i + 1) * seg + j; 00558 d = (j == seg - 1) ? ((i + 1) * seg) : ((i + 1) * seg + j + 1); 00559 tri_indices.push_back(Triangle(a, c, b)); 00560 tri_indices.push_back(Triangle(b, c, d)); 00561 } 00562 } 00563 00564 for(unsigned int j = 0; j < seg; ++j) 00565 { 00566 unsigned int a, b; 00567 a = j; 00568 b = (j == seg - 1) ? 0 : (j + 1); 00569 tri_indices.push_back(Triangle(ring * seg, a, b)); 00570 00571 a = (ring - 1) * seg + j; 00572 b = (j == seg - 1) ? (ring - 1) * seg : ((ring - 1) * seg + j + 1); 00573 tri_indices.push_back(Triangle(a, ring * seg + 1, b)); 00574 } 00575 00576 CollisionMesh<BV>* m = new CollisionMesh<BV>; 00577 m->model.beginModel(); 00578 m->model.addSubModel(points, tri_indices); 00579 m->model.endModel(); 00580 m->computeAABB(); 00581 00582 return m; 00583 } 00584 00585 00586 00587 00588 } 00589 00590 #endif