~ubuntu-branches/ubuntu/maverick/blender/maverick

« back to all changes in this revision

Viewing changes to extern/bullet2/src/BulletCollision/Gimpact/btGImpactShape.h

  • Committer: Bazaar Package Importer
  • Author(s): Khashayar Naderehvandi, Khashayar Naderehvandi, Alessio Treglia
  • Date: 2009-01-22 16:53:59 UTC
  • mfrom: (14.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20090122165359-v0996tn7fbit64ni
Tags: 2.48a+dfsg-1ubuntu1
[ Khashayar Naderehvandi ]
* Merge from debian experimental (LP: #320045), Ubuntu remaining changes:
  - Add patch correcting header file locations.
  - Add libvorbis-dev and libgsm1-dev to Build-Depends.
  - Use avcodec_decode_audio2() in source/blender/src/hddaudio.c

[ Alessio Treglia ]
* Add missing previous changelog entries.

Show diffs side-by-side

added added

removed removed

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