1 #include "float_math.h"
9 /*----------------------------------------------------------------------
10 Copyright (c) 2004 Open Dynamics Framework Group
14 Redistribution and use in source and binary forms, with or without modification, are permitted provided
15 that the following conditions are met:
17 Redistributions of source code must retain the above copyright notice, this list of conditions
18 and the following disclaimer.
20 Redistributions in binary form must reproduce the above copyright notice,
21 this list of conditions and the following disclaimer in the documentation
22 and/or other materials provided with the distribution.
24 Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
25 be used to endorse or promote products derived from this software without specific prior written permission.
27 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
28 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29 DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
32 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 -----------------------------------------------------------------------*/
36 // http://codesuppository.blogspot.com
38 // mailto: jratcliff@infiniplex.net
40 // http://www.amillionpixels.us
43 #include "ConvexDecomposition.h"
44 #include "cd_vector.h"
49 #include "splitplane.h"
50 #include "meshvolume.h"
51 #include "concavity.h"
52 #include "bestfitobb.h"
53 #include "float_math.h"
54 #include "fitsphere.h"
60 using namespace ConvexDecomposition;
64 namespace ConvexDecomposition
71 FaceTri(const float *vertices,unsigned int i1,unsigned int i2,unsigned int i3)
73 mP1.Set( &vertices[i1*3] );
74 mP2.Set( &vertices[i2*3] );
75 mP3.Set( &vertices[i3*3] );
86 void addTri(VertexLookup vl,UintVector &list,const Vector3d &p1,const Vector3d &p2,const Vector3d &p3)
88 unsigned int i1 = Vl_getIndex(vl, p1.Ptr() );
89 unsigned int i2 = Vl_getIndex(vl, p2.Ptr() );
90 unsigned int i3 = Vl_getIndex(vl, p3.Ptr() );
92 // do *not* process degenerate triangles!
94 if ( i1 != i2 && i1 != i3 && i2 != i3 )
103 void calcConvexDecomposition(unsigned int vcount,
104 const float *vertices,
106 const unsigned int *indices,
107 ConvexDecompInterface *callback,
118 if ( depth < MAXDEPTH )
122 float c = computeConcavity( vcount, vertices, tcount, indices, callback, plane, volume );
126 masterVolume = volume;
129 float percent = (c*100.0f)/masterVolume;
131 if ( percent > CONCAVE_PERCENT ) // if great than 5% of the total volume is concave, go ahead and keep splitting.
138 if ( depth >= MAXDEPTH || !split )
147 desc.SetHullFlag(QF_TRIANGLES);
149 desc.mVcount = vcount;
150 desc.mVertices = vertices;
151 desc.mVertexStride = sizeof(float)*3;
153 HullError ret = hl.CreateConvexHull(desc,result);
158 ConvexResult r(result.mNumOutputVertices, result.mOutputVertices, result.mNumFaces, result.mIndices);
161 callback->ConvexDecompResult(r);
167 static unsigned int colors[8] =
179 static int count = 0;
183 if ( count == 8 ) count = 0;
185 assert( count >= 0 && count < 8 );
187 unsigned int color = colors[count];
189 const unsigned int *source = indices;
191 for (unsigned int i=0; i<tcount; i++)
194 unsigned int i1 = *source++;
195 unsigned int i2 = *source++;
196 unsigned int i3 = *source++;
198 FaceTri t(vertices, i1, i2, i3 );
200 callback->ConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(), t.mP3.Ptr(), color );
205 hl.ReleaseResult (result);
213 VertexLookup vfront = Vl_createVertexLookup();
214 VertexLookup vback = Vl_createVertexLookup();
217 bool showmesh = false;
225 for (float x=-1; x<1; x+=0.10f)
227 for (float y=0; y<1; y+=0.10f)
229 for (float z=-1; z<1; z+=0.04f)
231 float d = x*plane[0] + y*plane[1] + z*plane[2] + plane[3];
234 callback->ConvexDebugPoint(p.Ptr(), 0.02f, 0x00FF00);
236 callback->ConvexDebugPoint(p.Ptr(), 0.02f, 0xFF0000);
244 // ok..now we are going to 'split' all of the input triangles against this plane!
245 const unsigned int *source = indices;
246 for (unsigned int i=0; i<tcount; i++)
248 unsigned int i1 = *source++;
249 unsigned int i2 = *source++;
250 unsigned int i3 = *source++;
252 FaceTri t(vertices, i1, i2, i3 );
257 unsigned int fcount=0;
258 unsigned int bcount=0;
260 PlaneTriResult result;
262 result = planeTriIntersection(plane,t.mP1.Ptr(),sizeof(Vector3d),0.00001f,front[0].Ptr(),fcount,back[0].Ptr(),bcount );
264 if( fcount > 4 || bcount > 4 )
266 result = planeTriIntersection(plane,t.mP1.Ptr(),sizeof(Vector3d),0.00001f,front[0].Ptr(),fcount,back[0].Ptr(),bcount );
273 assert( fcount == 3 );
276 callback->ConvexDebugTri( front[0].Ptr(), front[1].Ptr(), front[2].Ptr(), 0x00FF00 );
280 addTri( vfront, ifront, front[0], front[1], front[2] );
287 assert( bcount == 3 );
290 callback->ConvexDebugTri( back[0].Ptr(), back[1].Ptr(), back[2].Ptr(), 0xFFFF00 );
294 addTri( vback, iback, back[0], back[1], back[2] );
301 assert( fcount >= 3 && fcount <= 4);
302 assert( bcount >= 3 && bcount <= 4);
306 addTri( vfront, ifront, front[0], front[1], front[2] );
307 addTri( vback, iback, back[0], back[1], back[2] );
312 addTri( vfront, ifront, front[0], front[2], front[3] );
317 addTri( vback, iback, back[0], back[2], back[3] );
324 callback->ConvexDebugTri( front[0].Ptr(), front[1].Ptr(), front[2].Ptr(), 0x00D000 );
325 callback->ConvexDebugTri( back[0].Ptr(), back[1].Ptr(), back[2].Ptr(), 0xD0D000 );
329 callback->ConvexDebugTri( front[0].Ptr(), front[2].Ptr(), front[3].Ptr(), 0x00D000 );
333 callback->ConvexDebugTri( back[0].Ptr(), back[2].Ptr(), back[3].Ptr(), 0xD0D000 );
341 // ok... here we recursively call
344 unsigned int vcount = Vl_getVcount(vfront);
345 const float *vertices = Vl_getVertices(vfront);
346 unsigned int tcount = ifront.size()/3;
348 calcConvexDecomposition(vcount, vertices, tcount, &ifront[0], callback, masterVolume, depth+1);
354 Vl_releaseVertexLookup(vfront);
358 unsigned int vcount = Vl_getVcount(vback);
359 const float *vertices = Vl_getVertices(vback);
360 unsigned int tcount = iback.size()/3;
362 calcConvexDecomposition(vcount, vertices, tcount, &iback[0], callback, masterVolume, depth+1);
367 Vl_releaseVertexLookup(vback);