Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/physics/src/bullet/BulletCollision/GIMPACT/btGeometryOperations.h @ 1983

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

Added Bullet physics engine.

  • Property svn:eol-style set to native
File size: 4.8 KB
Line 
1#ifndef BT_BASIC_GEOMETRY_OPERATIONS_H_INCLUDED
2#define BT_BASIC_GEOMETRY_OPERATIONS_H_INCLUDED
3
4/*! \file btGeometryOperations.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) 2007 Francisco Leon Najera. C.C. 80087371.
14email: projectileman@yahoo.com
15
16
17This software is provided 'as-is', without any express or implied warranty.
18In no event will the authors be held liable for any damages arising from the use of this software.
19Permission is granted to anyone to use this software for any purpose,
20including commercial applications, and to alter it and redistribute it freely,
21subject to the following restrictions:
22
231. 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.
242. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
253. This notice may not be removed or altered from any source distribution.
26*/
27
28#include "btBoxCollision.h"
29
30
31
32/*! \defgroup GEOMETRIC_OPERATIONS
33*/
34//! @{
35
36
37#define PLANEDIREPSILON 0.0000001f
38#define PARALELENORMALS 0.000001f
39
40
41#define BT_CLAMP(number,minval,maxval) (number<minval?minval:(number>maxval?maxval:number))
42
43/// Calc a plane from a triangle edge an a normal. plane is a vec4f
44SIMD_FORCE_INLINE void bt_edge_plane(const btVector3 & e1,const btVector3 &  e2, const btVector3 & normal,btVector4 & plane)
45{
46        btVector3 planenormal = (e2-e1).cross(normal);
47        planenormal.normalize();
48        plane.setValue(planenormal[0],planenormal[1],planenormal[2],e2.dot(planenormal));
49}
50
51
52
53//***************** SEGMENT and LINE FUNCTIONS **********************************///
54
55/*! Finds the closest point(cp) to (v) on a segment (e1,e2)
56 */
57SIMD_FORCE_INLINE void bt_closest_point_on_segment(
58        btVector3 & cp, const btVector3 & v,
59        const btVector3  &e1,const btVector3 &e2)
60{
61    btVector3 n = e2-e1;
62    cp = v - e1;
63        btScalar _scalar = cp.dot(n)/n.dot(n);
64        if(_scalar <0.0f)
65        {
66            cp = e1;
67        }
68        else if(_scalar >1.0f)
69        {
70            cp = e2;
71        }
72        else
73        {
74                cp = _scalar*n + e1;
75        }
76}
77
78
79//! line plane collision
80/*!
81*\return
82        -0  if the ray never intersects
83        -1 if the ray collides in front
84        -2 if the ray collides in back
85*/
86
87SIMD_FORCE_INLINE int bt_line_plane_collision(
88        const btVector4 & plane,
89        const btVector3 & vDir,
90        const btVector3 & vPoint,
91        btVector3 & pout,
92        btScalar &tparam,
93        btScalar tmin, btScalar tmax)
94{
95
96        btScalar _dotdir = vDir.dot(plane);
97
98        if(btFabs(_dotdir)<PLANEDIREPSILON)
99        {
100                tparam = tmax;
101            return 0;
102        }
103
104        btScalar _dis = bt_distance_point_plane(plane,vPoint);
105        char returnvalue = _dis<0.0f? 2:1;
106        tparam = -_dis/_dotdir;
107
108        if(tparam<tmin)
109        {
110                returnvalue = 0;
111                tparam = tmin;
112        }
113        else if(tparam>tmax)
114        {
115                returnvalue = 0;
116                tparam = tmax;
117        }
118        pout = tparam*vDir + vPoint;
119        return returnvalue;
120}
121
122
123//! Find closest points on segments
124SIMD_FORCE_INLINE void bt_segment_collision(
125        const btVector3 & vA1,
126        const btVector3 & vA2,
127        const btVector3 & vB1,
128        const btVector3 & vB2,
129        btVector3 & vPointA,
130        btVector3 & vPointB)
131{
132    btVector3 AD = vA2 - vA1;
133    btVector3 BD = vB2 - vB1;
134    btVector3 N = AD.cross(BD);
135    btScalar tp = N.length2();
136
137    btVector4 _M;//plane
138
139    if(tp<SIMD_EPSILON)//ARE PARALELE
140    {
141        //project B over A
142        bool invert_b_order = false;
143        _M[0] = vB1.dot(AD);
144        _M[1] = vB2.dot(AD);
145
146        if(_M[0]>_M[1])
147        {
148                invert_b_order  = true;
149                BT_SWAP_NUMBERS(_M[0],_M[1]);
150        }
151        _M[2] = vA1.dot(AD);
152        _M[3] = vA2.dot(AD);
153        //mid points
154        N[0] = (_M[0]+_M[1])*0.5f;
155        N[1] = (_M[2]+_M[3])*0.5f;
156
157        if(N[0]<N[1])
158        {
159                if(_M[1]<_M[2])
160                {
161                        vPointB = invert_b_order?vB1:vB2;
162                        vPointA = vA1;
163                }
164                else if(_M[1]<_M[3])
165                {
166                        vPointB = invert_b_order?vB1:vB2;
167                        bt_closest_point_on_segment(vPointA,vPointB,vA1,vA2);
168                }
169                else
170                {
171                        vPointA = vA2;
172                        bt_closest_point_on_segment(vPointB,vPointA,vB1,vB2);
173                }
174        }
175        else
176        {
177                if(_M[3]<_M[0])
178                {
179                        vPointB = invert_b_order?vB2:vB1;
180                        vPointA = vA2;
181                }
182                else if(_M[3]<_M[1])
183                {
184                        vPointA = vA2;
185                        bt_closest_point_on_segment(vPointB,vPointA,vB1,vB2);
186                }
187                else
188                {
189                        vPointB = invert_b_order?vB1:vB2;
190                        bt_closest_point_on_segment(vPointA,vPointB,vA1,vA2);
191                }
192        }
193        return;
194    }
195
196    N = N.cross(BD);
197    _M.setValue(N[0],N[1],N[2],vB1.dot(N));
198
199        // get point A as the plane collision point
200    bt_line_plane_collision(_M,AD,vA1,vPointA,tp,btScalar(0), btScalar(1));
201
202    /*Closest point on segment*/
203    vPointB = vPointA - vB1;
204        tp = vPointB.dot(BD);
205        tp/= BD.dot(BD);
206        tp = BT_CLAMP(tp,0.0f,1.0f);
207
208        vPointB = tp*BD + vB1;
209}
210
211
212
213//! @}
214
215
216#endif // GIM_VECTOR_H_INCLUDED
Note: See TracBrowser for help on using the repository browser.