[dali_2.3.21] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-physics / third-party / bullet3 / 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 #ifndef GIMPACT_SHAPE_H
25 #define GIMPACT_SHAPE_H
26
27 #include "BulletCollision/CollisionShapes/btCollisionShape.h"
28 #include "BulletCollision/CollisionShapes/btTriangleShape.h"
29 #include "BulletCollision/CollisionShapes/btStridingMeshInterface.h"
30 #include "BulletCollision/CollisionShapes/btCollisionMargin.h"
31 #include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
32 #include "BulletCollision/CollisionShapes/btConcaveShape.h"
33 #include "BulletCollision/CollisionShapes/btTetrahedronShape.h"
34 #include "LinearMath/btVector3.h"
35 #include "LinearMath/btTransform.h"
36 #include "LinearMath/btMatrix3x3.h"
37 #include "LinearMath/btAlignedObjectArray.h"
38
39 #include "btGImpactQuantizedBvh.h"  // box tree class
40
41 //! declare Quantized trees, (you can change to float based trees)
42 typedef btGImpactQuantizedBvh btGImpactBoxSet;
43
44 enum eGIMPACT_SHAPE_TYPE
45 {
46         CONST_GIMPACT_COMPOUND_SHAPE = 0,
47         CONST_GIMPACT_TRIMESH_SHAPE_PART,
48         CONST_GIMPACT_TRIMESH_SHAPE
49 };
50
51 //! Helper class for tetrahedrons
52 class btTetrahedronShapeEx : public btBU_Simplex1to4
53 {
54 public:
55         btTetrahedronShapeEx()
56         {
57                 m_numVertices = 4;
58         }
59
60         SIMD_FORCE_INLINE void setVertices(
61                 const btVector3& v0, const btVector3& v1,
62                 const btVector3& v2, const btVector3& v3)
63         {
64                 m_vertices[0] = v0;
65                 m_vertices[1] = v1;
66                 m_vertices[2] = v2;
67                 m_vertices[3] = v3;
68                 recalcLocalAabb();
69         }
70 };
71
72 //! Base class for gimpact shapes
73 class btGImpactShapeInterface : public btConcaveShape
74 {
75 protected:
76         btAABB m_localAABB;
77         bool m_needs_update;
78         btVector3 localScaling;
79         btGImpactBoxSet m_box_set;  // optionally boxset
80
81         //! use this function for perfofm refit in bounding boxes
82         //! use this function for perfofm refit in bounding boxes
83         virtual void calcLocalAABB()
84         {
85                 lockChildShapes();
86                 if (m_box_set.getNodeCount() == 0)
87                 {
88                         m_box_set.buildSet();
89                 }
90                 else
91                 {
92                         m_box_set.update();
93                 }
94                 unlockChildShapes();
95
96                 m_localAABB = m_box_set.getGlobalBox();
97         }
98
99 public:
100         btGImpactShapeInterface()
101         {
102                 m_shapeType = GIMPACT_SHAPE_PROXYTYPE;
103                 m_localAABB.invalidate();
104                 m_needs_update = true;
105                 localScaling.setValue(1.f, 1.f, 1.f);
106         }
107
108         //! performs refit operation
109         /*!
110         Updates the entire Box set of this shape.
111         \pre postUpdate() must be called for attemps to calculating the box set, else this function
112                 will does nothing.
113         \post if m_needs_update == true, then it calls calcLocalAABB();
114         */
115         SIMD_FORCE_INLINE void updateBound()
116         {
117                 if (!m_needs_update) return;
118                 calcLocalAABB();
119                 m_needs_update = false;
120         }
121
122         //! If the Bounding box is not updated, then this class attemps to calculate it.
123         /*!
124     \post Calls updateBound() for update the box set.
125     */
126         void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
127         {
128                 btAABB transformedbox = m_localAABB;
129                 transformedbox.appy_transform(t);
130                 aabbMin = transformedbox.m_min;
131                 aabbMax = transformedbox.m_max;
132         }
133
134         //! Tells to this object that is needed to refit the box set
135         virtual void postUpdate()
136         {
137                 m_needs_update = true;
138         }
139
140         //! Obtains the local box, which is the global calculated box of the total of subshapes
141         SIMD_FORCE_INLINE const btAABB& getLocalBox()
142         {
143                 return m_localAABB;
144         }
145
146         virtual int getShapeType() const
147         {
148                 return GIMPACT_SHAPE_PROXYTYPE;
149         }
150
151         /*!
152         \post You must call updateBound() for update the box set.
153         */
154         virtual void setLocalScaling(const btVector3& scaling)
155         {
156                 localScaling = scaling;
157                 postUpdate();
158         }
159
160         virtual const btVector3& getLocalScaling() const
161         {
162                 return localScaling;
163         }
164
165         virtual void setMargin(btScalar margin)
166         {
167                 m_collisionMargin = margin;
168                 int i = getNumChildShapes();
169                 while (i--)
170                 {
171                         btCollisionShape* child = getChildShape(i);
172                         child->setMargin(margin);
173                 }
174
175                 m_needs_update = true;
176         }
177
178         //! Subshape member functions
179         //!@{
180
181         //! Base method for determinig which kind of GIMPACT shape we get
182         virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const = 0;
183
184         //! gets boxset
185         SIMD_FORCE_INLINE const btGImpactBoxSet* getBoxSet() const
186         {
187                 return &m_box_set;
188         }
189
190         //! Determines if this class has a hierarchy structure for sorting its primitives
191         SIMD_FORCE_INLINE bool hasBoxSet() const
192         {
193                 if (m_box_set.getNodeCount() == 0) return false;
194                 return true;
195         }
196
197         //! Obtains the primitive manager
198         virtual const btPrimitiveManagerBase* getPrimitiveManager() const = 0;
199
200         //! Gets the number of children
201         virtual int getNumChildShapes() const = 0;
202
203         //! if true, then its children must get transforms.
204         virtual bool childrenHasTransform() const = 0;
205
206         //! Determines if this shape has triangles
207         virtual bool needsRetrieveTriangles() const = 0;
208
209         //! Determines if this shape has tetrahedrons
210         virtual bool needsRetrieveTetrahedrons() const = 0;
211
212         virtual void getBulletTriangle(int prim_index, btTriangleShapeEx& triangle) const = 0;
213
214         virtual void getBulletTetrahedron(int prim_index, btTetrahedronShapeEx& tetrahedron) const = 0;
215
216         //! call when reading child shapes
217         virtual void lockChildShapes() const
218         {
219         }
220
221         virtual void unlockChildShapes() const
222         {
223         }
224
225         //! if this trimesh
226         SIMD_FORCE_INLINE void getPrimitiveTriangle(int index, btPrimitiveTriangle& triangle) const
227         {
228                 getPrimitiveManager()->get_primitive_triangle(index, triangle);
229         }
230
231         //! Retrieves the bound from a child
232         /*!
233     */
234         virtual void getChildAabb(int child_index, const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
235         {
236                 btAABB child_aabb;
237                 getPrimitiveManager()->get_primitive_box(child_index, child_aabb);
238                 child_aabb.appy_transform(t);
239                 aabbMin = child_aabb.m_min;
240                 aabbMax = child_aabb.m_max;
241         }
242
243         //! Gets the children
244         virtual btCollisionShape* getChildShape(int index) = 0;
245
246         //! Gets the child
247         virtual const btCollisionShape* getChildShape(int index) const = 0;
248
249         //! Gets the children transform
250         virtual btTransform getChildTransform(int index) const = 0;
251
252         //! Sets the children transform
253         /*!
254         \post You must call updateBound() for update the box set.
255         */
256         virtual void setChildTransform(int index, const btTransform& transform) = 0;
257
258         //!@}
259
260         //! virtual method for ray collision
261         virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const
262         {
263                 (void)rayFrom;
264                 (void)rayTo;
265                 (void)resultCallback;
266         }
267
268         //! Function for retrieve triangles.
269         /*!
270         It gives the triangles in local space
271         */
272         virtual void processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const
273         {
274                 (void)callback;
275                 (void)aabbMin;
276                 (void)aabbMax;
277         }
278
279         //! Function for retrieve triangles.
280         /*!
281         It gives the triangles in local space
282         */
283         virtual void processAllTrianglesRay(btTriangleCallback* /*callback*/, const btVector3& /*rayFrom*/, const btVector3& /*rayTo*/) const
284         {
285         }
286
287         //!@}
288 };
289
290 //! btGImpactCompoundShape allows to handle multiple btCollisionShape objects at once
291 /*!
292 This class only can manage Convex subshapes
293 */
294 class btGImpactCompoundShape : public btGImpactShapeInterface
295 {
296 public:
297         //! compound primitive manager
298         class CompoundPrimitiveManager : public btPrimitiveManagerBase
299         {
300         public:
301                 virtual ~CompoundPrimitiveManager() {}
302                 btGImpactCompoundShape* m_compoundShape;
303
304                 CompoundPrimitiveManager(const CompoundPrimitiveManager& compound)
305                         : btPrimitiveManagerBase()
306                 {
307                         m_compoundShape = compound.m_compoundShape;
308                 }
309
310                 CompoundPrimitiveManager(btGImpactCompoundShape* compoundShape)
311                 {
312                         m_compoundShape = compoundShape;
313                 }
314
315                 CompoundPrimitiveManager()
316                 {
317                         m_compoundShape = NULL;
318                 }
319
320                 virtual bool is_trimesh() const
321                 {
322                         return false;
323                 }
324
325                 virtual int get_primitive_count() const
326                 {
327                         return (int)m_compoundShape->getNumChildShapes();
328                 }
329
330                 virtual void get_primitive_box(int prim_index, btAABB& primbox) const
331                 {
332                         btTransform prim_trans;
333                         if (m_compoundShape->childrenHasTransform())
334                         {
335                                 prim_trans = m_compoundShape->getChildTransform(prim_index);
336                         }
337                         else
338                         {
339                                 prim_trans.setIdentity();
340                         }
341                         const btCollisionShape* shape = m_compoundShape->getChildShape(prim_index);
342                         shape->getAabb(prim_trans, primbox.m_min, primbox.m_max);
343                 }
344
345                 virtual void get_primitive_triangle(int prim_index, btPrimitiveTriangle& triangle) const
346                 {
347                         btAssert(0);
348                         (void)prim_index;
349                         (void)triangle;
350                 }
351         };
352
353 protected:
354         CompoundPrimitiveManager m_primitive_manager;
355         btAlignedObjectArray<btTransform> m_childTransforms;
356         btAlignedObjectArray<btCollisionShape*> m_childShapes;
357
358 public:
359         btGImpactCompoundShape(bool children_has_transform = true)
360         {
361                 (void)children_has_transform;
362                 m_primitive_manager.m_compoundShape = this;
363                 m_box_set.setPrimitiveManager(&m_primitive_manager);
364         }
365
366         virtual ~btGImpactCompoundShape()
367         {
368         }
369
370         //! if true, then its children must get transforms.
371         virtual bool childrenHasTransform() const
372         {
373                 if (m_childTransforms.size() == 0) return false;
374                 return true;
375         }
376
377         //! Obtains the primitive manager
378         virtual const btPrimitiveManagerBase* getPrimitiveManager() const
379         {
380                 return &m_primitive_manager;
381         }
382
383         //! Obtains the compopund primitive manager
384         SIMD_FORCE_INLINE CompoundPrimitiveManager* getCompoundPrimitiveManager()
385         {
386                 return &m_primitive_manager;
387         }
388
389         //! Gets the number of children
390         virtual int getNumChildShapes() const
391         {
392                 return m_childShapes.size();
393         }
394
395         //! Use this method for adding children. Only Convex shapes are allowed.
396         void addChildShape(const btTransform& localTransform, btCollisionShape* shape)
397         {
398                 btAssert(shape->isConvex());
399                 m_childTransforms.push_back(localTransform);
400                 m_childShapes.push_back(shape);
401         }
402
403         //! Use this method for adding children. Only Convex shapes are allowed.
404         void addChildShape(btCollisionShape* shape)
405         {
406                 btAssert(shape->isConvex());
407                 m_childShapes.push_back(shape);
408         }
409
410         //! Gets the children
411         virtual btCollisionShape* getChildShape(int index)
412         {
413                 return m_childShapes[index];
414         }
415
416         //! Gets the children
417         virtual const btCollisionShape* getChildShape(int index) const
418         {
419                 return m_childShapes[index];
420         }
421
422         //! Retrieves the bound from a child
423         /*!
424     */
425         virtual void getChildAabb(int child_index, const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
426         {
427                 if (childrenHasTransform())
428                 {
429                         m_childShapes[child_index]->getAabb(t * m_childTransforms[child_index], aabbMin, aabbMax);
430                 }
431                 else
432                 {
433                         m_childShapes[child_index]->getAabb(t, aabbMin, aabbMax);
434                 }
435         }
436
437         //! Gets the children transform
438         virtual btTransform getChildTransform(int index) const
439         {
440                 btAssert(m_childTransforms.size() == m_childShapes.size());
441                 return m_childTransforms[index];
442         }
443
444         //! Sets the children transform
445         /*!
446         \post You must call updateBound() for update the box set.
447         */
448         virtual void setChildTransform(int index, const btTransform& transform)
449         {
450                 btAssert(m_childTransforms.size() == m_childShapes.size());
451                 m_childTransforms[index] = transform;
452                 postUpdate();
453         }
454
455         //! Determines if this shape has triangles
456         virtual bool needsRetrieveTriangles() const
457         {
458                 return false;
459         }
460
461         //! Determines if this shape has tetrahedrons
462         virtual bool needsRetrieveTetrahedrons() const
463         {
464                 return false;
465         }
466
467         virtual void getBulletTriangle(int prim_index, btTriangleShapeEx& triangle) const
468         {
469                 (void)prim_index;
470                 (void)triangle;
471                 btAssert(0);
472         }
473
474         virtual void getBulletTetrahedron(int prim_index, btTetrahedronShapeEx& tetrahedron) const
475         {
476                 (void)prim_index;
477                 (void)tetrahedron;
478                 btAssert(0);
479         }
480
481         //! Calculates the exact inertia tensor for this shape
482         virtual void calculateLocalInertia(btScalar mass, btVector3& inertia) const;
483
484         virtual const char* getName() const
485         {
486                 return "GImpactCompound";
487         }
488
489         virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const
490         {
491                 return CONST_GIMPACT_COMPOUND_SHAPE;
492         }
493 };
494
495 //! This class manages a sub part of a mesh supplied by the btStridingMeshInterface interface.
496 /*!
497 - Simply create this shape by passing the btStridingMeshInterface to the constructor btGImpactMeshShapePart, then you must call updateBound() after creating the mesh
498 - When making operations with this shape, you must call <b>lock</b> before accessing to the trimesh primitives, and then call <b>unlock</b>
499 - You can handle deformable meshes with this shape, by calling postUpdate() every time when changing the mesh vertices.
500
501 */
502 class btGImpactMeshShapePart : public btGImpactShapeInterface
503 {
504 public:
505         //! Trimesh primitive manager
506         /*!
507         Manages the info from btStridingMeshInterface object and controls the Lock/Unlock mechanism
508         */
509         class TrimeshPrimitiveManager : public btPrimitiveManagerBase
510         {
511         public:
512                 btScalar m_margin;
513                 btStridingMeshInterface* m_meshInterface;
514                 btVector3 m_scale;
515                 int m_part;
516                 int m_lock_count;
517                 const unsigned char* vertexbase;
518                 int numverts;
519                 PHY_ScalarType type;
520                 int stride;
521                 const unsigned char* indexbase;
522                 int indexstride;
523                 int numfaces;
524                 PHY_ScalarType indicestype;
525
526                 TrimeshPrimitiveManager()
527                 {
528                         m_meshInterface = NULL;
529                         m_part = 0;
530                         m_margin = 0.01f;
531                         m_scale = btVector3(1.f, 1.f, 1.f);
532                         m_lock_count = 0;
533                         vertexbase = 0;
534                         numverts = 0;
535                         stride = 0;
536                         indexbase = 0;
537                         indexstride = 0;
538                         numfaces = 0;
539                 }
540
541                 TrimeshPrimitiveManager(const TrimeshPrimitiveManager& manager)
542                         : btPrimitiveManagerBase()
543                 {
544                         m_meshInterface = manager.m_meshInterface;
545                         m_part = manager.m_part;
546                         m_margin = manager.m_margin;
547                         m_scale = manager.m_scale;
548                         m_lock_count = 0;
549                         vertexbase = 0;
550                         numverts = 0;
551                         stride = 0;
552                         indexbase = 0;
553                         indexstride = 0;
554                         numfaces = 0;
555                 }
556
557                 TrimeshPrimitiveManager(
558                         btStridingMeshInterface* meshInterface, int part)
559                 {
560                         m_meshInterface = meshInterface;
561                         m_part = part;
562                         m_scale = m_meshInterface->getScaling();
563                         m_margin = 0.1f;
564                         m_lock_count = 0;
565                         vertexbase = 0;
566                         numverts = 0;
567                         stride = 0;
568                         indexbase = 0;
569                         indexstride = 0;
570                         numfaces = 0;
571                 }
572
573                 virtual ~TrimeshPrimitiveManager() {}
574
575                 void lock()
576                 {
577                         if (m_lock_count > 0)
578                         {
579                                 m_lock_count++;
580                                 return;
581                         }
582                         m_meshInterface->getLockedReadOnlyVertexIndexBase(
583                                 &vertexbase, numverts,
584                                 type, stride, &indexbase, indexstride, numfaces, indicestype, m_part);
585
586                         m_lock_count = 1;
587                 }
588
589                 void unlock()
590                 {
591                         if (m_lock_count == 0) return;
592                         if (m_lock_count > 1)
593                         {
594                                 --m_lock_count;
595                                 return;
596                         }
597                         m_meshInterface->unLockReadOnlyVertexBase(m_part);
598                         vertexbase = NULL;
599                         m_lock_count = 0;
600                 }
601
602                 virtual bool is_trimesh() const
603                 {
604                         return true;
605                 }
606
607                 virtual int get_primitive_count() const
608                 {
609                         return (int)numfaces;
610                 }
611
612                 SIMD_FORCE_INLINE int get_vertex_count() const
613                 {
614                         return (int)numverts;
615                 }
616
617                 SIMD_FORCE_INLINE void get_indices(int face_index, unsigned int& i0, unsigned int& i1, unsigned int& i2) const
618                 {
619                         if (indicestype == PHY_SHORT)
620                         {
621                                 unsigned short* s_indices = (unsigned short*)(indexbase + face_index * indexstride);
622                                 i0 = s_indices[0];
623                                 i1 = s_indices[1];
624                                 i2 = s_indices[2];
625                         }
626                         else if (indicestype == PHY_INTEGER)
627                         {
628                                 unsigned int* i_indices = (unsigned int*)(indexbase + face_index * indexstride);
629                                 i0 = i_indices[0];
630                                 i1 = i_indices[1];
631                                 i2 = i_indices[2];
632                         }
633                         else
634                         {
635                                 btAssert(indicestype == PHY_UCHAR);
636                                 unsigned char* i_indices = (unsigned char*)(indexbase + face_index * indexstride);
637                                 i0 = i_indices[0];
638                                 i1 = i_indices[1];
639                                 i2 = i_indices[2];
640                         }
641                 }
642
643                 SIMD_FORCE_INLINE void get_vertex(unsigned int vertex_index, btVector3& vertex) const
644                 {
645                         if (type == PHY_DOUBLE)
646                         {
647                                 double* dvertices = (double*)(vertexbase + vertex_index * stride);
648                                 vertex[0] = btScalar(dvertices[0] * m_scale[0]);
649                                 vertex[1] = btScalar(dvertices[1] * m_scale[1]);
650                                 vertex[2] = btScalar(dvertices[2] * m_scale[2]);
651                         }
652                         else
653                         {
654                                 float* svertices = (float*)(vertexbase + vertex_index * stride);
655                                 vertex[0] = svertices[0] * m_scale[0];
656                                 vertex[1] = svertices[1] * m_scale[1];
657                                 vertex[2] = svertices[2] * m_scale[2];
658                         }
659                 }
660
661                 virtual void get_primitive_box(int prim_index, btAABB& primbox) const
662                 {
663                         btPrimitiveTriangle triangle;
664                         get_primitive_triangle(prim_index, triangle);
665                         primbox.calc_from_triangle_margin(
666                                 triangle.m_vertices[0],
667                                 triangle.m_vertices[1], triangle.m_vertices[2], triangle.m_margin);
668                 }
669
670                 virtual void get_primitive_triangle(int prim_index, btPrimitiveTriangle& triangle) const
671                 {
672                         unsigned int indices[3];
673                         get_indices(prim_index, indices[0], indices[1], indices[2]);
674                         get_vertex(indices[0], triangle.m_vertices[0]);
675                         get_vertex(indices[1], triangle.m_vertices[1]);
676                         get_vertex(indices[2], triangle.m_vertices[2]);
677                         triangle.m_margin = m_margin;
678                 }
679
680                 SIMD_FORCE_INLINE void get_bullet_triangle(int prim_index, btTriangleShapeEx& triangle) const
681                 {
682                         unsigned int indices[3];
683                         get_indices(prim_index, indices[0], indices[1], indices[2]);
684                         get_vertex(indices[0], triangle.m_vertices1[0]);
685                         get_vertex(indices[1], triangle.m_vertices1[1]);
686                         get_vertex(indices[2], triangle.m_vertices1[2]);
687                         triangle.setMargin(m_margin);
688                 }
689         };
690
691 protected:
692         TrimeshPrimitiveManager m_primitive_manager;
693
694 public:
695         btGImpactMeshShapePart()
696         {
697                 m_box_set.setPrimitiveManager(&m_primitive_manager);
698         }
699
700         btGImpactMeshShapePart(btStridingMeshInterface* meshInterface, int part);
701         virtual ~btGImpactMeshShapePart();
702
703         //! if true, then its children must get transforms.
704         virtual bool childrenHasTransform() const
705         {
706                 return false;
707         }
708
709         //! call when reading child shapes
710         virtual void lockChildShapes() const;
711         virtual void unlockChildShapes() const;
712
713         //! Gets the number of children
714         virtual int getNumChildShapes() const
715         {
716                 return m_primitive_manager.get_primitive_count();
717         }
718
719         //! Gets the children
720         virtual btCollisionShape* getChildShape(int index)
721         {
722                 (void)index;
723                 btAssert(0);
724                 return NULL;
725         }
726
727         //! Gets the child
728         virtual const btCollisionShape* getChildShape(int index) const
729         {
730                 (void)index;
731                 btAssert(0);
732                 return NULL;
733         }
734
735         //! Gets the children transform
736         virtual btTransform getChildTransform(int index) const
737         {
738                 (void)index;
739                 btAssert(0);
740                 return btTransform();
741         }
742
743         //! Sets the children transform
744         /*!
745         \post You must call updateBound() for update the box set.
746         */
747         virtual void setChildTransform(int index, const btTransform& transform)
748         {
749                 (void)index;
750                 (void)transform;
751                 btAssert(0);
752         }
753
754         //! Obtains the primitive manager
755         virtual const btPrimitiveManagerBase* getPrimitiveManager() const
756         {
757                 return &m_primitive_manager;
758         }
759
760         SIMD_FORCE_INLINE TrimeshPrimitiveManager* getTrimeshPrimitiveManager()
761         {
762                 return &m_primitive_manager;
763         }
764
765         virtual void calculateLocalInertia(btScalar mass, btVector3& inertia) const;
766
767         virtual const char* getName() const
768         {
769                 return "GImpactMeshShapePart";
770         }
771
772         virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const
773         {
774                 return CONST_GIMPACT_TRIMESH_SHAPE_PART;
775         }
776
777         //! Determines if this shape has triangles
778         virtual bool needsRetrieveTriangles() const
779         {
780                 return true;
781         }
782
783         //! Determines if this shape has tetrahedrons
784         virtual bool needsRetrieveTetrahedrons() const
785         {
786                 return false;
787         }
788
789         virtual void getBulletTriangle(int prim_index, btTriangleShapeEx& triangle) const
790         {
791                 m_primitive_manager.get_bullet_triangle(prim_index, triangle);
792         }
793
794         virtual void getBulletTetrahedron(int prim_index, btTetrahedronShapeEx& tetrahedron) const
795         {
796                 (void)prim_index;
797                 (void)tetrahedron;
798                 btAssert(0);
799         }
800
801         SIMD_FORCE_INLINE int getVertexCount() const
802         {
803                 return m_primitive_manager.get_vertex_count();
804         }
805
806         SIMD_FORCE_INLINE void getVertex(int vertex_index, btVector3& vertex) const
807         {
808                 m_primitive_manager.get_vertex(vertex_index, vertex);
809         }
810
811         SIMD_FORCE_INLINE void setMargin(btScalar margin)
812         {
813                 m_primitive_manager.m_margin = margin;
814                 postUpdate();
815         }
816
817         SIMD_FORCE_INLINE btScalar getMargin() const
818         {
819                 return m_primitive_manager.m_margin;
820         }
821
822         virtual void setLocalScaling(const btVector3& scaling)
823         {
824                 m_primitive_manager.m_scale = scaling;
825                 postUpdate();
826         }
827
828         virtual const btVector3& getLocalScaling() const
829         {
830                 return m_primitive_manager.m_scale;
831         }
832
833         SIMD_FORCE_INLINE int getPart() const
834         {
835                 return (int)m_primitive_manager.m_part;
836         }
837
838         virtual void processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const;
839         virtual void processAllTrianglesRay(btTriangleCallback* callback, const btVector3& rayFrom, const btVector3& rayTo) const;
840 };
841
842 //! This class manages a mesh supplied by the btStridingMeshInterface interface.
843 /*!
844 Set of btGImpactMeshShapePart parts
845 - Simply create this shape by passing the btStridingMeshInterface to the constructor btGImpactMeshShape, then you must call updateBound() after creating the mesh
846
847 - You can handle deformable meshes with this shape, by calling postUpdate() every time when changing the mesh vertices.
848
849 */
850 class btGImpactMeshShape : public btGImpactShapeInterface
851 {
852         btStridingMeshInterface* m_meshInterface;
853
854 protected:
855         btAlignedObjectArray<btGImpactMeshShapePart*> m_mesh_parts;
856         void buildMeshParts(btStridingMeshInterface* meshInterface)
857         {
858                 for (int i = 0; i < meshInterface->getNumSubParts(); ++i)
859                 {
860                         btGImpactMeshShapePart* newpart = new btGImpactMeshShapePart(meshInterface, i);
861                         m_mesh_parts.push_back(newpart);
862                 }
863         }
864
865         //! use this function for perfofm refit in bounding boxes
866         virtual void calcLocalAABB()
867         {
868                 m_localAABB.invalidate();
869                 int i = m_mesh_parts.size();
870                 while (i--)
871                 {
872                         m_mesh_parts[i]->updateBound();
873                         m_localAABB.merge(m_mesh_parts[i]->getLocalBox());
874                 }
875         }
876
877 public:
878         btGImpactMeshShape(btStridingMeshInterface* meshInterface)
879         {
880                 m_meshInterface = meshInterface;
881                 buildMeshParts(meshInterface);
882         }
883
884         virtual ~btGImpactMeshShape()
885         {
886                 int i = m_mesh_parts.size();
887                 while (i--)
888                 {
889                         btGImpactMeshShapePart* part = m_mesh_parts[i];
890                         delete part;
891                 }
892                 m_mesh_parts.clear();
893         }
894
895         btStridingMeshInterface* getMeshInterface()
896         {
897                 return m_meshInterface;
898         }
899
900         const btStridingMeshInterface* getMeshInterface() const
901         {
902                 return m_meshInterface;
903         }
904
905         int getMeshPartCount() const
906         {
907                 return m_mesh_parts.size();
908         }
909
910         btGImpactMeshShapePart* getMeshPart(int index)
911         {
912                 return m_mesh_parts[index];
913         }
914
915         const btGImpactMeshShapePart* getMeshPart(int index) const
916         {
917                 return m_mesh_parts[index];
918         }
919
920         virtual void setLocalScaling(const btVector3& scaling)
921         {
922                 localScaling = scaling;
923
924                 int i = m_mesh_parts.size();
925                 while (i--)
926                 {
927                         btGImpactMeshShapePart* part = m_mesh_parts[i];
928                         part->setLocalScaling(scaling);
929                 }
930
931                 m_needs_update = true;
932         }
933
934         virtual void setMargin(btScalar margin)
935         {
936                 m_collisionMargin = margin;
937
938                 int i = m_mesh_parts.size();
939                 while (i--)
940                 {
941                         btGImpactMeshShapePart* part = m_mesh_parts[i];
942                         part->setMargin(margin);
943                 }
944
945                 m_needs_update = true;
946         }
947
948         //! Tells to this object that is needed to refit all the meshes
949         virtual void postUpdate()
950         {
951                 int i = m_mesh_parts.size();
952                 while (i--)
953                 {
954                         btGImpactMeshShapePart* part = m_mesh_parts[i];
955                         part->postUpdate();
956                 }
957
958                 m_needs_update = true;
959         }
960
961         virtual void calculateLocalInertia(btScalar mass, btVector3& inertia) const;
962
963         //! Obtains the primitive manager
964         virtual const btPrimitiveManagerBase* getPrimitiveManager() const
965         {
966                 btAssert(0);
967                 return NULL;
968         }
969
970         //! Gets the number of children
971         virtual int getNumChildShapes() const
972         {
973                 btAssert(0);
974                 return 0;
975         }
976
977         //! if true, then its children must get transforms.
978         virtual bool childrenHasTransform() const
979         {
980                 btAssert(0);
981                 return false;
982         }
983
984         //! Determines if this shape has triangles
985         virtual bool needsRetrieveTriangles() const
986         {
987                 btAssert(0);
988                 return false;
989         }
990
991         //! Determines if this shape has tetrahedrons
992         virtual bool needsRetrieveTetrahedrons() const
993         {
994                 btAssert(0);
995                 return false;
996         }
997
998         virtual void getBulletTriangle(int prim_index, btTriangleShapeEx& triangle) const
999         {
1000                 (void)prim_index;
1001                 (void)triangle;
1002                 btAssert(0);
1003         }
1004
1005         virtual void getBulletTetrahedron(int prim_index, btTetrahedronShapeEx& tetrahedron) const
1006         {
1007                 (void)prim_index;
1008                 (void)tetrahedron;
1009                 btAssert(0);
1010         }
1011
1012         //! call when reading child shapes
1013         virtual void lockChildShapes() const
1014         {
1015                 btAssert(0);
1016         }
1017
1018         virtual void unlockChildShapes() const
1019         {
1020                 btAssert(0);
1021         }
1022
1023         //! Retrieves the bound from a child
1024         /*!
1025     */
1026         virtual void getChildAabb(int child_index, const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
1027         {
1028                 (void)child_index;
1029                 (void)t;
1030                 (void)aabbMin;
1031                 (void)aabbMax;
1032                 btAssert(0);
1033         }
1034
1035         //! Gets the children
1036         virtual btCollisionShape* getChildShape(int index)
1037         {
1038                 (void)index;
1039                 btAssert(0);
1040                 return NULL;
1041         }
1042
1043         //! Gets the child
1044         virtual const btCollisionShape* getChildShape(int index) const
1045         {
1046                 (void)index;
1047                 btAssert(0);
1048                 return NULL;
1049         }
1050
1051         //! Gets the children transform
1052         virtual btTransform getChildTransform(int index) const
1053         {
1054                 (void)index;
1055                 btAssert(0);
1056                 return btTransform();
1057         }
1058
1059         //! Sets the children transform
1060         /*!
1061         \post You must call updateBound() for update the box set.
1062         */
1063         virtual void setChildTransform(int index, const btTransform& transform)
1064         {
1065                 (void)index;
1066                 (void)transform;
1067                 btAssert(0);
1068         }
1069
1070         virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const
1071         {
1072                 return CONST_GIMPACT_TRIMESH_SHAPE;
1073         }
1074
1075         virtual const char* getName() const
1076         {
1077                 return "GImpactMesh";
1078         }
1079
1080         virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const;
1081
1082         //! Function for retrieve triangles.
1083         /*!
1084         It gives the triangles in local space
1085         */
1086         virtual void processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const;
1087
1088         virtual void processAllTrianglesRay(btTriangleCallback* callback, const btVector3& rayFrom, const btVector3& rayTo) const;
1089
1090         virtual int calculateSerializeBufferSize() const;
1091
1092         ///fills the dataBuffer and returns the struct name (and 0 on failure)
1093         virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const;
1094 };
1095
1096 ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
1097 struct btGImpactMeshShapeData
1098 {
1099         btCollisionShapeData m_collisionShapeData;
1100
1101         btStridingMeshInterfaceData m_meshInterface;
1102
1103         btVector3FloatData m_localScaling;
1104
1105         float m_collisionMargin;
1106
1107         int m_gimpactSubType;
1108 };
1109
1110 SIMD_FORCE_INLINE int btGImpactMeshShape::calculateSerializeBufferSize() const
1111 {
1112         return sizeof(btGImpactMeshShapeData);
1113 }
1114
1115 #endif  //GIMPACT_MESH_SHAPE_H