Imported Upstream version 2.81
[platform/upstream/libbullet.git] / src / BulletCollision / Gimpact / btGImpactShape.h
1 /*! \file btGImpactShape.h
2 \author Francisco Le\7fn Nßjera
3 */
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
28 #include "BulletCollision/CollisionShapes/btCollisionShape.h"
29 #include "BulletCollision/CollisionShapes/btTriangleShape.h"
30 #include "BulletCollision/CollisionShapes/btStridingMeshInterface.h"
31 #include "BulletCollision/CollisionShapes/btCollisionMargin.h"
32 #include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
33 #include "BulletCollision/CollisionShapes/btConcaveShape.h"
34 #include "BulletCollision/CollisionShapes/btTetrahedronShape.h"
35 #include "LinearMath/btVector3.h"
36 #include "LinearMath/btTransform.h"
37 #include "LinearMath/btMatrix3x3.h"
38 #include "LinearMath/btAlignedObjectArray.h"
39
40 #include "btGImpactQuantizedBvh.h" // box tree class
41
42
43 //! declare Quantized trees, (you can change to float based trees)
44 typedef btGImpactQuantizedBvh btGImpactBoxSet;
45
46 enum eGIMPACT_SHAPE_TYPE
47 {
48         CONST_GIMPACT_COMPOUND_SHAPE = 0,
49         CONST_GIMPACT_TRIMESH_SHAPE_PART,
50         CONST_GIMPACT_TRIMESH_SHAPE
51 };
52
53
54 //! Helper class for tetrahedrons
55 class btTetrahedronShapeEx:public btBU_Simplex1to4
56 {
57 public:
58         btTetrahedronShapeEx()
59         {
60                 m_numVertices = 4;
61         }
62
63
64         SIMD_FORCE_INLINE void setVertices(
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;
72                 recalcLocalAabb();
73         }
74 };
75
76
77 //! Base class for gimpact shapes
78 class btGImpactShapeInterface : public btConcaveShape
79 {
80 protected:
81     btAABB m_localAABB;
82     bool m_needs_update;
83     btVector3  localScaling;
84     btGImpactBoxSet m_box_set;// optionally boxset
85
86         //! use this function for perfofm refit in bounding boxes
87     //! use this function for perfofm refit in bounding boxes
88     virtual void calcLocalAABB()
89     {
90                 lockChildShapes();
91         if(m_box_set.getNodeCount() == 0)
92         {
93                 m_box_set.buildSet();
94         }
95         else
96         {
97                 m_box_set.update();
98         }
99         unlockChildShapes();
100
101         m_localAABB = m_box_set.getGlobalBox();
102     }
103
104
105 public:
106         btGImpactShapeInterface()
107         {
108                 m_shapeType=GIMPACT_SHAPE_PROXYTYPE;
109                 m_localAABB.invalidate();
110                 m_needs_update = true;
111                 localScaling.setValue(1.f,1.f,1.f);
112         }
113
114
115         //! performs refit operation
116         /*!
117         Updates the entire Box set of this shape.
118         \pre postUpdate() must be called for attemps to calculating the box set, else this function
119                 will does nothing.
120         \post if m_needs_update == true, then it calls calcLocalAABB();
121         */
122     SIMD_FORCE_INLINE void updateBound()
123     {
124         if(!m_needs_update) return;
125         calcLocalAABB();
126         m_needs_update  = false;
127     }
128
129     //! If the Bounding box is not updated, then this class attemps to calculate it.
130     /*!
131     \post Calls updateBound() for update the box set.
132     */
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
141     //! Tells to this object that is needed to refit the box set
142     virtual void postUpdate()
143     {
144         m_needs_update = true;
145     }
146
147         //! Obtains the local box, which is the global calculated box of the total of subshapes
148         SIMD_FORCE_INLINE const btAABB & getLocalBox()
149         {
150                 return m_localAABB;
151         }
152
153
154     virtual int getShapeType() const
155     {
156         return GIMPACT_SHAPE_PROXYTYPE;
157     }
158
159     /*!
160         \post You must call updateBound() for update the box set.
161         */
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
188         //! Subshape member functions
189         //!@{
190
191         //! Base method for determinig which kind of GIMPACT shape we get
192         virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const = 0 ;
193
194         //! gets boxset
195         SIMD_FORCE_INLINE const btGImpactBoxSet * getBoxSet() const
196         {
197                 return &m_box_set;
198         }
199
200         //! Determines if this class has a hierarchy structure for sorting its primitives
201         SIMD_FORCE_INLINE bool hasBoxSet()  const
202         {
203                 if(m_box_set.getNodeCount() == 0) return false;
204                 return true;
205         }
206
207         //! Obtains the primitive manager
208         virtual const btPrimitiveManagerBase * getPrimitiveManager()  const = 0;
209
210
211         //! Gets the number of children
212         virtual int     getNumChildShapes() const  = 0;
213
214         //! if true, then its children must get transforms.
215         virtual bool childrenHasTransform() const = 0;
216
217         //! Determines if this shape has triangles
218         virtual bool needsRetrieveTriangles() const = 0;
219
220         //! Determines if this shape has tetrahedrons
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
229         //! call when reading child shapes
230         virtual void lockChildShapes() const
231         {
232         }
233
234         virtual void unlockChildShapes() const
235         {
236         }
237
238         //! if this trimesh
239         SIMD_FORCE_INLINE void getPrimitiveTriangle(int index,btPrimitiveTriangle & triangle) const
240         {
241                 getPrimitiveManager()->get_primitive_triangle(index,triangle);
242         }
243
244
245         //! Retrieves the bound from a child
246     /*!
247     */
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
257         //! Gets the children
258         virtual btCollisionShape* getChildShape(int index) = 0;
259
260
261         //! Gets the child
262         virtual const btCollisionShape* getChildShape(int index) const = 0;
263
264         //! Gets the children transform
265         virtual btTransform     getChildTransform(int index) const = 0;
266
267         //! Sets the children transform
268         /*!
269         \post You must call updateBound() for update the box set.
270         */
271         virtual void setChildTransform(int index, const btTransform & transform) = 0;
272
273         //!@}
274
275
276         //! virtual method for ray collision
277         virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback)  const
278         {
279         (void) rayFrom; (void) rayTo; (void) resultCallback;
280         }
281
282         //! Function for retrieve triangles.
283         /*!
284         It gives the triangles in local space
285         */
286         virtual void    processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
287         {
288         (void) callback; (void) aabbMin; (void) aabbMax;
289         }
290
291         //!@}
292
293 };
294
295
296 //! btGImpactCompoundShape allows to handle multiple btCollisionShape objects at once
297 /*!
298 This class only can manage Convex subshapes
299 */
300 class btGImpactCompoundShape    : public btGImpactShapeInterface
301 {
302 public:
303         //! compound primitive manager
304         class CompoundPrimitiveManager:public btPrimitiveManagerBase
305         {
306         public:
307                 virtual ~CompoundPrimitiveManager() {}
308                 btGImpactCompoundShape * m_compoundShape;
309
310
311                 CompoundPrimitiveManager(const CompoundPrimitiveManager& compound)
312             : btPrimitiveManagerBase()
313                 {
314                         m_compoundShape = compound.m_compoundShape;
315                 }
316
317                 CompoundPrimitiveManager(btGImpactCompoundShape * compoundShape)
318                 {
319                         m_compoundShape = compoundShape;
320                 }
321
322                 CompoundPrimitiveManager()
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;
340                         if(m_compoundShape->childrenHasTransform())
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:
363         CompoundPrimitiveManager m_primitive_manager;
364         btAlignedObjectArray<btTransform>               m_childTransforms;
365         btAlignedObjectArray<btCollisionShape*> m_childShapes;
366
367
368 public:
369
370         btGImpactCompoundShape(bool children_has_transform = true)
371         {
372         (void) children_has_transform;
373                 m_primitive_manager.m_compoundShape = this;
374                 m_box_set.setPrimitiveManager(&m_primitive_manager);
375         }
376
377         virtual ~btGImpactCompoundShape()
378         {
379         }
380
381
382         //! if true, then its children must get transforms.
383         virtual bool childrenHasTransform() const
384         {
385                 if(m_childTransforms.size()==0) return false;
386                 return true;
387         }
388
389
390         //! Obtains the primitive manager
391         virtual const btPrimitiveManagerBase * getPrimitiveManager()  const
392         {
393                 return &m_primitive_manager;
394         }
395
396         //! Obtains the compopund primitive manager
397         SIMD_FORCE_INLINE CompoundPrimitiveManager * getCompoundPrimitiveManager()
398         {
399                 return &m_primitive_manager;
400         }
401
402         //! Gets the number of children
403         virtual int     getNumChildShapes() const
404         {
405                 return m_childShapes.size();
406         }
407
408
409         //! Use this method for adding children. Only Convex shapes are allowed.
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
417         //! Use this method for adding children. Only Convex shapes are allowed.
418         void addChildShape(btCollisionShape* shape)
419         {
420                 btAssert(shape->isConvex());
421                 m_childShapes.push_back(shape);
422         }
423
424         //! Gets the children
425         virtual btCollisionShape* getChildShape(int index)
426         {
427                 return m_childShapes[index];
428         }
429
430         //! Gets the children
431         virtual const btCollisionShape* getChildShape(int index) const
432         {
433                 return m_childShapes[index];
434         }
435
436         //! Retrieves the bound from a child
437     /*!
438     */
439     virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
440     {
441
442         if(childrenHasTransform())
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
453         //! Gets the children transform
454         virtual btTransform     getChildTransform(int index) const
455         {
456                 btAssert(m_childTransforms.size() == m_childShapes.size());
457                 return m_childTransforms[index];
458         }
459
460         //! Sets the children transform
461         /*!
462         \post You must call updateBound() for update the box set.
463         */
464         virtual void setChildTransform(int index, const btTransform & transform)
465         {
466                 btAssert(m_childTransforms.size() == m_childShapes.size());
467                 m_childTransforms[index] = transform;
468                 postUpdate();
469         }
470
471         //! Determines if this shape has triangles
472         virtual bool needsRetrieveTriangles() const
473         {
474                 return false;
475         }
476
477         //! Determines if this shape has tetrahedrons
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
497         //! Calculates the exact inertia tensor for this shape
498         virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia) const;
499
500         virtual const char*     getName()const
501         {
502                 return "GImpactCompound";
503         }
504
505         virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const
506         {
507                 return CONST_GIMPACT_COMPOUND_SHAPE;
508         }
509
510 };
511
512
513
514 //! This class manages a sub part of a mesh supplied by the btStridingMeshInterface interface.
515 /*!
516 - Simply create this shape by passing the btStridingMeshInterface to the constructor btGImpactMeshShapePart, then you must call updateBound() after creating the mesh
517 - When making operations with this shape, you must call <b>lock</b> before accessing to the trimesh primitives, and then call <b>unlock</b>
518 - You can handle deformable meshes with this shape, by calling postUpdate() every time when changing the mesh vertices.
519
520 */
521 class btGImpactMeshShapePart : public btGImpactShapeInterface
522 {
523 public:
524         //! Trimesh primitive manager
525         /*!
526         Manages the info from btStridingMeshInterface object and controls the Lock/Unlock mechanism
527         */
528         class TrimeshPrimitiveManager:public btPrimitiveManagerBase
529         {
530         public:
531                 btScalar m_margin;
532                 btStridingMeshInterface * m_meshInterface;
533                 btVector3 m_scale;
534                 int m_part;
535                 int m_lock_count;
536                 const unsigned char *vertexbase;
537                 int numverts;
538                 PHY_ScalarType type;
539                 int stride;
540                 const unsigned char *indexbase;
541                 int indexstride;
542                 int  numfaces;
543                 PHY_ScalarType indicestype;
544
545                 TrimeshPrimitiveManager()
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
560                 TrimeshPrimitiveManager(const TrimeshPrimitiveManager & manager)
561             : btPrimitiveManagerBase()
562                 {
563                         m_meshInterface = manager.m_meshInterface;
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
577                 TrimeshPrimitiveManager(
578                         btStridingMeshInterface * meshInterface,        int part)
579                 {
580                         m_meshInterface = meshInterface;
581                         m_part = part;
582                         m_scale = m_meshInterface->getScaling();
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
594                 virtual ~TrimeshPrimitiveManager() {}
595
596                 void lock()
597                 {
598                         if(m_lock_count>0)
599                         {
600                                 m_lock_count++;
601                                 return;
602                         }
603                         m_meshInterface->getLockedReadOnlyVertexIndexBase(
604                                 &vertexbase,numverts,
605                                 type, stride,&indexbase, indexstride, numfaces,indicestype,m_part);
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                         }
618                         m_meshInterface->unLockReadOnlyVertexBase(m_part);
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
633                 SIMD_FORCE_INLINE int get_vertex_count() const
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);
678                         primbox.calc_from_triangle_margin(
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:
707         TrimeshPrimitiveManager m_primitive_manager;
708 public:
709
710         btGImpactMeshShapePart()
711         {
712                 m_box_set.setPrimitiveManager(&m_primitive_manager);
713         }
714
715
716         btGImpactMeshShapePart(btStridingMeshInterface * meshInterface, int part)
717         {
718                 m_primitive_manager.m_meshInterface = meshInterface;
719                 m_primitive_manager.m_part = part;
720                 m_box_set.setPrimitiveManager(&m_primitive_manager);
721         }
722
723         virtual ~btGImpactMeshShapePart()
724         {
725         }
726
727         //! if true, then its children must get transforms.
728         virtual bool childrenHasTransform() const
729         {
730                 return false;
731         }
732
733
734         //! call when reading child shapes
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
749         //! Gets the number of children
750         virtual int     getNumChildShapes() const
751         {
752                 return m_primitive_manager.get_primitive_count();
753         }
754
755
756         //! Gets the children
757         virtual btCollisionShape* getChildShape(int index)
758         {
759         (void) index;
760                 btAssert(0);
761                 return NULL;
762         }
763
764
765
766         //! Gets the child
767         virtual const btCollisionShape* getChildShape(int index) const
768         {
769         (void) index;
770                 btAssert(0);
771                 return NULL;
772         }
773
774         //! Gets the children transform
775         virtual btTransform     getChildTransform(int index) const
776         {
777         (void) index;
778                 btAssert(0);
779                 return btTransform();
780         }
781
782         //! Sets the children transform
783         /*!
784         \post You must call updateBound() for update the box set.
785         */
786         virtual void setChildTransform(int index, const btTransform & transform)
787         {
788         (void) index;
789         (void) transform;
790                 btAssert(0);
791         }
792
793
794         //! Obtains the primitive manager
795         virtual const btPrimitiveManagerBase * getPrimitiveManager()  const
796         {
797                 return &m_primitive_manager;
798         }
799
800         SIMD_FORCE_INLINE TrimeshPrimitiveManager * getTrimeshPrimitiveManager()
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
819         virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const
820         {
821                 return CONST_GIMPACT_TRIMESH_SHAPE_PART;
822         }
823
824         //! Determines if this shape has triangles
825         virtual bool needsRetrieveTriangles() const
826         {
827                 return true;
828         }
829
830         //! Determines if this shape has tetrahedrons
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
850         SIMD_FORCE_INLINE int getVertexCount() const
851         {
852                 return m_primitive_manager.get_vertex_count();
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
860         SIMD_FORCE_INLINE void setMargin(btScalar margin)
861     {
862         m_primitive_manager.m_margin = margin;
863         postUpdate();
864     }
865
866     SIMD_FORCE_INLINE btScalar getMargin() const
867     {
868         return m_primitive_manager.m_margin;
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     {
879         return m_primitive_manager.m_scale;
880     }
881
882     SIMD_FORCE_INLINE int getPart() const
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
891 //! This class manages a mesh supplied by the btStridingMeshInterface interface.
892 /*!
893 Set of btGImpactMeshShapePart parts
894 - Simply create this shape by passing the btStridingMeshInterface to the constructor btGImpactMeshShape, then you must call updateBound() after creating the mesh
895
896 - You can handle deformable meshes with this shape, by calling postUpdate() every time when changing the mesh vertices.
897
898 */
899 class btGImpactMeshShape : public btGImpactShapeInterface
900 {
901         btStridingMeshInterface* m_meshInterface;
902
903 protected:
904         btAlignedObjectArray<btGImpactMeshShapePart*> m_mesh_parts;
905         void buildMeshParts(btStridingMeshInterface * meshInterface)
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
914         //! use this function for perfofm refit in bounding boxes
915     virtual void calcLocalAABB()
916     {
917         m_localAABB.invalidate();
918         int i = m_mesh_parts.size();
919         while(i--)
920         {
921                 m_mesh_parts[i]->updateBound();
922                 m_localAABB.merge(m_mesh_parts[i]->getLocalBox());
923         }
924     }
925
926 public:
927         btGImpactMeshShape(btStridingMeshInterface * meshInterface)
928         {
929                 m_meshInterface = meshInterface;
930                 buildMeshParts(meshInterface);
931         }
932
933         virtual ~btGImpactMeshShape()
934         {
935                 int i = m_mesh_parts.size();
936         while(i--)
937         {
938                         btGImpactMeshShapePart * part = m_mesh_parts[i];
939                         delete part;
940         }
941                 m_mesh_parts.clear();
942         }
943
944
945         btStridingMeshInterface* getMeshInterface()
946         {
947                 return m_meshInterface;
948         }
949
950         const btStridingMeshInterface* getMeshInterface() const
951         {
952                 return m_meshInterface;
953         }
954
955         int getMeshPartCount() const
956         {
957                 return m_mesh_parts.size();
958         }
959
960         btGImpactMeshShapePart * getMeshPart(int index)
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         {
980                         btGImpactMeshShapePart * part = m_mesh_parts[i];
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         {
994                         btGImpactMeshShapePart * part = m_mesh_parts[i];
995                         part->setMargin(margin);
996         }
997
998                 m_needs_update = true;
999     }
1000
1001         //! Tells to this object that is needed to refit all the meshes
1002     virtual void postUpdate()
1003     {
1004                 int i = m_mesh_parts.size();
1005         while(i--)
1006         {
1007                         btGImpactMeshShapePart * part = m_mesh_parts[i];
1008                         part->postUpdate();
1009         }
1010
1011         m_needs_update = true;
1012     }
1013
1014         virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia) const;
1015
1016
1017         //! Obtains the primitive manager
1018         virtual const btPrimitiveManagerBase * getPrimitiveManager()  const
1019         {
1020                 btAssert(0);
1021                 return NULL;
1022         }
1023
1024
1025         //! Gets the number of children
1026         virtual int     getNumChildShapes() const
1027         {
1028                 btAssert(0);
1029                 return 0;
1030         }
1031
1032
1033         //! if true, then its children must get transforms.
1034         virtual bool childrenHasTransform() const
1035         {
1036                 btAssert(0);
1037                 return false;
1038         }
1039
1040         //! Determines if this shape has triangles
1041         virtual bool needsRetrieveTriangles() const
1042         {
1043                 btAssert(0);
1044                 return false;
1045         }
1046
1047         //! Determines if this shape has tetrahedrons
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
1066         //! call when reading child shapes
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
1080         //! Retrieves the bound from a child
1081     /*!
1082     */
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
1089         //! Gets the children
1090         virtual btCollisionShape* getChildShape(int index)
1091         {
1092         (void) index;
1093                 btAssert(0);
1094                 return NULL;
1095         }
1096
1097
1098         //! Gets the child
1099         virtual const btCollisionShape* getChildShape(int index) const
1100         {
1101         (void) index;
1102                 btAssert(0);
1103                 return NULL;
1104         }
1105
1106         //! Gets the children transform
1107         virtual btTransform     getChildTransform(int index) const
1108         {
1109         (void) index;
1110                 btAssert(0);
1111                 return btTransform();
1112         }
1113
1114         //! Sets the children transform
1115         /*!
1116         \post You must call updateBound() for update the box set.
1117         */
1118         virtual void setChildTransform(int index, const btTransform & transform)
1119         {
1120         (void) index; (void) transform;
1121                 btAssert(0);
1122         }
1123
1124
1125         virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const
1126         {
1127                 return CONST_GIMPACT_TRIMESH_SHAPE;
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
1138         //! Function for retrieve triangles.
1139         /*!
1140         It gives the triangles in local space
1141         */
1142         virtual void    processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
1143
1144         virtual int     calculateSerializeBufferSize() const;
1145
1146         ///fills the dataBuffer and returns the struct name (and 0 on failure)
1147         virtual const char*     serialize(void* dataBuffer, btSerializer* serializer) const;
1148
1149 };
1150
1151 ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
1152 struct  btGImpactMeshShapeData
1153 {
1154         btCollisionShapeData    m_collisionShapeData;
1155
1156         btStridingMeshInterfaceData m_meshInterface;
1157
1158         btVector3FloatData      m_localScaling;
1159
1160         float   m_collisionMargin;
1161
1162         int             m_gimpactSubType;
1163 };
1164
1165 SIMD_FORCE_INLINE       int     btGImpactMeshShape::calculateSerializeBufferSize() const
1166 {
1167         return sizeof(btGImpactMeshShapeData);
1168 }
1169
1170
1171 #endif //GIMPACT_MESH_SHAPE_H