Bullet Collision Detection & Physics Library
btGImpactShape.h
Go to the documentation of this file.
1 
4 /*
5 This source file is part of GIMPACT Library.
6 
7 For the latest info, see http://gimpact.sourceforge.net/
8 
9 Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
10 email: projectileman@yahoo.com
11 
12 
13 This software is provided 'as-is', without any express or implied warranty.
14 In no event will the authors be held liable for any damages arising from the use of this software.
15 Permission is granted to anyone to use this software for any purpose,
16 including commercial applications, and to alter it and redistribute it freely,
17 subject to the following restrictions:
18 
19 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
20 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
21 3. This notice may not be removed or altered from any source distribution.
22 */
23 
24 
25 #ifndef GIMPACT_SHAPE_H
26 #define GIMPACT_SHAPE_H
27 
35 #include "LinearMath/btVector3.h"
36 #include "LinearMath/btTransform.h"
37 #include "LinearMath/btMatrix3x3.h"
39 
40 #include "btGImpactQuantizedBvh.h" // box tree class
41 
42 
45 
47 {
51 };
52 
53 
56 {
57 public:
59  {
60  m_numVertices = 4;
61  }
62 
63 
65  const btVector3 & v0,const btVector3 & v1,
66  const btVector3 & v2,const btVector3 & v3)
67  {
68  m_vertices[0] = v0;
69  m_vertices[1] = v1;
70  m_vertices[2] = v2;
71  m_vertices[3] = v3;
73  }
74 };
75 
76 
79 {
80 protected:
84  btGImpactBoxSet m_box_set;// optionally boxset
85 
88  virtual void calcLocalAABB()
89  {
91  if(m_box_set.getNodeCount() == 0)
92  {
94  }
95  else
96  {
97  m_box_set.update();
98  }
100 
102  }
103 
104 
105 public:
107  {
110  m_needs_update = true;
111  localScaling.setValue(1.f,1.f,1.f);
112  }
113 
114 
116 
123  {
124  if(!m_needs_update) return;
125  calcLocalAABB();
126  m_needs_update = false;
127  }
128 
130 
133  void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
134  {
135  btAABB transformedbox = m_localAABB;
136  transformedbox.appy_transform(t);
137  aabbMin = transformedbox.m_min;
138  aabbMax = transformedbox.m_max;
139  }
140 
142  virtual void postUpdate()
143  {
144  m_needs_update = true;
145  }
146 
149  {
150  return m_localAABB;
151  }
152 
153 
154  virtual int getShapeType() const
155  {
157  }
158 
162  virtual void setLocalScaling(const btVector3& scaling)
163  {
164  localScaling = scaling;
165  postUpdate();
166  }
167 
168  virtual const btVector3& getLocalScaling() const
169  {
170  return localScaling;
171  }
172 
173 
174  virtual void setMargin(btScalar margin)
175  {
176  m_collisionMargin = margin;
177  int i = getNumChildShapes();
178  while(i--)
179  {
180  btCollisionShape* child = getChildShape(i);
181  child->setMargin(margin);
182  }
183 
184  m_needs_update = true;
185  }
186 
187 
190 
192  virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const = 0 ;
193 
196  {
197  return &m_box_set;
198  }
199 
202  {
203  if(m_box_set.getNodeCount() == 0) return false;
204  return true;
205  }
206 
208  virtual const btPrimitiveManagerBase * getPrimitiveManager() const = 0;
209 
210 
212  virtual int getNumChildShapes() const = 0;
213 
215  virtual bool childrenHasTransform() const = 0;
216 
218  virtual bool needsRetrieveTriangles() const = 0;
219 
221  virtual bool needsRetrieveTetrahedrons() const = 0;
222 
223  virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const = 0;
224 
225  virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const = 0;
226 
227 
228 
230  virtual void lockChildShapes() const
231  {
232  }
233 
234  virtual void unlockChildShapes() const
235  {
236  }
237 
240  {
241  getPrimitiveManager()->get_primitive_triangle(index,triangle);
242  }
243 
244 
246 
248  virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
249  {
250  btAABB child_aabb;
251  getPrimitiveManager()->get_primitive_box(child_index,child_aabb);
252  child_aabb.appy_transform(t);
253  aabbMin = child_aabb.m_min;
254  aabbMax = child_aabb.m_max;
255  }
256 
258  virtual btCollisionShape* getChildShape(int index) = 0;
259 
260 
262  virtual const btCollisionShape* getChildShape(int index) const = 0;
263 
265  virtual btTransform getChildTransform(int index) const = 0;
266 
268 
271  virtual void setChildTransform(int index, const btTransform & transform) = 0;
272 
274 
275 
277  virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const
278  {
279  (void) rayFrom; (void) rayTo; (void) resultCallback;
280  }
281 
283 
286  virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
287  {
288  (void) callback; (void) aabbMin; (void) aabbMax;
289  }
290 
292 
293 };
294 
295 
297 
301 {
302 public:
305  {
306  public:
309 
310 
313  {
314  m_compoundShape = compound.m_compoundShape;
315  }
316 
318  {
319  m_compoundShape = compoundShape;
320  }
321 
323  {
324  m_compoundShape = NULL;
325  }
326 
327  virtual bool is_trimesh() const
328  {
329  return false;
330  }
331 
332  virtual int get_primitive_count() const
333  {
334  return (int )m_compoundShape->getNumChildShapes();
335  }
336 
337  virtual void get_primitive_box(int prim_index ,btAABB & primbox) const
338  {
339  btTransform prim_trans;
341  {
342  prim_trans = m_compoundShape->getChildTransform(prim_index);
343  }
344  else
345  {
346  prim_trans.setIdentity();
347  }
348  const btCollisionShape* shape = m_compoundShape->getChildShape(prim_index);
349  shape->getAabb(prim_trans,primbox.m_min,primbox.m_max);
350  }
351 
352  virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const
353  {
354  btAssert(0);
355  (void) prim_index; (void) triangle;
356  }
357 
358  };
359 
360 
361 
362 protected:
366 
367 
368 public:
369 
370  btGImpactCompoundShape(bool children_has_transform = true)
371  {
372  (void) children_has_transform;
375  }
376 
378  {
379  }
380 
381 
383  virtual bool childrenHasTransform() const
384  {
385  if(m_childTransforms.size()==0) return false;
386  return true;
387  }
388 
389 
392  {
393  return &m_primitive_manager;
394  }
395 
398  {
399  return &m_primitive_manager;
400  }
401 
403  virtual int getNumChildShapes() const
404  {
405  return m_childShapes.size();
406  }
407 
408 
410  void addChildShape(const btTransform& localTransform,btCollisionShape* shape)
411  {
412  btAssert(shape->isConvex());
413  m_childTransforms.push_back(localTransform);
414  m_childShapes.push_back(shape);
415  }
416 
419  {
420  btAssert(shape->isConvex());
421  m_childShapes.push_back(shape);
422  }
423 
425  virtual btCollisionShape* getChildShape(int index)
426  {
427  return m_childShapes[index];
428  }
429 
431  virtual const btCollisionShape* getChildShape(int index) const
432  {
433  return m_childShapes[index];
434  }
435 
437 
439  virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
440  {
441 
443  {
444  m_childShapes[child_index]->getAabb(t*m_childTransforms[child_index],aabbMin,aabbMax);
445  }
446  else
447  {
448  m_childShapes[child_index]->getAabb(t,aabbMin,aabbMax);
449  }
450  }
451 
452 
454  virtual btTransform getChildTransform(int index) const
455  {
457  return m_childTransforms[index];
458  }
459 
461 
464  virtual void setChildTransform(int index, const btTransform & transform)
465  {
467  m_childTransforms[index] = transform;
468  postUpdate();
469  }
470 
472  virtual bool needsRetrieveTriangles() const
473  {
474  return false;
475  }
476 
478  virtual bool needsRetrieveTetrahedrons() const
479  {
480  return false;
481  }
482 
483 
484  virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const
485  {
486  (void) prim_index; (void) triangle;
487  btAssert(0);
488  }
489 
490  virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const
491  {
492  (void) prim_index; (void) tetrahedron;
493  btAssert(0);
494  }
495 
496 
498  virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
499 
500  virtual const char* getName()const
501  {
502  return "GImpactCompound";
503  }
504 
506  {
508  }
509 
510 };
511 
512 
513 
515 
522 {
523 public:
525 
529  {
530  public:
534  int m_part;
536  const unsigned char *vertexbase;
537  int numverts;
539  int stride;
540  const unsigned char *indexbase;
542  int numfaces;
544 
546  {
547  m_meshInterface = NULL;
548  m_part = 0;
549  m_margin = 0.01f;
550  m_scale = btVector3(1.f,1.f,1.f);
551  m_lock_count = 0;
552  vertexbase = 0;
553  numverts = 0;
554  stride = 0;
555  indexbase = 0;
556  indexstride = 0;
557  numfaces = 0;
558  }
559 
562  {
564  m_part = manager.m_part;
565  m_margin = manager.m_margin;
566  m_scale = manager.m_scale;
567  m_lock_count = 0;
568  vertexbase = 0;
569  numverts = 0;
570  stride = 0;
571  indexbase = 0;
572  indexstride = 0;
573  numfaces = 0;
574 
575  }
576 
578  btStridingMeshInterface * meshInterface, int part)
579  {
580  m_meshInterface = meshInterface;
581  m_part = part;
583  m_margin = 0.1f;
584  m_lock_count = 0;
585  vertexbase = 0;
586  numverts = 0;
587  stride = 0;
588  indexbase = 0;
589  indexstride = 0;
590  numfaces = 0;
591 
592  }
593 
595 
596  void lock()
597  {
598  if(m_lock_count>0)
599  {
600  m_lock_count++;
601  return;
602  }
606 
607  m_lock_count = 1;
608  }
609 
610  void unlock()
611  {
612  if(m_lock_count == 0) return;
613  if(m_lock_count>1)
614  {
615  --m_lock_count;
616  return;
617  }
619  vertexbase = NULL;
620  m_lock_count = 0;
621  }
622 
623  virtual bool is_trimesh() const
624  {
625  return true;
626  }
627 
628  virtual int get_primitive_count() const
629  {
630  return (int )numfaces;
631  }
632 
634  {
635  return (int )numverts;
636  }
637 
638  SIMD_FORCE_INLINE void get_indices(int face_index,int &i0,int &i1,int &i2) const
639  {
640  if(indicestype == PHY_SHORT)
641  {
642  unsigned short * s_indices = (unsigned short *)(indexbase + face_index*indexstride);
643  i0 = s_indices[0];
644  i1 = s_indices[1];
645  i2 = s_indices[2];
646  }
647  else
648  {
649  int * i_indices = (int *)(indexbase + face_index*indexstride);
650  i0 = i_indices[0];
651  i1 = i_indices[1];
652  i2 = i_indices[2];
653  }
654  }
655 
656  SIMD_FORCE_INLINE void get_vertex(int vertex_index, btVector3 & vertex) const
657  {
658  if(type == PHY_DOUBLE)
659  {
660  double * dvertices = (double *)(vertexbase + vertex_index*stride);
661  vertex[0] = btScalar(dvertices[0]*m_scale[0]);
662  vertex[1] = btScalar(dvertices[1]*m_scale[1]);
663  vertex[2] = btScalar(dvertices[2]*m_scale[2]);
664  }
665  else
666  {
667  float * svertices = (float *)(vertexbase + vertex_index*stride);
668  vertex[0] = svertices[0]*m_scale[0];
669  vertex[1] = svertices[1]*m_scale[1];
670  vertex[2] = svertices[2]*m_scale[2];
671  }
672  }
673 
674  virtual void get_primitive_box(int prim_index ,btAABB & primbox) const
675  {
676  btPrimitiveTriangle triangle;
677  get_primitive_triangle(prim_index,triangle);
679  triangle.m_vertices[0],
680  triangle.m_vertices[1],triangle.m_vertices[2],triangle.m_margin);
681  }
682 
683  virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const
684  {
685  int indices[3];
686  get_indices(prim_index,indices[0],indices[1],indices[2]);
687  get_vertex(indices[0],triangle.m_vertices[0]);
688  get_vertex(indices[1],triangle.m_vertices[1]);
689  get_vertex(indices[2],triangle.m_vertices[2]);
690  triangle.m_margin = m_margin;
691  }
692 
693  SIMD_FORCE_INLINE void get_bullet_triangle(int prim_index,btTriangleShapeEx & triangle) const
694  {
695  int indices[3];
696  get_indices(prim_index,indices[0],indices[1],indices[2]);
697  get_vertex(indices[0],triangle.m_vertices1[0]);
698  get_vertex(indices[1],triangle.m_vertices1[1]);
699  get_vertex(indices[2],triangle.m_vertices1[2]);
700  triangle.setMargin(m_margin);
701  }
702 
703  };
704 
705 
706 protected:
708 public:
709 
711  {
713  }
714 
715 
717  {
718  m_primitive_manager.m_meshInterface = meshInterface;
721  }
722 
724  {
725  }
726 
728  virtual bool childrenHasTransform() const
729  {
730  return false;
731  }
732 
733 
735  virtual void lockChildShapes() const
736  {
737  void * dummy = (void*)(m_box_set.getPrimitiveManager());
738  TrimeshPrimitiveManager * dummymanager = static_cast<TrimeshPrimitiveManager *>(dummy);
739  dummymanager->lock();
740  }
741 
742  virtual void unlockChildShapes() const
743  {
744  void * dummy = (void*)(m_box_set.getPrimitiveManager());
745  TrimeshPrimitiveManager * dummymanager = static_cast<TrimeshPrimitiveManager *>(dummy);
746  dummymanager->unlock();
747  }
748 
750  virtual int getNumChildShapes() const
751  {
753  }
754 
755 
757  virtual btCollisionShape* getChildShape(int index)
758  {
759  (void) index;
760  btAssert(0);
761  return NULL;
762  }
763 
764 
765 
767  virtual const btCollisionShape* getChildShape(int index) const
768  {
769  (void) index;
770  btAssert(0);
771  return NULL;
772  }
773 
775  virtual btTransform getChildTransform(int index) const
776  {
777  (void) index;
778  btAssert(0);
779  return btTransform();
780  }
781 
783 
786  virtual void setChildTransform(int index, const btTransform & transform)
787  {
788  (void) index;
789  (void) transform;
790  btAssert(0);
791  }
792 
793 
796  {
797  return &m_primitive_manager;
798  }
799 
801  {
802  return &m_primitive_manager;
803  }
804 
805 
806 
807 
808 
809  virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
810 
811 
812 
813 
814  virtual const char* getName()const
815  {
816  return "GImpactMeshShapePart";
817  }
818 
820  {
822  }
823 
825  virtual bool needsRetrieveTriangles() const
826  {
827  return true;
828  }
829 
831  virtual bool needsRetrieveTetrahedrons() const
832  {
833  return false;
834  }
835 
836  virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const
837  {
838  m_primitive_manager.get_bullet_triangle(prim_index,triangle);
839  }
840 
841  virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const
842  {
843  (void) prim_index;
844  (void) tetrahedron;
845  btAssert(0);
846  }
847 
848 
849 
851  {
853  }
854 
855  SIMD_FORCE_INLINE void getVertex(int vertex_index, btVector3 & vertex) const
856  {
857  m_primitive_manager.get_vertex(vertex_index,vertex);
858  }
859 
861  {
862  m_primitive_manager.m_margin = margin;
863  postUpdate();
864  }
865 
867  {
869  }
870 
871  virtual void setLocalScaling(const btVector3& scaling)
872  {
873  m_primitive_manager.m_scale = scaling;
874  postUpdate();
875  }
876 
877  virtual const btVector3& getLocalScaling() const
878  {
880  }
881 
883  {
884  return (int)m_primitive_manager.m_part;
885  }
886 
887  virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
888 };
889 
890 
892 
900 {
902 
903 protected:
906  {
907  for (int i=0;i<meshInterface->getNumSubParts() ;++i )
908  {
909  btGImpactMeshShapePart * newpart = new btGImpactMeshShapePart(meshInterface,i);
910  m_mesh_parts.push_back(newpart);
911  }
912  }
913 
915  virtual void calcLocalAABB()
916  {
918  int i = m_mesh_parts.size();
919  while(i--)
920  {
921  m_mesh_parts[i]->updateBound();
923  }
924  }
925 
926 public:
928  {
929  m_meshInterface = meshInterface;
930  buildMeshParts(meshInterface);
931  }
932 
934  {
935  int i = m_mesh_parts.size();
936  while(i--)
937  {
939  delete part;
940  }
942  }
943 
944 
946  {
947  return m_meshInterface;
948  }
949 
951  {
952  return m_meshInterface;
953  }
954 
955  int getMeshPartCount() const
956  {
957  return m_mesh_parts.size();
958  }
959 
961  {
962  return m_mesh_parts[index];
963  }
964 
965 
966 
967  const btGImpactMeshShapePart * getMeshPart(int index) const
968  {
969  return m_mesh_parts[index];
970  }
971 
972 
973  virtual void setLocalScaling(const btVector3& scaling)
974  {
975  localScaling = scaling;
976 
977  int i = m_mesh_parts.size();
978  while(i--)
979  {
981  part->setLocalScaling(scaling);
982  }
983 
984  m_needs_update = true;
985  }
986 
987  virtual void setMargin(btScalar margin)
988  {
989  m_collisionMargin = margin;
990 
991  int i = m_mesh_parts.size();
992  while(i--)
993  {
995  part->setMargin(margin);
996  }
997 
998  m_needs_update = true;
999  }
1000 
1002  virtual void postUpdate()
1003  {
1004  int i = m_mesh_parts.size();
1005  while(i--)
1006  {
1008  part->postUpdate();
1009  }
1010 
1011  m_needs_update = true;
1012  }
1013 
1014  virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const;
1015 
1016 
1019  {
1020  btAssert(0);
1021  return NULL;
1022  }
1023 
1024 
1026  virtual int getNumChildShapes() const
1027  {
1028  btAssert(0);
1029  return 0;
1030  }
1031 
1032 
1034  virtual bool childrenHasTransform() const
1035  {
1036  btAssert(0);
1037  return false;
1038  }
1039 
1041  virtual bool needsRetrieveTriangles() const
1042  {
1043  btAssert(0);
1044  return false;
1045  }
1046 
1048  virtual bool needsRetrieveTetrahedrons() const
1049  {
1050  btAssert(0);
1051  return false;
1052  }
1053 
1054  virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const
1055  {
1056  (void) prim_index; (void) triangle;
1057  btAssert(0);
1058  }
1059 
1060  virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const
1061  {
1062  (void) prim_index; (void) tetrahedron;
1063  btAssert(0);
1064  }
1065 
1067  virtual void lockChildShapes() const
1068  {
1069  btAssert(0);
1070  }
1071 
1072  virtual void unlockChildShapes() const
1073  {
1074  btAssert(0);
1075  }
1076 
1077 
1078 
1079 
1081 
1083  virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
1084  {
1085  (void) child_index; (void) t; (void) aabbMin; (void) aabbMax;
1086  btAssert(0);
1087  }
1088 
1090  virtual btCollisionShape* getChildShape(int index)
1091  {
1092  (void) index;
1093  btAssert(0);
1094  return NULL;
1095  }
1096 
1097 
1099  virtual const btCollisionShape* getChildShape(int index) const
1100  {
1101  (void) index;
1102  btAssert(0);
1103  return NULL;
1104  }
1105 
1107  virtual btTransform getChildTransform(int index) const
1108  {
1109  (void) index;
1110  btAssert(0);
1111  return btTransform();
1112  }
1113 
1115 
1118  virtual void setChildTransform(int index, const btTransform & transform)
1119  {
1120  (void) index; (void) transform;
1121  btAssert(0);
1122  }
1123 
1124 
1126  {
1128  }
1129 
1130 
1131  virtual const char* getName()const
1132  {
1133  return "GImpactMesh";
1134  }
1135 
1136  virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const;
1137 
1139 
1142  virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
1143 
1144  virtual int calculateSerializeBufferSize() const;
1145 
1147  virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
1148 
1149 };
1150 
1153 {
1155 
1157 
1159 
1161 
1163 };
1164 
1166 {
1167  return sizeof(btGImpactMeshShapeData);
1168 }
1169 
1170 
1171 #endif //GIMPACT_MESH_SHAPE_H