Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Extras / GIMPACTUtils / btGImpactConvexDecompositionShape.cpp
1 /*
2 This source file is part of GIMPACT Library.
3
4 For the latest info, see http://gimpact.sourceforge.net/
5
6 Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
7 email: projectileman@yahoo.com
8
9
10 This software is provided 'as-is', without any express or implied warranty.
11 In no event will the authors be held liable for any damages arising from the use of this software.
12 Permission is granted to anyone to use this software for any purpose,
13 including commercial applications, and to alter it and redistribute it freely,
14 subject to the following restrictions:
15
16 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.
17 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
19 */
20
21 #include "btGImpactConvexDecompositionShape.h"
22 #include "BulletCollision/CollisionShapes/btConvexHullShape.h"
23
24 #include "ConvexBuilder.h"
25
26 class GIM_ConvexDecomposition : public ConvexDecomposition::ConvexDecompInterface
27 {
28 protected:
29         btGImpactConvexDecompositionShape * m_compoundShape;
30
31         btAlignedObjectArray<btCollisionShape*> m_convexShapes;
32
33
34 public:
35         int     mBaseCount;
36         int             mHullCount;
37         bool m_transformSubShapes;
38
39         GIM_ConvexDecomposition(btGImpactConvexDecompositionShape * compoundShape,bool transformSubShapes)
40         {
41                 mBaseCount = 0;
42                 mHullCount = 0;
43                 m_compoundShape = compoundShape;
44                 m_transformSubShapes = transformSubShapes;
45         }
46
47         virtual ~GIM_ConvexDecomposition()
48         {
49                 int i;
50                 for (i=0;i<m_convexShapes.size();i++)
51                 {
52                         btCollisionShape* shape = m_convexShapes[i];
53                         delete shape;
54                 }
55
56         }
57
58         virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult &result)
59         {
60
61                 //calc centroid, to shift vertices around center of mass
62                 btVector3 centroid(0,0,0);
63                 btAlignedObjectArray<btVector3> vertices;
64
65                 if(m_transformSubShapes)
66                 {
67
68                         //const unsigned int *src = result.mHullIndices;
69                         for (unsigned int i=0; i<result.mHullVcount; i++)
70                         {
71                                 btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]);
72
73                                 centroid += vertex;
74
75                         }
76                         centroid *= 1.f/(float(result.mHullVcount) );
77                 }
78
79                 // collect vertices
80                 for (unsigned int i=0; i<result.mHullVcount; i++)
81                 {
82                         btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]);
83
84                         if(m_transformSubShapes)
85                         {
86                                 vertex -= centroid ;
87                         }
88                         vertices.push_back(vertex);
89                 }
90
91                 // build convex shape
92
93                 btCollisionShape* convexShape = new btConvexHullShape(
94                                 &(vertices[0].getX()),vertices.size(),sizeof(btVector3));
95                 m_convexShapes.push_back(convexShape);
96
97                 convexShape->setMargin(m_compoundShape->getMargin());
98
99                 if(m_transformSubShapes)
100                 {
101                         btTransform trans;
102                         trans.setIdentity();
103                         trans.setOrigin(centroid);
104
105                         // add convex shape
106
107                         m_compoundShape->addChildShape(trans,convexShape);
108                 }
109                 else
110                 {
111                         btTransform trans;
112                         trans.setIdentity();
113                         //trans.setOrigin(centroid);
114
115                         // add convex shape
116
117                         m_compoundShape->addChildShape(trans,convexShape);
118
119                         //m_compoundShape->addChildShape(convexShape);
120                 }
121         }
122
123         void processDecomposition(int part)
124         {
125                 btGImpactMeshShapePart::TrimeshPrimitiveManager * trimeshInterface =
126                                 m_compoundShape->getTrimeshInterface(part);
127
128
129                 trimeshInterface->lock();
130
131                 //collect vertices
132                 btAlignedObjectArray<float> vertices;
133                 vertices.reserve(trimeshInterface->get_vertex_count()*3);
134
135                 for(int vi = 0;vi<trimeshInterface->get_vertex_count();vi++)
136                 {
137                         btVector3 vec;
138                         trimeshInterface->get_vertex(vi,vec);
139                         vertices.push_back(vec[0]);
140                         vertices.push_back(vec[1]);
141                         vertices.push_back(vec[2]);
142                 }
143
144
145                 //collect indices
146                 btAlignedObjectArray<unsigned int> indices;
147                 indices.reserve(trimeshInterface->get_primitive_count()*3);
148
149
150                 for(int i = 0;i<trimeshInterface->get_primitive_count();i++)
151                 {
152                         int i0, i1,i2;
153                         trimeshInterface->get_indices(i,i0,i1,i2);
154                         indices.push_back(i0);
155                         indices.push_back(i1);
156                         indices.push_back(i2);
157                 }
158
159                 trimeshInterface->unlock();
160
161
162
163                 unsigned int depth = 5;
164                 float cpercent     = 5;
165                 float ppercent     = 15;
166                 unsigned int maxv  = 16;
167                 float skinWidth    = 0.0f;
168
169
170                 ConvexDecomposition::DecompDesc desc;
171                 desc.mVcount       = trimeshInterface->get_vertex_count();
172                 desc.mVertices     = &vertices[0];
173                 desc.mTcount       = trimeshInterface->get_primitive_count();
174                 desc.mIndices      = &indices[0];
175                 desc.mDepth        = depth;
176                 desc.mCpercent     = cpercent;
177                 desc.mPpercent     = ppercent;
178                 desc.mMaxVertices  = maxv;
179                 desc.mSkinWidth    = skinWidth;
180                 desc.mCallback = this;
181
182                 //convexDecomposition.performConvexDecomposition(desc);
183
184                 ConvexBuilder cb(desc.mCallback);
185                 cb.process(desc);
186         }
187
188
189
190
191 };
192
193
194
195 void btGImpactConvexDecompositionShape::buildConvexDecomposition(bool transformSubShapes)
196 {
197
198         m_decomposition = new GIM_ConvexDecomposition(this,transformSubShapes);
199
200         int part_count = m_trimeshInterfaces.size();
201         for (int i = 0;i<part_count ;i++ )
202         {
203                 m_decomposition->processDecomposition(i);
204         }
205
206         postUpdate();
207 }
208
209 btGImpactConvexDecompositionShape::~btGImpactConvexDecompositionShape()
210 {
211         delete m_decomposition;
212 }
213 void btGImpactConvexDecompositionShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
214 {
215
216         int part_count = m_trimeshInterfaces.size();
217         for (int part = 0;part<part_count ;part++ )
218         {
219                 void * ptr = (void * )&m_trimeshInterfaces[part];
220
221                 btGImpactMeshShapePart::TrimeshPrimitiveManager * trimeshInterface =
222                         static_cast<btGImpactMeshShapePart::TrimeshPrimitiveManager *>(ptr);
223
224                 trimeshInterface->lock();
225
226                 btPrimitiveTriangle triangle;
227
228
229                 int i = trimeshInterface->get_primitive_count();
230                 while(i--)
231                 {
232                         trimeshInterface->get_primitive_triangle(i,triangle);
233                         callback->processTriangle(triangle.m_vertices,part,i);
234                 }
235
236                 trimeshInterface->unlock();
237         }
238
239
240 }