Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/masterserver2/src/external/bullet/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp @ 8016

Last change on this file since 8016 was 5781, checked in by rgrieder, 15 years ago

Reverted trunk again. We might want to find a way to delete these revisions again (x3n's changes are still available as diff in the commit mails).

  • Property svn:eol-style set to native
File size: 21.2 KB
Line 
1/*
2This source file is part of GIMPACT Library.
3
4For the latest info, see http://gimpact.sourceforge.net/
5
6Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
7email: projectileman@yahoo.com
8
9
10This software is provided 'as-is', without any express or implied warranty.
11In no event will the authors be held liable for any damages arising from the use of this software.
12Permission is granted to anyone to use this software for any purpose,
13including commercial applications, and to alter it and redistribute it freely,
14subject to the following restrictions:
15
161. 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.
172. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
183. This notice may not be removed or altered from any source distribution.
19*/
20/*
21Author: Francisco Len Nßjera
22Concave-Concave Collision
23
24*/
25
26#include "BulletCollision/CollisionDispatch/btManifoldResult.h"
27#include "LinearMath/btIDebugDraw.h"
28#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
29#include "BulletCollision/CollisionShapes/btBoxShape.h"
30#include "btGImpactCollisionAlgorithm.h"
31#include "btContactProcessing.h"
32#include "LinearMath/btQuickprof.h"
33
34
35//! Class for accessing the plane equation
36class btPlaneShape : public btStaticPlaneShape
37{
38public:
39
40        btPlaneShape(const btVector3& v, float f)
41                :btStaticPlaneShape(v,f)
42        {
43        }
44
45        void get_plane_equation(btVector4 &equation)
46        {
47                equation[0] = m_planeNormal[0];
48                equation[1] = m_planeNormal[1];
49                equation[2] = m_planeNormal[2];
50                equation[3] = m_planeConstant;
51        }
52
53
54        void get_plane_equation_transformed(const btTransform & trans,btVector4 &equation)
55        {
56                equation[0] = trans.getBasis().getRow(0).dot(m_planeNormal);
57                equation[1] = trans.getBasis().getRow(1).dot(m_planeNormal);
58                equation[2] = trans.getBasis().getRow(2).dot(m_planeNormal);
59                equation[3] = trans.getOrigin().dot(m_planeNormal) + m_planeConstant;
60        }
61};
62
63
64
65//////////////////////////////////////////////////////////////////////////////////////////////
66#ifdef TRI_COLLISION_PROFILING
67
68btClock g_triangle_clock;
69
70float g_accum_triangle_collision_time = 0;
71int g_count_triangle_collision = 0;
72
73void bt_begin_gim02_tri_time()
74{
75        g_triangle_clock.reset();
76}
77
78void bt_end_gim02_tri_time()
79{
80        g_accum_triangle_collision_time += g_triangle_clock.getTimeMicroseconds();
81        g_count_triangle_collision++;
82}
83#endif //TRI_COLLISION_PROFILING
84//! Retrieving shapes shapes
85/*!
86Declared here due of insuficent space on Pool allocators
87*/
88//!@{
89class GIM_ShapeRetriever
90{
91public:
92        btGImpactShapeInterface * m_gim_shape;
93        btTriangleShapeEx m_trishape;
94        btTetrahedronShapeEx m_tetrashape;
95
96public:
97        class ChildShapeRetriever
98        {
99        public:
100                GIM_ShapeRetriever * m_parent;
101                virtual btCollisionShape * getChildShape(int index)
102                {
103                        return m_parent->m_gim_shape->getChildShape(index);
104                }
105        };
106
107        class TriangleShapeRetriever:public ChildShapeRetriever
108        {
109        public:
110
111                virtual btCollisionShape * getChildShape(int index)
112                {
113                        m_parent->m_gim_shape->getBulletTriangle(index,m_parent->m_trishape);
114                        return &m_parent->m_trishape;
115                }
116        };
117
118        class TetraShapeRetriever:public ChildShapeRetriever
119        {
120        public:
121
122                virtual btCollisionShape * getChildShape(int index)
123                {
124                        m_parent->m_gim_shape->getBulletTetrahedron(index,m_parent->m_tetrashape);
125                        return &m_parent->m_tetrashape;
126                }
127        };
128public:
129        ChildShapeRetriever m_child_retriever;
130        TriangleShapeRetriever m_tri_retriever;
131        TetraShapeRetriever  m_tetra_retriever;
132        ChildShapeRetriever * m_current_retriever;
133
134        GIM_ShapeRetriever(btGImpactShapeInterface * gim_shape)
135        {
136                m_gim_shape = gim_shape;
137                //select retriever
138                if(m_gim_shape->needsRetrieveTriangles())
139                {
140                        m_current_retriever = &m_tri_retriever;
141                }
142                else if(m_gim_shape->needsRetrieveTetrahedrons())
143                {
144                        m_current_retriever = &m_tetra_retriever;
145                }
146                else
147                {
148                        m_current_retriever = &m_child_retriever;
149                }
150
151                m_current_retriever->m_parent = this;
152        }
153
154        btCollisionShape * getChildShape(int index)
155        {
156                return m_current_retriever->getChildShape(index);
157        }
158
159
160};
161
162
163
164//!@}
165
166
167#ifdef TRI_COLLISION_PROFILING
168
169//! Gets the average time in miliseconds of tree collisions
170float btGImpactCollisionAlgorithm::getAverageTreeCollisionTime()
171{
172        return btGImpactBoxSet::getAverageTreeCollisionTime();
173
174}
175
176//! Gets the average time in miliseconds of triangle collisions
177float btGImpactCollisionAlgorithm::getAverageTriangleCollisionTime()
178{
179        if(g_count_triangle_collision == 0) return 0;
180
181        float avgtime = g_accum_triangle_collision_time;
182        avgtime /= (float)g_count_triangle_collision;
183
184        g_accum_triangle_collision_time = 0;
185        g_count_triangle_collision = 0;
186
187        return avgtime;
188}
189
190#endif //TRI_COLLISION_PROFILING
191
192
193
194btGImpactCollisionAlgorithm::btGImpactCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
195: btActivatingCollisionAlgorithm(ci,body0,body1)
196{
197        m_manifoldPtr = NULL;
198        m_convex_algorithm = NULL;
199}
200
201btGImpactCollisionAlgorithm::~btGImpactCollisionAlgorithm()
202{
203        clearCache();
204}
205
206
207
208
209
210void btGImpactCollisionAlgorithm::addContactPoint(btCollisionObject * body0,
211                                btCollisionObject * body1,
212                                const btVector3 & point,
213                                const btVector3 & normal,
214                                btScalar distance)
215{
216        m_resultOut->setShapeIdentifiers(m_part0,m_triface0,m_part1,m_triface1);
217        checkManifold(body0,body1);
218        m_resultOut->addContactPoint(normal,point,distance);
219}
220
221
222void btGImpactCollisionAlgorithm::shape_vs_shape_collision(
223                                          btCollisionObject * body0,
224                                          btCollisionObject * body1,
225                                          btCollisionShape * shape0,
226                                          btCollisionShape * shape1)
227{
228
229        btCollisionShape* tmpShape0 = body0->getCollisionShape();
230        btCollisionShape* tmpShape1 = body1->getCollisionShape();
231       
232        body0->internalSetTemporaryCollisionShape(shape0);
233        body1->internalSetTemporaryCollisionShape(shape1);
234
235        {
236                btCollisionAlgorithm* algor = newAlgorithm(body0,body1);
237                // post :       checkManifold is called
238
239                m_resultOut->setShapeIdentifiers(m_part0,m_triface0,m_part1,m_triface1);
240
241                algor->processCollision(body0,body1,*m_dispatchInfo,m_resultOut);
242
243                algor->~btCollisionAlgorithm();
244                m_dispatcher->freeCollisionAlgorithm(algor);
245        }
246
247        body0->internalSetTemporaryCollisionShape(tmpShape0);
248        body1->internalSetTemporaryCollisionShape(tmpShape1);
249}
250
251void btGImpactCollisionAlgorithm::convex_vs_convex_collision(
252                                          btCollisionObject * body0,
253                                          btCollisionObject * body1,
254                                          btCollisionShape * shape0,
255                                          btCollisionShape * shape1)
256{
257
258        btCollisionShape* tmpShape0 = body0->getCollisionShape();
259        btCollisionShape* tmpShape1 = body1->getCollisionShape();
260       
261        body0->internalSetTemporaryCollisionShape(shape0);
262        body1->internalSetTemporaryCollisionShape(shape1);
263
264
265        m_resultOut->setShapeIdentifiers(m_part0,m_triface0,m_part1,m_triface1);
266
267        checkConvexAlgorithm(body0,body1);
268        m_convex_algorithm->processCollision(body0,body1,*m_dispatchInfo,m_resultOut);
269
270        body0->internalSetTemporaryCollisionShape(tmpShape0);
271        body1->internalSetTemporaryCollisionShape(tmpShape1);
272
273}
274
275
276
277
278void btGImpactCollisionAlgorithm::gimpact_vs_gimpact_find_pairs(
279                                          const btTransform & trans0,
280                                          const btTransform & trans1,
281                                          btGImpactShapeInterface * shape0,
282                                          btGImpactShapeInterface * shape1,btPairSet & pairset)
283{
284        if(shape0->hasBoxSet() && shape1->hasBoxSet())
285        {
286                btGImpactBoxSet::find_collision(shape0->getBoxSet(),trans0,shape1->getBoxSet(),trans1,pairset);
287        }
288        else
289        {
290                btAABB boxshape0;
291                btAABB boxshape1;
292                int i = shape0->getNumChildShapes();
293
294                while(i--)
295                {
296                        shape0->getChildAabb(i,trans0,boxshape0.m_min,boxshape0.m_max);
297
298                        int j = shape1->getNumChildShapes();
299                        while(j--)
300                        {
301                                shape1->getChildAabb(i,trans1,boxshape1.m_min,boxshape1.m_max);
302
303                                if(boxshape1.has_collision(boxshape0))
304                                {
305                                        pairset.push_pair(i,j);
306                                }
307                        }
308                }
309        }
310
311
312}
313
314
315void btGImpactCollisionAlgorithm::gimpact_vs_shape_find_pairs(
316                                          const btTransform & trans0,
317                                          const btTransform & trans1,
318                                          btGImpactShapeInterface * shape0,
319                                          btCollisionShape * shape1,
320                                          btAlignedObjectArray<int> & collided_primitives)
321{
322
323        btAABB boxshape;
324
325
326        if(shape0->hasBoxSet())
327        {
328                btTransform trans1to0 = trans0.inverse();
329                trans1to0 *= trans1;
330
331                shape1->getAabb(trans1to0,boxshape.m_min,boxshape.m_max);
332
333                shape0->getBoxSet()->boxQuery(boxshape, collided_primitives);
334        }
335        else
336        {
337                shape1->getAabb(trans1,boxshape.m_min,boxshape.m_max);
338
339                btAABB boxshape0;
340                int i = shape0->getNumChildShapes();
341
342                while(i--)
343                {
344                        shape0->getChildAabb(i,trans0,boxshape0.m_min,boxshape0.m_max);
345
346                        if(boxshape.has_collision(boxshape0))
347                        {
348                                collided_primitives.push_back(i);
349                        }
350                }
351
352        }
353
354}
355
356
357void btGImpactCollisionAlgorithm::collide_gjk_triangles(btCollisionObject * body0,
358                                  btCollisionObject * body1,
359                                  btGImpactMeshShapePart * shape0,
360                                  btGImpactMeshShapePart * shape1,
361                                  const int * pairs, int pair_count)
362{
363        btTriangleShapeEx tri0;
364        btTriangleShapeEx tri1;
365
366        shape0->lockChildShapes();
367        shape1->lockChildShapes();
368
369        const int * pair_pointer = pairs;
370
371        while(pair_count--)
372        {
373
374                m_triface0 = *(pair_pointer);
375                m_triface1 = *(pair_pointer+1);
376                pair_pointer+=2;
377
378
379
380                shape0->getBulletTriangle(m_triface0,tri0);
381                shape1->getBulletTriangle(m_triface1,tri1);
382
383
384                //collide two convex shapes
385                if(tri0.overlap_test_conservative(tri1))
386                {
387                        convex_vs_convex_collision(body0,body1,&tri0,&tri1);
388                }
389
390        }
391
392        shape0->unlockChildShapes();
393        shape1->unlockChildShapes();
394}
395
396void btGImpactCollisionAlgorithm::collide_sat_triangles(btCollisionObject * body0,
397                                          btCollisionObject * body1,
398                                          btGImpactMeshShapePart * shape0,
399                                          btGImpactMeshShapePart * shape1,
400                                          const int * pairs, int pair_count)
401{
402        btTransform orgtrans0 = body0->getWorldTransform();
403        btTransform orgtrans1 = body1->getWorldTransform();
404
405        btPrimitiveTriangle ptri0;
406        btPrimitiveTriangle ptri1;
407        GIM_TRIANGLE_CONTACT contact_data;
408
409        shape0->lockChildShapes();
410        shape1->lockChildShapes();
411
412        const int * pair_pointer = pairs;
413
414        while(pair_count--)
415        {
416
417                m_triface0 = *(pair_pointer);
418                m_triface1 = *(pair_pointer+1);
419                pair_pointer+=2;
420
421
422                shape0->getPrimitiveTriangle(m_triface0,ptri0);
423                shape1->getPrimitiveTriangle(m_triface1,ptri1);
424
425                #ifdef TRI_COLLISION_PROFILING
426                bt_begin_gim02_tri_time();
427                #endif
428
429                ptri0.applyTransform(orgtrans0);
430                ptri1.applyTransform(orgtrans1);
431
432
433                //build planes
434                ptri0.buildTriPlane();
435                ptri1.buildTriPlane();
436                // test conservative
437
438
439
440                if(ptri0.overlap_test_conservative(ptri1))
441                {
442                        if(ptri0.find_triangle_collision_clip_method(ptri1,contact_data))
443                        {
444
445                                int j = contact_data.m_point_count;
446                                while(j--)
447                                {
448
449                                        addContactPoint(body0, body1,
450                                                                contact_data.m_points[j],
451                                                                contact_data.m_separating_normal,
452                                                                -contact_data.m_penetration_depth);
453                                }
454                        }
455                }
456
457                #ifdef TRI_COLLISION_PROFILING
458                bt_end_gim02_tri_time();
459                #endif
460
461        }
462
463        shape0->unlockChildShapes();
464        shape1->unlockChildShapes();
465
466}
467
468
469void btGImpactCollisionAlgorithm::gimpact_vs_gimpact(
470                                                btCollisionObject * body0,
471                                                btCollisionObject * body1,
472                                                btGImpactShapeInterface * shape0,
473                                                btGImpactShapeInterface * shape1)
474{
475
476        if(shape0->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE)
477        {
478                btGImpactMeshShape * meshshape0 = static_cast<btGImpactMeshShape *>(shape0);
479                m_part0 = meshshape0->getMeshPartCount();
480
481                while(m_part0--)
482                {
483                        gimpact_vs_gimpact(body0,body1,meshshape0->getMeshPart(m_part0),shape1);
484                }
485
486                return;
487        }
488
489        if(shape1->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE)
490        {
491                btGImpactMeshShape * meshshape1 = static_cast<btGImpactMeshShape *>(shape1);
492                m_part1 = meshshape1->getMeshPartCount();
493
494                while(m_part1--)
495                {
496
497                        gimpact_vs_gimpact(body0,body1,shape0,meshshape1->getMeshPart(m_part1));
498
499                }
500
501                return;
502        }
503
504
505        btTransform orgtrans0 = body0->getWorldTransform();
506        btTransform orgtrans1 = body1->getWorldTransform();
507
508        btPairSet pairset;
509
510        gimpact_vs_gimpact_find_pairs(orgtrans0,orgtrans1,shape0,shape1,pairset);
511
512        if(pairset.size()== 0) return;
513
514        if(shape0->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART &&
515                shape1->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART)
516        {
517                btGImpactMeshShapePart * shapepart0 = static_cast<btGImpactMeshShapePart * >(shape0);
518                btGImpactMeshShapePart * shapepart1 = static_cast<btGImpactMeshShapePart * >(shape1);
519                //specialized function
520                #ifdef BULLET_TRIANGLE_COLLISION
521                collide_gjk_triangles(body0,body1,shapepart0,shapepart1,&pairset[0].m_index1,pairset.size());
522                #else
523                collide_sat_triangles(body0,body1,shapepart0,shapepart1,&pairset[0].m_index1,pairset.size());
524                #endif
525
526                return;
527        }
528
529        //general function
530
531        shape0->lockChildShapes();
532        shape1->lockChildShapes();
533
534        GIM_ShapeRetriever retriever0(shape0);
535        GIM_ShapeRetriever retriever1(shape1);
536
537        bool child_has_transform0 = shape0->childrenHasTransform();
538        bool child_has_transform1 = shape1->childrenHasTransform();
539
540        int i = pairset.size();
541        while(i--)
542        {
543                GIM_PAIR * pair = &pairset[i];
544                m_triface0 = pair->m_index1;
545                m_triface1 = pair->m_index2;
546                btCollisionShape * colshape0 = retriever0.getChildShape(m_triface0);
547                btCollisionShape * colshape1 = retriever1.getChildShape(m_triface1);
548
549                if(child_has_transform0)
550                {
551                        body0->setWorldTransform(orgtrans0*shape0->getChildTransform(m_triface0));
552                }
553
554                if(child_has_transform1)
555                {
556                        body1->setWorldTransform(orgtrans1*shape1->getChildTransform(m_triface1));
557                }
558
559                //collide two convex shapes
560                convex_vs_convex_collision(body0,body1,colshape0,colshape1);
561
562
563                if(child_has_transform0)
564                {
565                        body0->setWorldTransform(orgtrans0);
566                }
567
568                if(child_has_transform1)
569                {
570                        body1->setWorldTransform(orgtrans1);
571                }
572
573        }
574
575        shape0->unlockChildShapes();
576        shape1->unlockChildShapes();
577}
578
579void btGImpactCollisionAlgorithm::gimpact_vs_shape(btCollisionObject * body0,
580                                  btCollisionObject * body1,
581                                  btGImpactShapeInterface * shape0,
582                                  btCollisionShape * shape1,bool swapped)
583{
584        if(shape0->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE)
585        {
586                btGImpactMeshShape * meshshape0 = static_cast<btGImpactMeshShape *>(shape0);
587                int& part = swapped ? m_part1 : m_part0;
588                part = meshshape0->getMeshPartCount();
589
590                while(part--)
591                {
592
593                        gimpact_vs_shape(body0,
594                                  body1,
595                                  meshshape0->getMeshPart(part),
596                                  shape1,swapped);
597
598                }
599
600                return;
601        }
602
603        #ifdef GIMPACT_VS_PLANE_COLLISION
604        if(shape0->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART &&
605                shape1->getShapeType() == STATIC_PLANE_PROXYTYPE)
606        {
607                btGImpactMeshShapePart * shapepart = static_cast<btGImpactMeshShapePart *>(shape0);
608                btStaticPlaneShape * planeshape = static_cast<btStaticPlaneShape * >(shape1);
609                gimpacttrimeshpart_vs_plane_collision(body0,body1,shapepart,planeshape,swapped);
610                return;
611        }
612
613        #endif
614
615
616
617        if(shape1->isCompound())
618        {
619                btCompoundShape * compoundshape = static_cast<btCompoundShape *>(shape1);
620                gimpact_vs_compoundshape(body0,body1,shape0,compoundshape,swapped);
621                return;
622        }
623        else if(shape1->isConcave())
624        {
625                btConcaveShape * concaveshape = static_cast<btConcaveShape *>(shape1);
626                gimpact_vs_concave(body0,body1,shape0,concaveshape,swapped);
627                return;
628        }
629
630
631        btTransform orgtrans0 = body0->getWorldTransform();
632
633        btTransform orgtrans1 = body1->getWorldTransform();
634
635        btAlignedObjectArray<int> collided_results;
636
637        gimpact_vs_shape_find_pairs(orgtrans0,orgtrans1,shape0,shape1,collided_results);
638
639        if(collided_results.size() == 0) return;
640
641
642        shape0->lockChildShapes();
643
644        GIM_ShapeRetriever retriever0(shape0);
645
646
647        bool child_has_transform0 = shape0->childrenHasTransform();
648
649
650        int i = collided_results.size();
651
652        while(i--)
653        {
654                int child_index = collided_results[i];
655        if(swapped)
656                m_triface1 = child_index;
657        else
658            m_triface0 = child_index;
659
660                btCollisionShape * colshape0 = retriever0.getChildShape(child_index);
661
662                if(child_has_transform0)
663                {
664                        body0->setWorldTransform(orgtrans0*shape0->getChildTransform(child_index));
665                }
666
667                //collide two shapes
668                if(swapped)
669                {
670                        shape_vs_shape_collision(body1,body0,shape1,colshape0);
671                }
672                else
673                {
674                        shape_vs_shape_collision(body0,body1,colshape0,shape1);
675                }
676
677                //restore transforms
678                if(child_has_transform0)
679                {
680                        body0->setWorldTransform(orgtrans0);
681                }
682
683        }
684
685        shape0->unlockChildShapes();
686
687}
688
689void btGImpactCollisionAlgorithm::gimpact_vs_compoundshape(btCollisionObject * body0,
690                                  btCollisionObject * body1,
691                                  btGImpactShapeInterface * shape0,
692                                  btCompoundShape * shape1,bool swapped)
693{
694        btTransform orgtrans1 = body1->getWorldTransform();
695
696        int i = shape1->getNumChildShapes();
697        while(i--)
698        {
699
700                btCollisionShape * colshape1 = shape1->getChildShape(i);
701                btTransform childtrans1 = orgtrans1*shape1->getChildTransform(i);
702
703                body1->setWorldTransform(childtrans1);
704
705                //collide child shape
706                gimpact_vs_shape(body0, body1,
707                                          shape0,colshape1,swapped);
708
709
710                //restore transforms
711                body1->setWorldTransform(orgtrans1);
712        }
713}
714
715void btGImpactCollisionAlgorithm::gimpacttrimeshpart_vs_plane_collision(
716                                          btCollisionObject * body0,
717                                          btCollisionObject * body1,
718                                          btGImpactMeshShapePart * shape0,
719                                          btStaticPlaneShape * shape1,bool swapped)
720{
721
722
723        btTransform orgtrans0 = body0->getWorldTransform();
724        btTransform orgtrans1 = body1->getWorldTransform();
725
726        btPlaneShape * planeshape = static_cast<btPlaneShape *>(shape1);
727        btVector4 plane;
728        planeshape->get_plane_equation_transformed(orgtrans1,plane);
729
730        //test box against plane
731
732        btAABB tribox;
733        shape0->getAabb(orgtrans0,tribox.m_min,tribox.m_max);
734        tribox.increment_margin(planeshape->getMargin());
735
736        if( tribox.plane_classify(plane)!= BT_CONST_COLLIDE_PLANE) return;
737
738        shape0->lockChildShapes();
739
740        btScalar margin = shape0->getMargin() + planeshape->getMargin();
741
742        btVector3 vertex;
743        int vi = shape0->getVertexCount();
744        while(vi--)
745        {
746                shape0->getVertex(vi,vertex);
747                vertex = orgtrans0(vertex);
748
749                btScalar distance = vertex.dot(plane) - plane[3] - margin;
750
751                if(distance<0.0)//add contact
752                {
753                        if(swapped)
754                        {
755                                addContactPoint(body1, body0,
756                                        vertex,
757                                        -plane,
758                                        distance);
759                        }
760                        else
761                        {
762                                addContactPoint(body0, body1,
763                                        vertex,
764                                        plane,
765                                        distance);
766                        }
767                }
768        }
769
770        shape0->unlockChildShapes();
771}
772
773
774
775
776class btGImpactTriangleCallback: public btTriangleCallback
777{
778public:
779        btGImpactCollisionAlgorithm * algorithm;
780        btCollisionObject * body0;
781        btCollisionObject * body1;
782        btGImpactShapeInterface * gimpactshape0;
783        bool swapped;
784        btScalar margin;
785
786        virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex)
787        {
788                btTriangleShapeEx tri1(triangle[0],triangle[1],triangle[2]);
789                tri1.setMargin(margin);
790        if(swapped)
791        {
792            algorithm->setPart0(partId);
793            algorithm->setFace0(triangleIndex);
794        }
795        else
796        {
797            algorithm->setPart1(partId);
798            algorithm->setFace1(triangleIndex);
799        }
800                algorithm->gimpact_vs_shape(
801                                                        body0,body1,gimpactshape0,&tri1,swapped);
802        }
803};
804
805
806
807
808void btGImpactCollisionAlgorithm::gimpact_vs_concave(
809                                  btCollisionObject * body0,
810                                  btCollisionObject * body1,
811                                  btGImpactShapeInterface * shape0,
812                                  btConcaveShape * shape1,bool swapped)
813{
814        //create the callback
815        btGImpactTriangleCallback tricallback;
816        tricallback.algorithm = this;
817        tricallback.body0 = body0;
818        tricallback.body1 = body1;
819        tricallback.gimpactshape0 = shape0;
820        tricallback.swapped = swapped;
821        tricallback.margin = shape1->getMargin();
822
823        //getting the trimesh AABB
824        btTransform gimpactInConcaveSpace;
825
826        gimpactInConcaveSpace = body1->getWorldTransform().inverse() * body0->getWorldTransform();
827
828        btVector3 minAABB,maxAABB;
829        shape0->getAabb(gimpactInConcaveSpace,minAABB,maxAABB);
830
831        shape1->processAllTriangles(&tricallback,minAABB,maxAABB);
832
833}
834
835
836
837void btGImpactCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
838{
839    clearCache();
840
841    m_resultOut = resultOut;
842        m_dispatchInfo = &dispatchInfo;
843    btGImpactShapeInterface * gimpactshape0;
844    btGImpactShapeInterface * gimpactshape1;
845
846        if (body0->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE)
847        {
848                gimpactshape0 = static_cast<btGImpactShapeInterface *>(body0->getCollisionShape());
849
850                if( body1->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE )
851                {
852                        gimpactshape1 = static_cast<btGImpactShapeInterface *>(body1->getCollisionShape());
853
854                        gimpact_vs_gimpact(body0,body1,gimpactshape0,gimpactshape1);
855                }
856                else
857                {
858                        gimpact_vs_shape(body0,body1,gimpactshape0,body1->getCollisionShape(),false);
859                }
860
861        }
862        else if (body1->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE )
863        {
864                gimpactshape1 = static_cast<btGImpactShapeInterface *>(body1->getCollisionShape());
865
866                gimpact_vs_shape(body1,body0,gimpactshape1,body0->getCollisionShape(),true);
867        }
868}
869
870
871btScalar btGImpactCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
872{
873        return 1.f;
874
875}
876
877///////////////////////////////////// REGISTERING ALGORITHM //////////////////////////////////////////////
878
879btGImpactCollisionAlgorithm::CreateFunc g_gimpact_cf;
880
881//! Use this function for register the algorithm externally
882void btGImpactCollisionAlgorithm::registerAlgorithm(btCollisionDispatcher * dispatcher)
883{
884
885        int i;
886
887        for ( i = 0;i < MAX_BROADPHASE_COLLISION_TYPES ;i++ )
888        {
889                dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,i ,&g_gimpact_cf);
890        }
891
892        for ( i = 0;i < MAX_BROADPHASE_COLLISION_TYPES ;i++ )
893        {
894                dispatcher->registerCollisionCreateFunc(i,GIMPACT_SHAPE_PROXYTYPE ,&g_gimpact_cf);
895        }
896
897}
Note: See TracBrowser for help on using the repository browser.