Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/external/bullet/BulletCollision/Gimpact/btGImpactShape.h @ 5738

Last change on this file since 5738 was 5738, checked in by landauf, 15 years ago

merged libraries2 back to trunk

  • Property svn:eol-style set to native
File size: 25.3 KB
Line 
1/*! \file btGImpactShape.h
2\author Francisco Len Nßjera
3*/
4/*
5This source file is part of GIMPACT Library.
6
7For the latest info, see http://gimpact.sourceforge.net/
8
9Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
10email: projectileman@yahoo.com
11
12
13This software is provided 'as-is', without any express or implied warranty.
14In no event will the authors be held liable for any damages arising from the use of this software.
15Permission is granted to anyone to use this software for any purpose,
16including commercial applications, and to alter it and redistribute it freely,
17subject to the following restrictions:
18
191. 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.
202. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
213. 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)
44typedef btGImpactQuantizedBvh btGImpactBoxSet;
45
46enum 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
55class btTetrahedronShapeEx:public btBU_Simplex1to4
56{
57public:
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
78class btGImpactShapeInterface : public btConcaveShape
79{
80protected:
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
105public:
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() = 0;
193
194        //! gets boxset
195        SIMD_FORCE_INLINE btGImpactBoxSet * getBoxSet()
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        }
280
281        //! Function for retrieve triangles.
282        /*!
283        It gives the triangles in local space
284        */
285        virtual void    processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
286        {
287        }
288
289        //!@}
290
291};
292
293
294//! btGImpactCompoundShape allows to handle multiple btCollisionShape objects at once
295/*!
296This class only can manage Convex subshapes
297*/
298class btGImpactCompoundShape    : public btGImpactShapeInterface
299{
300public:
301        //! compound primitive manager
302        class CompoundPrimitiveManager:public btPrimitiveManagerBase
303        {
304        public:
305                btGImpactCompoundShape * m_compoundShape;
306
307
308                CompoundPrimitiveManager(const CompoundPrimitiveManager& compound)
309                {
310                        m_compoundShape = compound.m_compoundShape;
311                }
312
313                CompoundPrimitiveManager(btGImpactCompoundShape * compoundShape)
314                {
315                        m_compoundShape = compoundShape;
316                }
317
318                CompoundPrimitiveManager()
319                {
320                        m_compoundShape = NULL;
321                }
322
323                virtual bool is_trimesh() const
324                {
325                        return false;
326                }
327
328                virtual int get_primitive_count() const
329                {
330                        return (int )m_compoundShape->getNumChildShapes();
331                }
332
333                virtual void get_primitive_box(int prim_index ,btAABB & primbox) const
334                {
335                        btTransform prim_trans;
336                        if(m_compoundShape->childrenHasTransform())
337                        {
338                                prim_trans = m_compoundShape->getChildTransform(prim_index);
339                        }
340                        else
341                        {
342                                prim_trans.setIdentity();
343                        }
344                        const btCollisionShape* shape = m_compoundShape->getChildShape(prim_index);
345                        shape->getAabb(prim_trans,primbox.m_min,primbox.m_max);
346                }
347
348                virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const
349                {
350                        btAssert(0);
351                }
352
353        };
354
355
356
357protected:
358        CompoundPrimitiveManager m_primitive_manager;
359        btAlignedObjectArray<btTransform>               m_childTransforms;
360        btAlignedObjectArray<btCollisionShape*> m_childShapes;
361
362
363public:
364
365        btGImpactCompoundShape(bool children_has_transform = true)
366        {
367                m_primitive_manager.m_compoundShape = this;
368                m_box_set.setPrimitiveManager(&m_primitive_manager);
369        }
370
371        virtual ~btGImpactCompoundShape()
372        {
373        }
374
375
376        //! if true, then its children must get transforms.
377        virtual bool childrenHasTransform() const
378        {
379                if(m_childTransforms.size()==0) return false;
380                return true;
381        }
382
383
384        //! Obtains the primitive manager
385        virtual const btPrimitiveManagerBase * getPrimitiveManager()  const
386        {
387                return &m_primitive_manager;
388        }
389
390        //! Obtains the compopund primitive manager
391        SIMD_FORCE_INLINE CompoundPrimitiveManager * getCompoundPrimitiveManager()
392        {
393                return &m_primitive_manager;
394        }
395
396        //! Gets the number of children
397        virtual int     getNumChildShapes() const
398        {
399                return m_childShapes.size();
400        }
401
402
403        //! Use this method for adding children. Only Convex shapes are allowed.
404        void addChildShape(const btTransform& localTransform,btCollisionShape* shape)
405        {
406                btAssert(shape->isConvex());
407                m_childTransforms.push_back(localTransform);
408                m_childShapes.push_back(shape);
409        }
410
411        //! Use this method for adding children. Only Convex shapes are allowed.
412        void addChildShape(btCollisionShape* shape)
413        {
414                btAssert(shape->isConvex());
415                m_childShapes.push_back(shape);
416        }
417
418        //! Gets the children
419        virtual btCollisionShape* getChildShape(int index)
420        {
421                return m_childShapes[index];
422        }
423
424        //! Gets the children
425        virtual const btCollisionShape* getChildShape(int index) const
426        {
427                return m_childShapes[index];
428        }
429
430        //! Retrieves the bound from a child
431    /*!
432    */
433    virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
434    {
435
436        if(childrenHasTransform())
437        {
438                m_childShapes[child_index]->getAabb(t*m_childTransforms[child_index],aabbMin,aabbMax);
439        }
440        else
441        {
442                m_childShapes[child_index]->getAabb(t,aabbMin,aabbMax);
443        }
444    }
445
446
447        //! Gets the children transform
448        virtual btTransform     getChildTransform(int index) const
449        {
450                btAssert(m_childTransforms.size() == m_childShapes.size());
451                return m_childTransforms[index];
452        }
453
454        //! Sets the children transform
455        /*!
456        \post You must call updateBound() for update the box set.
457        */
458        virtual void setChildTransform(int index, const btTransform & transform)
459        {
460                btAssert(m_childTransforms.size() == m_childShapes.size());
461                m_childTransforms[index] = transform;
462                postUpdate();
463        }
464
465        //! Determines if this shape has triangles
466        virtual bool needsRetrieveTriangles() const
467        {
468                return false;
469        }
470
471        //! Determines if this shape has tetrahedrons
472        virtual bool needsRetrieveTetrahedrons() const
473        {
474                return false;
475        }
476
477
478        virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const
479        {
480                btAssert(0);
481        }
482
483        virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const
484        {
485                btAssert(0);
486        }
487
488
489        //! Calculates the exact inertia tensor for this shape
490        virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia) const;
491
492        virtual const char*     getName()const
493        {
494                return "GImpactCompound";
495        }
496
497        virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType()
498        {
499                return CONST_GIMPACT_COMPOUND_SHAPE;
500        }
501
502};
503
504
505
506//! This class manages a sub part of a mesh supplied by the btStridingMeshInterface interface.
507/*!
508- Simply create this shape by passing the btStridingMeshInterface to the constructor btGImpactMeshShapePart, then you must call updateBound() after creating the mesh
509- When making operations with this shape, you must call <b>lock</b> before accessing to the trimesh primitives, and then call <b>unlock</b>
510- You can handle deformable meshes with this shape, by calling postUpdate() every time when changing the mesh vertices.
511
512*/
513class btGImpactMeshShapePart : public btGImpactShapeInterface
514{
515public:
516        //! Trimesh primitive manager
517        /*!
518        Manages the info from btStridingMeshInterface object and controls the Lock/Unlock mechanism
519        */
520        class TrimeshPrimitiveManager:public btPrimitiveManagerBase
521        {
522        public:
523                btScalar m_margin;
524                btStridingMeshInterface * m_meshInterface;
525                btVector3 m_scale;
526                int m_part;
527                int m_lock_count;
528                const unsigned char *vertexbase;
529                int numverts;
530                PHY_ScalarType type;
531                int stride;
532                const unsigned char *indexbase;
533                int indexstride;
534                int  numfaces;
535                PHY_ScalarType indicestype;
536
537                TrimeshPrimitiveManager()
538                {
539                        m_meshInterface = NULL;
540                        m_part = 0;
541                        m_margin = 0.01f;
542                        m_scale = btVector3(1.f,1.f,1.f);
543                        m_lock_count = 0;
544                        vertexbase = 0;
545                        numverts = 0;
546                        stride = 0;
547                        indexbase = 0;
548                        indexstride = 0;
549                        numfaces = 0;
550                }
551
552                TrimeshPrimitiveManager(const TrimeshPrimitiveManager & manager)
553                {
554                        m_meshInterface = manager.m_meshInterface;
555                        m_part = manager.m_part;
556                        m_margin = manager.m_margin;
557                        m_scale = manager.m_scale;
558                        m_lock_count = 0;
559                        vertexbase = 0;
560                        numverts = 0;
561                        stride = 0;
562                        indexbase = 0;
563                        indexstride = 0;
564                        numfaces = 0;
565
566                }
567
568                TrimeshPrimitiveManager(
569                        btStridingMeshInterface * meshInterface,        int part)
570                {
571                        m_meshInterface = meshInterface;
572                        m_part = part;
573                        m_scale = m_meshInterface->getScaling();
574                        m_margin = 0.1f;
575                        m_lock_count = 0;
576                        vertexbase = 0;
577                        numverts = 0;
578                        stride = 0;
579                        indexbase = 0;
580                        indexstride = 0;
581                        numfaces = 0;
582
583                }
584
585
586                void lock()
587                {
588                        if(m_lock_count>0)
589                        {
590                                m_lock_count++;
591                                return;
592                        }
593                        m_meshInterface->getLockedReadOnlyVertexIndexBase(
594                                &vertexbase,numverts,
595                                type, stride,&indexbase, indexstride, numfaces,indicestype,m_part);
596
597                        m_lock_count = 1;
598                }
599
600                void unlock()
601                {
602                        if(m_lock_count == 0) return;
603                        if(m_lock_count>1)
604                        {
605                                --m_lock_count;
606                                return;
607                        }
608                        m_meshInterface->unLockReadOnlyVertexBase(m_part);
609                        vertexbase = NULL;
610                        m_lock_count = 0;
611                }
612
613                virtual bool is_trimesh() const
614                {
615                        return true;
616                }
617
618                virtual int get_primitive_count() const
619                {
620                        return (int )numfaces;
621                }
622
623                SIMD_FORCE_INLINE int get_vertex_count() const
624                {
625                        return (int )numverts;
626                }
627
628                SIMD_FORCE_INLINE void get_indices(int face_index,int &i0,int &i1,int &i2) const
629                {
630                        if(indicestype == PHY_SHORT)
631                        {
632                                short * s_indices = (short *)(indexbase + face_index*indexstride);
633                                i0 = s_indices[0];
634                                i1 = s_indices[1];
635                                i2 = s_indices[2];
636                        }
637                        else
638                        {
639                                int * i_indices = (int *)(indexbase + face_index*indexstride);
640                                i0 = i_indices[0];
641                                i1 = i_indices[1];
642                                i2 = i_indices[2];
643                        }
644                }
645
646                SIMD_FORCE_INLINE void get_vertex(int vertex_index, btVector3 & vertex) const
647                {
648                        if(type == PHY_DOUBLE)
649                        {
650                                double * dvertices = (double *)(vertexbase + vertex_index*stride);
651                                vertex[0] = btScalar(dvertices[0]*m_scale[0]);
652                                vertex[1] = btScalar(dvertices[1]*m_scale[1]);
653                                vertex[2] = btScalar(dvertices[2]*m_scale[2]);
654                        }
655                        else
656                        {
657                                float * svertices = (float *)(vertexbase + vertex_index*stride);
658                                vertex[0] = svertices[0]*m_scale[0];
659                                vertex[1] = svertices[1]*m_scale[1];
660                                vertex[2] = svertices[2]*m_scale[2];
661                        }
662                }
663
664                virtual void get_primitive_box(int prim_index ,btAABB & primbox) const
665                {
666                        btPrimitiveTriangle  triangle;
667                        get_primitive_triangle(prim_index,triangle);
668                        primbox.calc_from_triangle_margin(
669                                triangle.m_vertices[0],
670                                triangle.m_vertices[1],triangle.m_vertices[2],triangle.m_margin);
671                }
672
673                virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const
674                {
675                        int indices[3];
676                        get_indices(prim_index,indices[0],indices[1],indices[2]);
677                        get_vertex(indices[0],triangle.m_vertices[0]);
678                        get_vertex(indices[1],triangle.m_vertices[1]);
679                        get_vertex(indices[2],triangle.m_vertices[2]);
680                        triangle.m_margin = m_margin;
681                }
682
683                SIMD_FORCE_INLINE void get_bullet_triangle(int prim_index,btTriangleShapeEx & 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_vertices1[0]);
688                        get_vertex(indices[1],triangle.m_vertices1[1]);
689                        get_vertex(indices[2],triangle.m_vertices1[2]);
690                        triangle.setMargin(m_margin);
691                }
692
693        };
694
695
696protected:
697        TrimeshPrimitiveManager m_primitive_manager;
698public:
699
700        btGImpactMeshShapePart()
701        {
702                m_box_set.setPrimitiveManager(&m_primitive_manager);
703        }
704
705
706        btGImpactMeshShapePart(btStridingMeshInterface * meshInterface, int part)
707        {
708                m_primitive_manager.m_meshInterface = meshInterface;
709                m_primitive_manager.m_part = part;
710                m_box_set.setPrimitiveManager(&m_primitive_manager);
711        }
712
713        virtual ~btGImpactMeshShapePart()
714        {
715        }
716
717        //! if true, then its children must get transforms.
718        virtual bool childrenHasTransform() const
719        {
720                return false;
721        }
722
723
724        //! call when reading child shapes
725        virtual void lockChildShapes() const
726        {
727                void * dummy = (void*)(m_box_set.getPrimitiveManager());
728                TrimeshPrimitiveManager * dummymanager = static_cast<TrimeshPrimitiveManager *>(dummy);
729                dummymanager->lock();
730        }
731
732        virtual void unlockChildShapes()  const
733        {
734                void * dummy = (void*)(m_box_set.getPrimitiveManager());
735                TrimeshPrimitiveManager * dummymanager = static_cast<TrimeshPrimitiveManager *>(dummy);
736                dummymanager->unlock();
737        }
738
739        //! Gets the number of children
740        virtual int     getNumChildShapes() const
741        {
742                return m_primitive_manager.get_primitive_count();
743        }
744
745
746        //! Gets the children
747        virtual btCollisionShape* getChildShape(int index)
748        {
749                btAssert(0);
750                return NULL;
751        }
752
753
754
755        //! Gets the child
756        virtual const btCollisionShape* getChildShape(int index) const
757        {
758                btAssert(0);
759                return NULL;
760        }
761
762        //! Gets the children transform
763        virtual btTransform     getChildTransform(int index) const
764        {
765                btAssert(0);
766                return btTransform();
767        }
768
769        //! Sets the children transform
770        /*!
771        \post You must call updateBound() for update the box set.
772        */
773        virtual void setChildTransform(int index, const btTransform & transform)
774        {
775                btAssert(0);
776        }
777
778
779        //! Obtains the primitive manager
780        virtual const btPrimitiveManagerBase * getPrimitiveManager()  const
781        {
782                return &m_primitive_manager;
783        }
784
785        SIMD_FORCE_INLINE TrimeshPrimitiveManager * getTrimeshPrimitiveManager()
786        {
787                return &m_primitive_manager;
788        }
789
790
791
792
793
794        virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia) const;
795
796
797
798
799        virtual const char*     getName()const
800        {
801                return "GImpactMeshShapePart";
802        }
803
804        virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType()
805        {
806                return CONST_GIMPACT_TRIMESH_SHAPE_PART;
807        }
808
809        //! Determines if this shape has triangles
810        virtual bool needsRetrieveTriangles() const
811        {
812                return true;
813        }
814
815        //! Determines if this shape has tetrahedrons
816        virtual bool needsRetrieveTetrahedrons() const
817        {
818                return false;
819        }
820
821        virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const
822        {
823                m_primitive_manager.get_bullet_triangle(prim_index,triangle);
824        }
825
826        virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const
827        {
828                btAssert(0);
829        }
830
831
832
833        SIMD_FORCE_INLINE int getVertexCount() const
834        {
835                return m_primitive_manager.get_vertex_count();
836        }
837
838        SIMD_FORCE_INLINE void getVertex(int vertex_index, btVector3 & vertex) const
839        {
840                m_primitive_manager.get_vertex(vertex_index,vertex);
841        }
842
843        SIMD_FORCE_INLINE void setMargin(btScalar margin)
844    {
845        m_primitive_manager.m_margin = margin;
846        postUpdate();
847    }
848
849    SIMD_FORCE_INLINE btScalar getMargin() const
850    {
851        return m_primitive_manager.m_margin;
852    }
853
854    virtual void        setLocalScaling(const btVector3& scaling)
855    {
856        m_primitive_manager.m_scale = scaling;
857        postUpdate();
858    }
859
860    virtual const btVector3& getLocalScaling() const
861    {
862        return m_primitive_manager.m_scale;
863    }
864
865    SIMD_FORCE_INLINE int getPart() const
866    {
867        return (int)m_primitive_manager.m_part;
868    }
869
870        virtual void    processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
871};
872
873
874//! This class manages a mesh supplied by the btStridingMeshInterface interface.
875/*!
876Set of btGImpactMeshShapePart parts
877- Simply create this shape by passing the btStridingMeshInterface to the constructor btGImpactMeshShape, then you must call updateBound() after creating the mesh
878
879- You can handle deformable meshes with this shape, by calling postUpdate() every time when changing the mesh vertices.
880
881*/
882class btGImpactMeshShape : public btGImpactShapeInterface
883{
884        btStridingMeshInterface* m_meshInterface;
885
886protected:
887        btAlignedObjectArray<btGImpactMeshShapePart*> m_mesh_parts;
888        void buildMeshParts(btStridingMeshInterface * meshInterface)
889        {
890                for (int i=0;i<meshInterface->getNumSubParts() ;++i )
891                {
892                        btGImpactMeshShapePart * newpart = new btGImpactMeshShapePart(meshInterface,i);
893                        m_mesh_parts.push_back(newpart);
894                }
895        }
896
897        //! use this function for perfofm refit in bounding boxes
898    virtual void calcLocalAABB()
899    {
900        m_localAABB.invalidate();
901        int i = m_mesh_parts.size();
902        while(i--)
903        {
904                m_mesh_parts[i]->updateBound();
905                m_localAABB.merge(m_mesh_parts[i]->getLocalBox());
906        }
907    }
908
909public:
910        btGImpactMeshShape(btStridingMeshInterface * meshInterface)
911        {
912                m_meshInterface = meshInterface;
913                buildMeshParts(meshInterface);
914        }
915
916        virtual ~btGImpactMeshShape()
917        {
918                int i = m_mesh_parts.size();
919        while(i--)
920        {
921                        btGImpactMeshShapePart * part = m_mesh_parts[i];
922                        delete part;
923        }
924                m_mesh_parts.clear();
925        }
926
927
928        btStridingMeshInterface* getMeshInterface()
929        {
930                return m_meshInterface;
931        }
932
933        const btStridingMeshInterface* getMeshInterface() const
934        {
935                return m_meshInterface;
936        }
937
938        int getMeshPartCount() const
939        {
940                return m_mesh_parts.size();
941        }
942
943        btGImpactMeshShapePart * getMeshPart(int index)
944        {
945                return m_mesh_parts[index];
946        }
947
948
949
950        const btGImpactMeshShapePart * getMeshPart(int index) const
951        {
952                return m_mesh_parts[index];
953        }
954
955
956        virtual void    setLocalScaling(const btVector3& scaling)
957        {
958                localScaling = scaling;
959
960                int i = m_mesh_parts.size();
961        while(i--)
962        {
963                        btGImpactMeshShapePart * part = m_mesh_parts[i];
964                        part->setLocalScaling(scaling);
965        }
966
967                m_needs_update = true;
968        }
969
970        virtual void setMargin(btScalar margin)
971    {
972        m_collisionMargin = margin;
973
974                int i = m_mesh_parts.size();
975        while(i--)
976        {
977                        btGImpactMeshShapePart * part = m_mesh_parts[i];
978                        part->setMargin(margin);
979        }
980
981                m_needs_update = true;
982    }
983
984        //! Tells to this object that is needed to refit all the meshes
985    virtual void postUpdate()
986    {
987                int i = m_mesh_parts.size();
988        while(i--)
989        {
990                        btGImpactMeshShapePart * part = m_mesh_parts[i];
991                        part->postUpdate();
992        }
993
994        m_needs_update = true;
995    }
996
997        virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia) const;
998
999
1000        //! Obtains the primitive manager
1001        virtual const btPrimitiveManagerBase * getPrimitiveManager()  const
1002        {
1003                btAssert(0);
1004                return NULL;
1005        }
1006
1007
1008        //! Gets the number of children
1009        virtual int     getNumChildShapes() const
1010        {
1011                btAssert(0);
1012                return 0;
1013        }
1014
1015
1016        //! if true, then its children must get transforms.
1017        virtual bool childrenHasTransform() const
1018        {
1019                btAssert(0);
1020                return false;
1021        }
1022
1023        //! Determines if this shape has triangles
1024        virtual bool needsRetrieveTriangles() const
1025        {
1026                btAssert(0);
1027                return false;
1028        }
1029
1030        //! Determines if this shape has tetrahedrons
1031        virtual bool needsRetrieveTetrahedrons() const
1032        {
1033                btAssert(0);
1034                return false;
1035        }
1036
1037        virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const
1038        {
1039                btAssert(0);
1040        }
1041
1042        virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const
1043        {
1044                btAssert(0);
1045        }
1046
1047        //! call when reading child shapes
1048        virtual void lockChildShapes() const
1049        {
1050                btAssert(0);
1051        }
1052
1053        virtual void unlockChildShapes() const
1054        {
1055                btAssert(0);
1056        }
1057
1058
1059
1060
1061        //! Retrieves the bound from a child
1062    /*!
1063    */
1064    virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
1065    {
1066        btAssert(0);
1067    }
1068
1069        //! Gets the children
1070        virtual btCollisionShape* getChildShape(int index)
1071        {
1072                btAssert(0);
1073                return NULL;
1074        }
1075
1076
1077        //! Gets the child
1078        virtual const btCollisionShape* getChildShape(int index) const
1079        {
1080                btAssert(0);
1081                return NULL;
1082        }
1083
1084        //! Gets the children transform
1085        virtual btTransform     getChildTransform(int index) const
1086        {
1087                btAssert(0);
1088                return btTransform();
1089        }
1090
1091        //! Sets the children transform
1092        /*!
1093        \post You must call updateBound() for update the box set.
1094        */
1095        virtual void setChildTransform(int index, const btTransform & transform)
1096        {
1097                btAssert(0);
1098        }
1099
1100
1101        virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType()
1102        {
1103                return CONST_GIMPACT_TRIMESH_SHAPE;
1104        }
1105
1106
1107        virtual const char*     getName()const
1108        {
1109                return "GImpactMesh";
1110        }
1111
1112        virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback)  const;
1113
1114        //! Function for retrieve triangles.
1115        /*!
1116        It gives the triangles in local space
1117        */
1118        virtual void    processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
1119};
1120
1121
1122#endif //GIMPACT_MESH_SHAPE_H
Note: See TracBrowser for help on using the repository browser.