Imported Upstream version 2.81
[platform/upstream/libbullet.git] / src / BulletCollision / CollisionShapes / btTriangleMeshShape.cpp
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
4
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose, 
8 including commercial applications, and to alter it and redistribute it freely, 
9 subject to the following restrictions:
10
11 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.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15
16 #include "btTriangleMeshShape.h"
17 #include "LinearMath/btVector3.h"
18 #include "LinearMath/btQuaternion.h"
19 #include "btStridingMeshInterface.h"
20 #include "LinearMath/btAabbUtil2.h"
21 #include "BulletCollision/CollisionShapes/btCollisionMargin.h"
22
23
24 btTriangleMeshShape::btTriangleMeshShape(btStridingMeshInterface* meshInterface)
25 : btConcaveShape (), m_meshInterface(meshInterface)
26 {
27         m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;
28         if(meshInterface->hasPremadeAabb())
29         {
30                 meshInterface->getPremadeAabb(&m_localAabbMin, &m_localAabbMax);
31         }
32         else
33         {
34                 recalcLocalAabb();
35         }
36 }
37
38
39 btTriangleMeshShape::~btTriangleMeshShape()
40 {
41                 
42 }
43
44
45
46
47 void btTriangleMeshShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
48 {
49
50         btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin);
51         localHalfExtents += btVector3(getMargin(),getMargin(),getMargin());
52         btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin);
53         
54         btMatrix3x3 abs_b = trans.getBasis().absolute();  
55
56         btVector3 center = trans(localCenter);
57
58     btVector3 extent = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
59         aabbMin = center - extent;
60         aabbMax = center + extent;
61 }
62
63 void    btTriangleMeshShape::recalcLocalAabb()
64 {
65         for (int i=0;i<3;i++)
66         {
67                 btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
68                 vec[i] = btScalar(1.);
69                 btVector3 tmp = localGetSupportingVertex(vec);
70                 m_localAabbMax[i] = tmp[i]+m_collisionMargin;
71                 vec[i] = btScalar(-1.);
72                 tmp = localGetSupportingVertex(vec);
73                 m_localAabbMin[i] = tmp[i]-m_collisionMargin;
74         }
75 }
76
77
78
79 class SupportVertexCallback : public btTriangleCallback
80 {
81
82         btVector3 m_supportVertexLocal;
83 public:
84
85         btTransform     m_worldTrans;
86         btScalar m_maxDot;
87         btVector3 m_supportVecLocal;
88
89         SupportVertexCallback(const btVector3& supportVecWorld,const btTransform& trans)
90                 : m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)), m_worldTrans(trans) ,m_maxDot(btScalar(-BT_LARGE_FLOAT))
91                 
92         {
93                 m_supportVecLocal = supportVecWorld * m_worldTrans.getBasis();
94         }
95
96         virtual void processTriangle( btVector3* triangle,int partId, int triangleIndex)
97         {
98                 (void)partId;
99                 (void)triangleIndex;
100                 for (int i=0;i<3;i++)
101                 {
102                         btScalar dot = m_supportVecLocal.dot(triangle[i]);
103                         if (dot > m_maxDot)
104                         {
105                                 m_maxDot = dot;
106                                 m_supportVertexLocal = triangle[i];
107                         }
108                 }
109         }
110
111         btVector3 GetSupportVertexWorldSpace()
112         {
113                 return m_worldTrans(m_supportVertexLocal);
114         }
115
116         btVector3       GetSupportVertexLocal()
117         {
118                 return m_supportVertexLocal;
119         }
120
121 };
122
123         
124 void btTriangleMeshShape::setLocalScaling(const btVector3& scaling)
125 {
126         m_meshInterface->setScaling(scaling);
127         recalcLocalAabb();
128 }
129
130 const btVector3& btTriangleMeshShape::getLocalScaling() const
131 {
132         return m_meshInterface->getScaling();
133 }
134
135
136
137
138
139
140 //#define DEBUG_TRIANGLE_MESH
141
142
143
144 void    btTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
145 {
146                 struct FilteredCallback : public btInternalTriangleIndexCallback
147         {
148                 btTriangleCallback* m_callback;
149                 btVector3 m_aabbMin;
150                 btVector3 m_aabbMax;
151
152                 FilteredCallback(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax)
153                         :m_callback(callback),
154                         m_aabbMin(aabbMin),
155                         m_aabbMax(aabbMax)
156                 {
157                 }
158
159                 virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
160                 {
161                         if (TestTriangleAgainstAabb2(&triangle[0],m_aabbMin,m_aabbMax))
162                         {
163                                 //check aabb in triangle-space, before doing this
164                                 m_callback->processTriangle(triangle,partId,triangleIndex);
165                         }
166                         
167                 }
168
169         };
170
171         FilteredCallback filterCallback(callback,aabbMin,aabbMax);
172
173         m_meshInterface->InternalProcessAllTriangles(&filterCallback,aabbMin,aabbMax);
174 }
175
176
177
178
179
180 void    btTriangleMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
181 {
182         (void)mass;
183         //moving concave objects not supported
184         btAssert(0);
185         inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
186 }
187
188
189 btVector3 btTriangleMeshShape::localGetSupportingVertex(const btVector3& vec) const
190 {
191         btVector3 supportVertex;
192
193         btTransform ident;
194         ident.setIdentity();
195
196         SupportVertexCallback supportCallback(vec,ident);
197
198         btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
199         
200         processAllTriangles(&supportCallback,-aabbMax,aabbMax);
201                 
202         supportVertex = supportCallback.GetSupportVertexLocal();
203
204         return supportVertex;
205 }
206
207