AnimatLab  2
Test
BlOsgGeometry.cpp
1 #include "StdAfx.h"
2 #include <stdarg.h>
3 #include "BlJoint.h"
4 #include "BlMotorizedJoint.h"
5 #include "BlRigidBody.h"
6 #include "BlClassFactory.h"
7 #include "BlSimulator.h"
8 #include "BlOsgGeometry.h"
9 
10 namespace BulletAnimatSim
11 {
12  namespace Environment
13  {
14 
15 #pragma region CreateGeometry_Code
16 
17  btHeightfieldTerrainShape BULLET_PORT *CreateBtHeightField(osg::HeightField *osgHeightField, float fltSegWidth, float fltSegLength, float &fltMinHeight, float &fltMaxHeight, btScalar **aryHeightData)
18  {
19  //Lets create the height array.
20  fltMaxHeight = -10000;
21  fltMinHeight = 10000;
22  int iCols = osgHeightField->getNumColumns();
23  int iRows = osgHeightField->getNumRows();
24 
25  btScalar * heightfieldData = new btScalar[iCols*iRows];
26 
27  //For some reason the bullet height field rows and the osg heightfield rows are in reverse order.
28  for(int iOsgRow=0, iBtRow=(iRows-1); iOsgRow<iRows; iOsgRow++, iBtRow--)
29  for(int iOsgCol=0, iBtCol=(iCols-1); iOsgCol<iCols; iOsgCol++,iBtCol--)
30  {
31  float fltHeight = osgHeightField->getHeight(iOsgCol, iOsgRow);
32  heightfieldData[(iBtRow*iCols) + iOsgCol] = fltHeight;
33  if(fltHeight > fltMaxHeight)
34  fltMaxHeight = fltHeight;
35  if(fltHeight < fltMinHeight)
36  fltMinHeight = fltHeight;
37  }
38 
39 
40  btHeightfieldTerrainShape* heightFieldShape = new btHeightfieldTerrainShape(iCols, iRows, heightfieldData, 1, fltMinHeight, fltMaxHeight, 1, PHY_FLOAT , false);
41 
42  btVector3 localScaling(fltSegWidth, 1, fltSegLength);
43  heightFieldShape->setLocalScaling(localScaling);
44  heightFieldShape->setUseDiamondSubdivision(true);
45 
46  *aryHeightData = heightfieldData;
47 
48  return heightFieldShape;
49  }
50 
51  btConvexHullShape BULLET_PORT *OsgMeshToConvexHull(osg::Node *lpNode, bool bOptimize, float fltMargin)
52  {
53  btConvexHullShape *originalConvexShape = osgbCollision::btConvexHullCollisionShapeFromOSG(lpNode);
54 
55  if(fltMargin >= 0)
56  originalConvexShape->setMargin(fltMargin);
57 
58  btConvexHullShape* simplifiedConvexShape = NULL;
59  if(bOptimize)
60  {
61  //create a hull approximation
62  btShapeHull* hull = new btShapeHull(originalConvexShape);
63  btScalar margin = originalConvexShape->getMargin();
64  if(fltMargin < 0)
65  hull->buildHull(margin);
66  else
67  hull->buildHull(fltMargin);
68 
69  simplifiedConvexShape = new btConvexHullShape((const btScalar *) hull->getVertexPointer(),hull->numVertices());
70  }
71 
72  //For really simple meshes it seems like the "Simplified" version is actually larger than the original.
73  if(simplifiedConvexShape && originalConvexShape->getNumVertices() > simplifiedConvexShape->getNumVertices())
74  {
75  if(originalConvexShape)
76  delete originalConvexShape;
77 
78  return simplifiedConvexShape;
79  }
80  else
81  {
82  if(simplifiedConvexShape)
83  delete simplifiedConvexShape;
84 
85  return originalConvexShape;
86  }
87  }
88 
108  float BULLET_PORT OsgConvexHullVolume( osg::Node* node)
109  {
110  btConvexHullShape *lpHull = OsgConvexShrunkenHullCollisionShape(node);
111 
112  if(!lpHull)
113  return 0;
114 
115  btShapeHull sh( lpHull );
116  sh.buildHull( btScalar( 0. ) );
117  int nVerts( sh.numVertices () );
118  int nIdx( sh.numIndices() );
119  if( (nVerts <= 0) || (nIdx <= 0) )
120  return( 0 );
121 
122  const btVector3* bVerts( sh.getVertexPointer() );
123  const unsigned int* bIdx( sh.getIndexPointer() );
124 
125  osg::ref_ptr<osg::Vec3Array> v(new osg::Vec3Array);
126  v->resize( nVerts );
127  unsigned int idx;
128  for( idx = 0; idx < (unsigned int)nVerts; idx++ )
129  ( *v )[ idx ] = osgbCollision::asOsgVec3( bVerts[ idx ] );
130 
131  //Find centriod
132  float fltXSum = 0, fltYSum=0, fltZSum=0;
133  for( idx = 0; idx < (unsigned int)nVerts; idx++ )
134  {
135  fltXSum += (*v)[idx][0];
136  fltYSum += (*v)[idx][1];
137  fltZSum += (*v)[idx][2];
138  }
139 
140  //Find halway point between first and last vertex to use as the center of our pyrmaids.
141  //osg::Vec3 vCenterPoint = vFirst + ((vLast - vFirst)/2.0);
142  osg::Vec3 vCenterPoint( (fltXSum/nVerts), (fltYSum/nVerts), (fltZSum/nVerts)); // = vFirst + ((vLast - vFirst)/2.0);
143 
144  float fltTotalVolume = 0;
145  if(nIdx >= 3)
146  {
147  for( idx = 2; idx < (unsigned int)nIdx; idx+=3 )
148  {
149  unsigned int iIdx1 = bIdx[ idx-2 ];
150  osg::Vec3 v1 = (*v)[iIdx1];
151 
152  unsigned int iIdx2 = bIdx[ idx-1 ];
153  osg::Vec3 v2 = (*v)[iIdx2];
154 
155  unsigned int iIdx3 = bIdx[ idx-0 ];
156  osg::Vec3 v3 = (*v)[iIdx3];
157 
158  OsgAnimatSim::Visualization::OsgPyramid p(vCenterPoint, v1, v2, v3);
159 
160  fltTotalVolume += p.Volume();
161  }
162  }
163 
164  if(lpHull)
165  delete lpHull;
166 
167  return fltTotalVolume;
168  }
169 
182  btConvexHullShape* OsgConvexShrunkenHullCollisionShape( osg::Node* node )
183  {
184  btConvexHullShape *lpHull = OsgMeshToConvexHull(node, true, 0);
185 
186  const btVector3 *aryPoints = lpHull->getUnscaledPoints();
187  int iVerts = lpHull->getNumVertices();
188 
189  // Convert verts to array of Bullet scalars.
190  btAlignedObjectArray<btVector3> aryVerts;
191  for( int iIdx=0; iIdx<iVerts; iIdx++ )
192  {
193  btVector3 vVert = aryPoints[iIdx];
194  aryVerts.push_back(btVector3(vVert[0], vVert[1], vVert[2]) );
195  }
196 
197  delete lpHull;
198 
199  btAlignedObjectArray<btVector3> aryPlaneEquations;
200 
201  btGeometryUtil::getPlaneEquationsFromVertices(aryVerts, aryPlaneEquations);
202 
203  btConvexHullShape *lpConvexShape = new btConvexHullShape();
204  float fltMargin = lpConvexShape->getMargin();
205  //lpConvexShape->setMargin(fltMargin/2);
206  lpConvexShape->setMargin(0);
207 
208  int sz = aryPlaneEquations.size();
209  bool tooSmall = false;
210  for (int i=0 ; i<sz ; ++i) {
211  if ((aryPlaneEquations[i][3] += lpConvexShape->getMargin()) >= 0) {
212  tooSmall = true;
213  break;
214  }
215  }
216 
217  if (!tooSmall) {
218  aryVerts.clear();
219  btGeometryUtil::getVerticesFromPlaneEquations(aryPlaneEquations, aryVerts);
220  }
221 
222  sz = aryVerts.size();
223  for (int i=0 ; i<sz ; ++i) {
224  lpConvexShape->addPoint(aryVerts[i]);
225  }
226 
227  return lpConvexShape;
228  }
229 
230 
231 #pragma endregion
232 
233  btVector3 Vec3AnimatToBullet(const CStdFPoint &vPoint)
234  {
235  btVector3 vVal(vPoint.x, vPoint.y, vPoint.z);
236  return vVal;
237  }
238 
239  CStdFPoint Vec3BulletToAnimat(const btVector3 &vPoint)
240  {
241  CStdFPoint vVal(vPoint[0], vPoint[1], vPoint[2]);
242  return vVal;
243  }
244 
245  } // Environment
246 //} //BulletAnimatSim
247 
248 }
Classes for implementing the cm-labs vortex physics engine for AnimatLab.