Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/bullet/BulletCollision/Gimpact/btGImpactShape.h @ 1963

Last change on this file since 1963 was 1963, checked in by rgrieder, 16 years ago

Added Bullet physics engine.

  • Property svn:eol-style set to native
File size: 25.0 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{
884protected:
885        btAlignedObjectArray<btGImpactMeshShapePart*> m_mesh_parts;
886        void buildMeshParts(btStridingMeshInterface * meshInterface)
887        {
888                for (int i=0;i<meshInterface->getNumSubParts() ;++i )
889                {
890                        btGImpactMeshShapePart * newpart = new btGImpactMeshShapePart(meshInterface,i);
891                        m_mesh_parts.push_back(newpart);
892                }
893        }
894
895        //! use this function for perfofm refit in bounding boxes
896    virtual void calcLocalAABB()
897    {
898        m_localAABB.invalidate();
899        int i = m_mesh_parts.size();
900        while(i--)
901        {
902                m_mesh_parts[i]->updateBound();
903                m_localAABB.merge(m_mesh_parts[i]->getLocalBox());
904        }
905    }
906
907public:
908        btGImpactMeshShape(btStridingMeshInterface * meshInterface)
909        {
910                buildMeshParts(meshInterface);
911        }
912
913        virtual ~btGImpactMeshShape()
914        {
915                int i = m_mesh_parts.size();
916        while(i--)
917        {
918                        btGImpactMeshShapePart * part = m_mesh_parts[i];
919                        delete part;
920        }
921                m_mesh_parts.clear();
922        }
923
924
925
926        int getMeshPartCount() const
927        {
928                return m_mesh_parts.size();
929        }
930
931        btGImpactMeshShapePart * getMeshPart(int index)
932        {
933                return m_mesh_parts[index];
934        }
935
936
937
938        const btGImpactMeshShapePart * getMeshPart(int index) const
939        {
940                return m_mesh_parts[index];
941        }
942
943
944        virtual void    setLocalScaling(const btVector3& scaling)
945        {
946                localScaling = scaling;
947
948                int i = m_mesh_parts.size();
949        while(i--)
950        {
951                        btGImpactMeshShapePart * part = m_mesh_parts[i];
952                        part->setLocalScaling(scaling);
953        }
954
955                m_needs_update = true;
956        }
957
958        virtual void setMargin(btScalar margin)
959    {
960        m_collisionMargin = margin;
961
962                int i = m_mesh_parts.size();
963        while(i--)
964        {
965                        btGImpactMeshShapePart * part = m_mesh_parts[i];
966                        part->setMargin(margin);
967        }
968
969                m_needs_update = true;
970    }
971
972        //! Tells to this object that is needed to refit all the meshes
973    virtual void postUpdate()
974    {
975                int i = m_mesh_parts.size();
976        while(i--)
977        {
978                        btGImpactMeshShapePart * part = m_mesh_parts[i];
979                        part->postUpdate();
980        }
981
982        m_needs_update = true;
983    }
984
985        virtual void    calculateLocalInertia(btScalar mass,btVector3& inertia) const;
986
987
988        //! Obtains the primitive manager
989        virtual const btPrimitiveManagerBase * getPrimitiveManager()  const
990        {
991                btAssert(0);
992                return NULL;
993        }
994
995
996        //! Gets the number of children
997        virtual int     getNumChildShapes() const
998        {
999                btAssert(0);
1000                return 0;
1001        }
1002
1003
1004        //! if true, then its children must get transforms.
1005        virtual bool childrenHasTransform() const
1006        {
1007                btAssert(0);
1008                return false;
1009        }
1010
1011        //! Determines if this shape has triangles
1012        virtual bool needsRetrieveTriangles() const
1013        {
1014                btAssert(0);
1015                return false;
1016        }
1017
1018        //! Determines if this shape has tetrahedrons
1019        virtual bool needsRetrieveTetrahedrons() const
1020        {
1021                btAssert(0);
1022                return false;
1023        }
1024
1025        virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const
1026        {
1027                btAssert(0);
1028        }
1029
1030        virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const
1031        {
1032                btAssert(0);
1033        }
1034
1035        //! call when reading child shapes
1036        virtual void lockChildShapes()
1037        {
1038                btAssert(0);
1039        }
1040
1041        virtual void unlockChildShapes()
1042        {
1043                btAssert(0);
1044        }
1045
1046
1047
1048
1049        //! Retrieves the bound from a child
1050    /*!
1051    */
1052    virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
1053    {
1054        btAssert(0);
1055    }
1056
1057        //! Gets the children
1058        virtual btCollisionShape* getChildShape(int index)
1059        {
1060                btAssert(0);
1061                return NULL;
1062        }
1063
1064
1065        //! Gets the child
1066        virtual const btCollisionShape* getChildShape(int index) const
1067        {
1068                btAssert(0);
1069                return NULL;
1070        }
1071
1072        //! Gets the children transform
1073        virtual btTransform     getChildTransform(int index) const
1074        {
1075                btAssert(0);
1076                return btTransform();
1077        }
1078
1079        //! Sets the children transform
1080        /*!
1081        \post You must call updateBound() for update the box set.
1082        */
1083        virtual void setChildTransform(int index, const btTransform & transform)
1084        {
1085                btAssert(0);
1086        }
1087
1088
1089        virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType()
1090        {
1091                return CONST_GIMPACT_TRIMESH_SHAPE;
1092        }
1093
1094
1095        virtual const char*     getName()const
1096        {
1097                return "GImpactMesh";
1098        }
1099
1100        virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback)  const;
1101
1102        //! Function for retrieve triangles.
1103        /*!
1104        It gives the triangles in local space
1105        */
1106        virtual void    processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
1107};
1108
1109
1110#endif //GIMPACT_MESH_SHAPE_H
Note: See TracBrowser for help on using the repository browser.