Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/bullet/BulletCollision/Gimpact/gim_box_collision.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: 16.4 KB
Line 
1#ifndef GIM_BOX_COLLISION_H_INCLUDED
2#define GIM_BOX_COLLISION_H_INCLUDED
3
4/*! \file gim_box_collision.h
5\author Francisco Len Nßjera
6*/
7/*
8-----------------------------------------------------------------------------
9This source file is part of GIMPACT Library.
10
11For the latest info, see http://gimpact.sourceforge.net/
12
13Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
14email: projectileman@yahoo.com
15
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of EITHER:
18   (1) The GNU Lesser General Public License as published by the Free
19       Software Foundation; either version 2.1 of the License, or (at
20       your option) any later version. The text of the GNU Lesser
21       General Public License is included with this library in the
22       file GIMPACT-LICENSE-LGPL.TXT.
23   (2) The BSD-style license that is included with this library in
24       the file GIMPACT-LICENSE-BSD.TXT.
25   (3) The zlib/libpng license that is included with this library in
26       the file GIMPACT-LICENSE-ZLIB.TXT.
27
28 This library is distributed in the hope that it will be useful,
29 but WITHOUT ANY WARRANTY; without even the implied warranty of
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
31 GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
32
33-----------------------------------------------------------------------------
34*/
35#include "gim_basic_geometry_operations.h"
36#include "LinearMath/btTransform.h"
37
38/*! \defgroup BOUND_AABB_OPERATIONS
39*/
40//! @{
41
42
43//SIMD_FORCE_INLINE bool test_cross_edge_box(
44//      const btVector3 & edge,
45//      const btVector3 & absolute_edge,
46//      const btVector3 & pointa,
47//      const btVector3 & pointb, const btVector3 & extend,
48//      int dir_index0,
49//      int dir_index1
50//      int component_index0,
51//      int component_index1)
52//{
53//      // dir coords are -z and y
54//
55//      const btScalar dir0 = -edge[dir_index0];
56//      const btScalar dir1 = edge[dir_index1];
57//      btScalar pmin = pointa[component_index0]*dir0 + pointa[component_index1]*dir1;
58//      btScalar pmax = pointb[component_index0]*dir0 + pointb[component_index1]*dir1;
59//      //find minmax
60//      if(pmin>pmax)
61//      {
62//              GIM_SWAP_NUMBERS(pmin,pmax);
63//      }
64//      //find extends
65//      const btScalar rad = extend[component_index0] * absolute_edge[dir_index0] +
66//                                      extend[component_index1] * absolute_edge[dir_index1];
67//
68//      if(pmin>rad || -rad>pmax) return false;
69//      return true;
70//}
71//
72//SIMD_FORCE_INLINE bool test_cross_edge_box_X_axis(
73//      const btVector3 & edge,
74//      const btVector3 & absolute_edge,
75//      const btVector3 & pointa,
76//      const btVector3 & pointb, btVector3 & extend)
77//{
78//
79//      return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,2,1,1,2);
80//}
81//
82//
83//SIMD_FORCE_INLINE bool test_cross_edge_box_Y_axis(
84//      const btVector3 & edge,
85//      const btVector3 & absolute_edge,
86//      const btVector3 & pointa,
87//      const btVector3 & pointb, btVector3 & extend)
88//{
89//
90//      return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,0,2,2,0);
91//}
92//
93//SIMD_FORCE_INLINE bool test_cross_edge_box_Z_axis(
94//      const btVector3 & edge,
95//      const btVector3 & absolute_edge,
96//      const btVector3 & pointa,
97//      const btVector3 & pointb, btVector3 & extend)
98//{
99//
100//      return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,1,0,0,1);
101//}
102
103#define TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,i_dir_0,i_dir_1,i_comp_0,i_comp_1)\
104{\
105        const btScalar dir0 = -edge[i_dir_0];\
106        const btScalar dir1 = edge[i_dir_1];\
107        btScalar pmin = pointa[i_comp_0]*dir0 + pointa[i_comp_1]*dir1;\
108        btScalar pmax = pointb[i_comp_0]*dir0 + pointb[i_comp_1]*dir1;\
109        if(pmin>pmax)\
110        {\
111                GIM_SWAP_NUMBERS(pmin,pmax); \
112        }\
113        const btScalar abs_dir0 = absolute_edge[i_dir_0];\
114        const btScalar abs_dir1 = absolute_edge[i_dir_1];\
115        const btScalar rad = _extend[i_comp_0] * abs_dir0 + _extend[i_comp_1] * abs_dir1;\
116        if(pmin>rad || -rad>pmax) return false;\
117}\
118
119
120#define TEST_CROSS_EDGE_BOX_X_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\
121{\
122        TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,2,1,1,2);\
123}\
124
125#define TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\
126{\
127        TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,0,2,2,0);\
128}\
129
130#define TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\
131{\
132        TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,1,0,0,1);\
133}\
134
135
136
137//!  Class for transforming a model1 to the space of model0
138class GIM_BOX_BOX_TRANSFORM_CACHE
139{
140public:
141    btVector3  m_T1to0;//!< Transforms translation of model1 to model 0
142        btMatrix3x3 m_R1to0;//!< Transforms Rotation of model1 to model 0, equal  to R0' * R1
143        btMatrix3x3 m_AR;//!< Absolute value of m_R1to0
144
145        SIMD_FORCE_INLINE void calc_absolute_matrix()
146        {
147                static const btVector3 vepsi(1e-6f,1e-6f,1e-6f);
148                m_AR[0] = vepsi + m_R1to0[0].absolute();
149                m_AR[1] = vepsi + m_R1to0[1].absolute();
150                m_AR[2] = vepsi + m_R1to0[2].absolute();
151        }
152
153        GIM_BOX_BOX_TRANSFORM_CACHE()
154        {
155        }
156
157
158        GIM_BOX_BOX_TRANSFORM_CACHE(mat4f  trans1_to_0)
159        {
160                COPY_MATRIX_3X3(m_R1to0,trans1_to_0)
161        MAT_GET_TRANSLATION(trans1_to_0,m_T1to0)
162                calc_absolute_matrix();
163        }
164
165        //! Calc the transformation relative  1 to 0. Inverts matrics by transposing
166        SIMD_FORCE_INLINE void calc_from_homogenic(const btTransform & trans0,const btTransform & trans1)
167        {
168
169                m_R1to0 = trans0.getBasis().transpose();
170                m_T1to0 = m_R1to0 * (-trans0.getOrigin());
171
172                m_T1to0 += m_R1to0*trans1.getOrigin();
173                m_R1to0 *= trans1.getBasis();
174
175                calc_absolute_matrix();
176        }
177
178        //! Calcs the full invertion of the matrices. Useful for scaling matrices
179        SIMD_FORCE_INLINE void calc_from_full_invert(const btTransform & trans0,const btTransform & trans1)
180        {
181                m_R1to0 = trans0.getBasis().inverse();
182                m_T1to0 = m_R1to0 * (-trans0.getOrigin());
183
184                m_T1to0 += m_R1to0*trans1.getOrigin();
185                m_R1to0 *= trans1.getBasis();
186
187                calc_absolute_matrix();
188        }
189
190        SIMD_FORCE_INLINE btVector3 transform(const btVector3 & point)
191        {
192                return btVector3(m_R1to0[0].dot(point) + m_T1to0.x(),
193                        m_R1to0[1].dot(point) + m_T1to0.y(),
194                        m_R1to0[2].dot(point) + m_T1to0.z());
195        }
196};
197
198
199#define BOX_PLANE_EPSILON 0.000001f
200
201//! Axis aligned box
202class GIM_AABB
203{
204public:
205        btVector3 m_min;
206        btVector3 m_max;
207
208        GIM_AABB()
209        {}
210
211
212        GIM_AABB(const btVector3 & V1,
213                         const btVector3 & V2,
214                         const btVector3 & V3)
215        {
216                m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]);
217                m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]);
218                m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]);
219
220                m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]);
221                m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]);
222                m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]);
223        }
224
225        GIM_AABB(const btVector3 & V1,
226                         const btVector3 & V2,
227                         const btVector3 & V3,
228                         GREAL margin)
229        {
230                m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]);
231                m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]);
232                m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]);
233
234                m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]);
235                m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]);
236                m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]);
237
238                m_min[0] -= margin;
239                m_min[1] -= margin;
240                m_min[2] -= margin;
241                m_max[0] += margin;
242                m_max[1] += margin;
243                m_max[2] += margin;
244        }
245
246        GIM_AABB(const GIM_AABB &other):
247                m_min(other.m_min),m_max(other.m_max)
248        {
249        }
250
251        GIM_AABB(const GIM_AABB &other,btScalar margin ):
252                m_min(other.m_min),m_max(other.m_max)
253        {
254                m_min[0] -= margin;
255                m_min[1] -= margin;
256                m_min[2] -= margin;
257                m_max[0] += margin;
258                m_max[1] += margin;
259                m_max[2] += margin;
260        }
261
262        SIMD_FORCE_INLINE void invalidate()
263        {
264                m_min[0] = G_REAL_INFINITY;
265                m_min[1] = G_REAL_INFINITY;
266                m_min[2] = G_REAL_INFINITY;
267                m_max[0] = -G_REAL_INFINITY;
268                m_max[1] = -G_REAL_INFINITY;
269                m_max[2] = -G_REAL_INFINITY;
270        }
271
272        SIMD_FORCE_INLINE void increment_margin(btScalar margin)
273        {
274                m_min[0] -= margin;
275                m_min[1] -= margin;
276                m_min[2] -= margin;
277                m_max[0] += margin;
278                m_max[1] += margin;
279                m_max[2] += margin;
280        }
281
282        SIMD_FORCE_INLINE void copy_with_margin(const GIM_AABB &other, btScalar margin)
283        {
284                m_min[0] = other.m_min[0] - margin;
285                m_min[1] = other.m_min[1] - margin;
286                m_min[2] = other.m_min[2] - margin;
287
288                m_max[0] = other.m_max[0] + margin;
289                m_max[1] = other.m_max[1] + margin;
290                m_max[2] = other.m_max[2] + margin;
291        }
292
293        template<typename CLASS_POINT>
294        SIMD_FORCE_INLINE void calc_from_triangle(
295                                                        const CLASS_POINT & V1,
296                                                        const CLASS_POINT & V2,
297                                                        const CLASS_POINT & V3)
298        {
299                m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]);
300                m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]);
301                m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]);
302
303                m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]);
304                m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]);
305                m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]);
306        }
307
308        template<typename CLASS_POINT>
309        SIMD_FORCE_INLINE void calc_from_triangle_margin(
310                                                        const CLASS_POINT & V1,
311                                                        const CLASS_POINT & V2,
312                                                        const CLASS_POINT & V3, btScalar margin)
313        {
314                m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]);
315                m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]);
316                m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]);
317
318                m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]);
319                m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]);
320                m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]);
321
322                m_min[0] -= margin;
323                m_min[1] -= margin;
324                m_min[2] -= margin;
325                m_max[0] += margin;
326                m_max[1] += margin;
327                m_max[2] += margin;
328        }
329
330        //! Apply a transform to an AABB
331        SIMD_FORCE_INLINE void appy_transform(const btTransform & trans)
332        {
333                btVector3 center = (m_max+m_min)*0.5f;
334                btVector3 extends = m_max - center;
335                // Compute new center
336                center = trans(center);
337
338                btVector3 textends(extends.dot(trans.getBasis().getRow(0).absolute()),
339                                 extends.dot(trans.getBasis().getRow(1).absolute()),
340                                 extends.dot(trans.getBasis().getRow(2).absolute()));
341
342                m_min = center - textends;
343                m_max = center + textends;
344        }
345
346        //! Merges a Box
347        SIMD_FORCE_INLINE void merge(const GIM_AABB & box)
348        {
349                m_min[0] = GIM_MIN(m_min[0],box.m_min[0]);
350                m_min[1] = GIM_MIN(m_min[1],box.m_min[1]);
351                m_min[2] = GIM_MIN(m_min[2],box.m_min[2]);
352
353                m_max[0] = GIM_MAX(m_max[0],box.m_max[0]);
354                m_max[1] = GIM_MAX(m_max[1],box.m_max[1]);
355                m_max[2] = GIM_MAX(m_max[2],box.m_max[2]);
356        }
357
358        //! Merges a point
359        template<typename CLASS_POINT>
360        SIMD_FORCE_INLINE void merge_point(const CLASS_POINT & point)
361        {
362                m_min[0] = GIM_MIN(m_min[0],point[0]);
363                m_min[1] = GIM_MIN(m_min[1],point[1]);
364                m_min[2] = GIM_MIN(m_min[2],point[2]);
365
366                m_max[0] = GIM_MAX(m_max[0],point[0]);
367                m_max[1] = GIM_MAX(m_max[1],point[1]);
368                m_max[2] = GIM_MAX(m_max[2],point[2]);
369        }
370
371        //! Gets the extend and center
372        SIMD_FORCE_INLINE void get_center_extend(btVector3 & center,btVector3 & extend)  const
373        {
374                center = (m_max+m_min)*0.5f;
375                extend = m_max - center;
376        }
377
378        //! Finds the intersecting box between this box and the other.
379        SIMD_FORCE_INLINE void find_intersection(const GIM_AABB & other, GIM_AABB & intersection)  const
380        {
381                intersection.m_min[0] = GIM_MAX(other.m_min[0],m_min[0]);
382                intersection.m_min[1] = GIM_MAX(other.m_min[1],m_min[1]);
383                intersection.m_min[2] = GIM_MAX(other.m_min[2],m_min[2]);
384
385                intersection.m_max[0] = GIM_MIN(other.m_max[0],m_max[0]);
386                intersection.m_max[1] = GIM_MIN(other.m_max[1],m_max[1]);
387                intersection.m_max[2] = GIM_MIN(other.m_max[2],m_max[2]);
388        }
389
390
391        SIMD_FORCE_INLINE bool has_collision(const GIM_AABB & other) const
392        {
393                if(m_min[0] > other.m_max[0] ||
394                   m_max[0] < other.m_min[0] ||
395                   m_min[1] > other.m_max[1] ||
396                   m_max[1] < other.m_min[1] ||
397                   m_min[2] > other.m_max[2] ||
398                   m_max[2] < other.m_min[2])
399                {
400                        return false;
401                }
402                return true;
403        }
404
405        /*! \brief Finds the Ray intersection parameter.
406        \param aabb Aligned box
407        \param vorigin A vec3f with the origin of the ray
408        \param vdir A vec3f with the direction of the ray
409        */
410        SIMD_FORCE_INLINE bool collide_ray(const btVector3 & vorigin,const btVector3 & vdir)
411        {
412                btVector3 extents,center;
413                this->get_center_extend(center,extents);;
414
415                btScalar Dx = vorigin[0] - center[0];
416                if(GIM_GREATER(Dx, extents[0]) && Dx*vdir[0]>=0.0f)     return false;
417                btScalar Dy = vorigin[1] - center[1];
418                if(GIM_GREATER(Dy, extents[1]) && Dy*vdir[1]>=0.0f)     return false;
419                btScalar Dz = vorigin[2] - center[2];
420                if(GIM_GREATER(Dz, extents[2]) && Dz*vdir[2]>=0.0f)     return false;
421
422
423                btScalar f = vdir[1] * Dz - vdir[2] * Dy;
424                if(btFabs(f) > extents[1]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[1])) return false;
425                f = vdir[2] * Dx - vdir[0] * Dz;
426                if(btFabs(f) > extents[0]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[0]))return false;
427                f = vdir[0] * Dy - vdir[1] * Dx;
428                if(btFabs(f) > extents[0]*btFabs(vdir[1]) + extents[1]*btFabs(vdir[0]))return false;
429                return true;
430        }
431
432
433        SIMD_FORCE_INLINE void projection_interval(const btVector3 & direction, btScalar &vmin, btScalar &vmax) const
434        {
435                btVector3 center = (m_max+m_min)*0.5f;
436                btVector3 extend = m_max-center;
437
438                btScalar _fOrigin =  direction.dot(center);
439                btScalar _fMaximumExtent = extend.dot(direction.absolute());
440                vmin = _fOrigin - _fMaximumExtent;
441                vmax = _fOrigin + _fMaximumExtent;
442        }
443
444        SIMD_FORCE_INLINE ePLANE_INTERSECTION_TYPE plane_classify(const btVector4 &plane) const
445        {
446                btScalar _fmin,_fmax;
447                this->projection_interval(plane,_fmin,_fmax);
448
449                if(plane[3] > _fmax + BOX_PLANE_EPSILON)
450                {
451                        return G_BACK_PLANE; // 0
452                }
453
454                if(plane[3]+BOX_PLANE_EPSILON >=_fmin)
455                {
456                        return G_COLLIDE_PLANE; //1
457                }
458                return G_FRONT_PLANE;//2
459        }
460
461        SIMD_FORCE_INLINE bool overlapping_trans_conservative(const GIM_AABB & box, btTransform & trans1_to_0)
462        {
463                GIM_AABB tbox = box;
464                tbox.appy_transform(trans1_to_0);
465                return has_collision(tbox);
466        }
467
468        //! transcache is the transformation cache from box to this AABB
469        SIMD_FORCE_INLINE bool overlapping_trans_cache(
470                const GIM_AABB & box,const GIM_BOX_BOX_TRANSFORM_CACHE & transcache, bool fulltest)
471        {
472
473                //Taken from OPCODE
474                btVector3 ea,eb;//extends
475                btVector3 ca,cb;//extends
476                get_center_extend(ca,ea);
477                box.get_center_extend(cb,eb);
478
479
480                btVector3 T;
481                btScalar t,t2;
482                int i;
483
484                // Class I : A's basis vectors
485                for(i=0;i<3;i++)
486                {
487                        T[i] =  transcache.m_R1to0[i].dot(cb) + transcache.m_T1to0[i] - ca[i];
488                        t = transcache.m_AR[i].dot(eb) + ea[i];
489                        if(GIM_GREATER(T[i], t))        return false;
490                }
491                // Class II : B's basis vectors
492                for(i=0;i<3;i++)
493                {
494                        t = MAT_DOT_COL(transcache.m_R1to0,T,i);
495                        t2 = MAT_DOT_COL(transcache.m_AR,ea,i) + eb[i];
496                        if(GIM_GREATER(t,t2))   return false;
497                }
498                // Class III : 9 cross products
499                if(fulltest)
500                {
501                        int j,m,n,o,p,q,r;
502                        for(i=0;i<3;i++)
503                        {
504                                m = (i+1)%3;
505                                n = (i+2)%3;
506                                o = i==0?1:0;
507                                p = i==2?1:2;
508                                for(j=0;j<3;j++)
509                                {
510                                        q = j==2?1:2;
511                                        r = j==0?1:0;
512                                        t = T[n]*transcache.m_R1to0[m][j] - T[m]*transcache.m_R1to0[n][j];
513                                        t2 = ea[o]*transcache.m_AR[p][j] + ea[p]*transcache.m_AR[o][j] +
514                                                eb[r]*transcache.m_AR[i][q] + eb[q]*transcache.m_AR[i][r];
515                                        if(GIM_GREATER(t,t2))   return false;
516                                }
517                        }
518                }
519                return true;
520        }
521
522        //! Simple test for planes.
523        SIMD_FORCE_INLINE bool collide_plane(
524                const btVector4 & plane)
525        {
526                ePLANE_INTERSECTION_TYPE classify = plane_classify(plane);
527                return (classify == G_COLLIDE_PLANE);
528        }
529
530        //! test for a triangle, with edges
531        SIMD_FORCE_INLINE bool collide_triangle_exact(
532                const btVector3 & p1,
533                const btVector3 & p2,
534                const btVector3 & p3,
535                const btVector4 & triangle_plane)
536        {
537                if(!collide_plane(triangle_plane)) return false;
538
539                btVector3 center,extends;
540                this->get_center_extend(center,extends);
541
542                const btVector3 v1(p1 - center);
543                const btVector3 v2(p2 - center);
544                const btVector3 v3(p3 - center);
545
546                //First axis
547                btVector3 diff(v2 - v1);
548                btVector3 abs_diff = diff.absolute();
549                //Test With X axis
550                TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v1,v3,extends);
551                //Test With Y axis
552                TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v1,v3,extends);
553                //Test With Z axis
554                TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v1,v3,extends);
555
556
557                diff = v3 - v2;
558                abs_diff = diff.absolute();
559                //Test With X axis
560                TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v2,v1,extends);
561                //Test With Y axis
562                TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v2,v1,extends);
563                //Test With Z axis
564                TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v2,v1,extends);
565
566                diff = v1 - v3;
567                abs_diff = diff.absolute();
568                //Test With X axis
569                TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v3,v2,extends);
570                //Test With Y axis
571                TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v3,v2,extends);
572                //Test With Z axis
573                TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v3,v2,extends);
574
575                return true;
576        }
577};
578
579
580//! Compairison of transformation objects
581SIMD_FORCE_INLINE bool btCompareTransformsEqual(const btTransform & t1,const btTransform & t2)
582{
583        if(!(t1.getOrigin() == t2.getOrigin()) ) return false;
584
585        if(!(t1.getBasis().getRow(0) == t2.getBasis().getRow(0)) ) return false;
586        if(!(t1.getBasis().getRow(1) == t2.getBasis().getRow(1)) ) return false;
587        if(!(t1.getBasis().getRow(2) == t2.getBasis().getRow(2)) ) return false;
588        return true;
589}
590
591
592//! @}
593
594#endif // GIM_BOX_COLLISION_H_INCLUDED
Note: See TracBrowser for help on using the repository browser.