7 #include "BlOsgGeometry.h"
9 #include "BlMotorizedJoint.h"
10 #include "BlRigidBody.h"
11 #include "BlClassFactory.h"
12 #include "BlSimulator.h"
22 BlSimulator::BlSimulator()
24 m_lpCollisionConfiguration = NULL;
25 m_lpDispatcher = NULL;
27 m_lpBroadPhase = NULL;
28 m_lpDynamicsWorld = NULL;
32 m_vsWinMgr =
new OsgSimulationWindowMgr;
33 m_lpWinMgr = m_vsWinMgr;
34 m_lpWinMgr->SetSystemPointers(
this, NULL, NULL, NULL,
true);
35 m_dblTotalStepTime = 0;
37 m_dblTotalStepTime= 0;
39 m_dblTotalVortexStepTime = 0;
40 m_lStepVortexTimeCount = 0;
42 m_osgAlphafunc = NULL;
43 m_iSubstepCallbackCount = 0;
46 m_lpMatrixUtil =
new OsgMatrixUtil;
48 SetMatrixUtil(m_lpMatrixUtil);
50 if(!m_lpAnimatClassFactory)
56 BlSimulator::~BlSimulator()
67 m_bShuttingDown =
true;
72 {
Std_TraceMsg(0,
"Caught Error in desctructor of Simulator\r\n",
"", -1,
false,
true);}
75 #pragma region MutatorOverrides
77 void BlSimulator::StabilityScale(
float fltVal)
79 OsgSimulator::StabilityScale(fltVal);
80 SetSimulationStabilityParams();
83 void BlSimulator::LinearCompliance(
float fltVal,
bool bUseScaling)
85 OsgSimulator::LinearCompliance(fltVal, bUseScaling);
86 SetSimulationStabilityParams();
89 void BlSimulator::AngularCompliance(
float fltVal,
bool bUseScaling)
91 OsgSimulator::AngularCompliance(fltVal, bUseScaling);
92 SetSimulationStabilityParams();
95 void BlSimulator::LinearDamping(
float fltVal,
bool bUseScaling)
97 OsgSimulator::LinearDamping(fltVal, bUseScaling);
98 SetSimulationStabilityParams();
101 void BlSimulator::AngularDamping(
float fltVal,
bool bUseScaling)
103 OsgSimulator::AngularDamping(fltVal, bUseScaling);
104 SetSimulationStabilityParams();
107 void BlSimulator::LinearKineticLoss(
float fltVal,
bool bUseScaling)
109 OsgSimulator::LinearKineticLoss(fltVal, bUseScaling);
110 SetSimulationStabilityParams();
113 void BlSimulator::AngularKineticLoss(
float fltVal,
bool bUseScaling)
115 OsgSimulator::AngularKineticLoss(fltVal, bUseScaling);
116 SetSimulationStabilityParams();
119 void BlSimulator::Gravity(
float fltVal,
bool bUseScaling)
121 OsgSimulator::Gravity(fltVal, bUseScaling);
123 if(m_lpDynamicsWorld)
124 m_lpDynamicsWorld->setGravity( btVector3( 0, m_fltGravity, 0 ) );
130 SimulationRecorder *BlSimulator::CreateSimulationRecorder()
136 void BlSimulator::Reset()
138 OsgSimulator::Reset();
140 if(m_lpDynamicsWorld)
142 delete m_lpDynamicsWorld;
143 m_lpDynamicsWorld = NULL;
154 delete m_lpBroadPhase;
155 m_lpBroadPhase = NULL;
160 delete m_lpDispatcher;
161 m_lpDispatcher = NULL;
164 if(m_lpCollisionConfiguration)
166 delete m_lpCollisionConfiguration;
167 m_lpCollisionConfiguration = NULL;
170 if(!m_lpAnimatClassFactory)
173 m_aryFluidPlanes.clear();
176 void BlSimulator::ResetSimulation()
178 OsgSimulator::ResetSimulation();
180 m_bSimRunning =
false;
211 bool AnimatContactCallback(btManifoldPoint& cp,
void* body0,
void* body1)
213 btCollisionObject *lpBtBody1 = (btCollisionObject *) body0;
214 btCollisionObject *lpBtBody2 = (btCollisionObject *) body1;
217 if( lpBtBody1 && lpBtBody2 &&
218 ( (lpBtBody1->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) ||
219 (lpBtBody2->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)) )
224 if(lpData1 && lpData1->m_lpBody && lpData2 && lpData2->m_lpBody)
226 if(lpBtBody1->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)
227 lpData1->m_lpBody->m_aryContactPoints.Add(
new BlContactPoint(&cp, lpData2->m_lpBody,
true));
229 if(lpBtBody2->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)
230 lpData2->m_lpBody->m_aryContactPoints.Add(
new BlContactPoint(&cp, lpData1->m_lpBody,
false));
237 void BlSimulator::InitializeBulletViewer(
int argc,
const char **argv)
241 osg::setNotifyLevel(osg::NotifySeverity::NOTICE);
253 osgDB::FilePathList aryList = osgDB::getLibraryFilePathList();
254 std::string strPath = m_strExecutablePath.substr(0, m_strExecutablePath.length()-1);
256 aryList.push_front(strPath);
257 osgDB::setLibraryFilePathList(aryList);
260 osgDB::getDataFilePathList().push_front(
"./Resources");
261 osgDB::getDataFilePathList().push_front(
"../Resources");
262 osgDB::getDataFilePathList().push_front(
"../../Resources");
265 osgDB::getDataFilePathList().push_front(
"/usr/share/fonts/truetype");
268 std::string strFile = osgDB::findLibraryFile(
"osgdb_freetype.dll");
272 m_grpScene =
new osg::MatrixTransform;
273 m_grpScene->setMatrix(osg::Matrix::identity());
274 m_grpScene->setName(
"World");
277 m_grpScene->addChild(m_lpMouseSpring->GetNode());
280 m_vsWinMgr->Initialize();
283 if(!m_osgCmdMgr.valid())
284 m_osgCmdMgr =
new osgManipulator::CommandManager;
286 osg::StateSet* rootStateSet = m_grpScene->getOrCreateStateSet();
287 rootStateSet->setMode( GL_LIGHTING, osg::StateAttribute::ON );
288 rootStateSet->setMode( GL_LIGHT0, osg::StateAttribute::ON );
292 m_osgAlphafunc =
new osg::AlphaFunc;
293 m_osgAlphafunc->setFunction(osg::AlphaFunc::GEQUAL, m_fltAlphaThreshold);
294 rootStateSet->setAttributeAndModes(m_osgAlphafunc, osg::StateAttribute::ON);
296 m_oLightMgr.Initialize();
299 void BlSimulator::SetSimulationStabilityParams()
304 void BlSimulator::BulletStepFinished(btScalar timeStep)
306 m_iSubstepCallbackCount++;
307 if(m_iPhysicsSubsteps == m_iSubstepCallbackCount)
309 AfterStepSimulation();
310 m_iSubstepCallbackCount = 0;
314 void ProcessTickCallback(btDynamicsWorld *world, btScalar timeStep)
317 w->BulletStepFinished(timeStep);
322 void BlSimulator::InitializeBullet(
int argc,
const char **argv)
324 InitializeBulletViewer(argc, argv);
326 int iObjectCount = 100 + m_iPhysicsBodyCount;
327 int iCollisionCount = iObjectCount*40;
329 m_lpCollisionConfiguration =
new btDefaultCollisionConfiguration();
332 m_lpSolver =
new btSequentialImpulseConstraintSolver;
336 btVector3 worldAabbMin( -10000, -10000, -10000 );
337 btVector3 worldAabbMax( 10000, 10000, 10000 );
338 m_lpBroadPhase =
new btAxisSweep3( worldAabbMin, worldAabbMax, 1000 );
340 m_lpDynamicsWorld =
new btDiscreteDynamicsWorld( m_lpDispatcher, m_lpBroadPhase, m_lpSolver, m_lpCollisionConfiguration );
341 m_lpDynamicsWorld->setGravity( btVector3( 0, m_fltGravity, 0 ) );
343 m_lpDynamicsWorld->setInternalTickCallback(ProcessTickCallback, static_cast<void *>(
this));
347 this->OSGRoot()->addChild(m_dbgDraw.getSceneGraph());
348 m_lpDynamicsWorld->setDebugDrawer( &m_dbgDraw );
352 gContactProcessedCallback = &AnimatContactCallback;
373 std::string strPath = this->ProjectPath();
374 std::string strOrigFile = AnimatSim::GetFilePath(strPath, strOriginalMeshFile);
375 std::string strNewFile = AnimatSim::GetFilePath(strPath, strCollisionMeshFile);
377 osg::ref_ptr<osg::Node> osgNode = MeshMgr()->LoadMesh(strOrigFile);
381 THROW_PARAM_ERROR(Bl_Err_lErrorLoadingMesh, Bl_Err_strErrorLoadingMesh,
"Original Mesh file", strOriginalMeshFile);
384 btConvexHullShape *btHull = OsgConvexShrunkenHullCollisionShape(osgNode.get());
387 THROW_PARAM_ERROR(Bl_Err_lConvertingMeshToConvexHull, Bl_Err_strConvertingMeshToConvexHull,
"Original Mesh file", strOriginalMeshFile);
390 osg::ref_ptr<osg::Node> osgNewNode = osgbCollision::osgNodeFromBtCollisionShape( btHull );
392 osg::Matrix osgScale = osg::Matrix::scale(fltScaleX, fltScaleY, fltScaleZ);
393 osg::ref_ptr<osg::MatrixTransform> osgScaleMT =
new osg::MatrixTransform(osgScale);
394 osgScaleMT->addChild(osgNewNode.get());
395 osgScaleMT->setDataVariance(osg::Object::STATIC);
402 osgUtil::Optimizer optimizer;
403 optimizer.optimize(osgScaleMT.get(), osgUtil::Optimizer::FLATTEN_STATIC_TRANSFORMS);
406 osgDB::writeNodeFile(*osgNewNode, strNewFile.c_str());
410 Std_SetFileTime(strNewFile);
413 void BlSimulator::ConvertV1MeshFile(std::string strOriginalMeshFile, std::string strNewMeshFile, std::string strTexture)
416 std::string strPath = this->ProjectPath();
417 std::string strOrigFile = AnimatSim::GetFilePath(strPath, strOriginalMeshFile);
418 std::string strNewFile = AnimatSim::GetFilePath(strPath, strNewMeshFile);
419 std::string strTextFile =
"";
422 strTextFile = AnimatSim::GetFilePath(strPath, strTexture);
424 osg::ref_ptr<osg::Node> osgNode = osgDB::readNodeFile(strOrigFile.c_str());
428 THROW_PARAM_ERROR(Bl_Err_lErrorLoadingMesh, Bl_Err_strErrorLoadingMesh,
"Original Mesh file", strOriginalMeshFile);
430 CStdFPoint vPos(0, 0, 0), vRot( -(osg::PI/2), 0, 0);
431 ApplyVertexTransform(osgNode.get(), SetupMatrix(vPos, vRot));
432 AddNodeTexture(osgNode.get(), strTextFile, GL_TEXTURE_2D);
435 osgDB::writeNodeFile(*osgNode, strNewFile.c_str());
439 void BlSimulator::GetPositionAndRotationFromD3DMatrix(
float (&aryTransform)[4][4], CStdFPoint &vPos, CStdFPoint &vRot)
441 osg::Matrix osgMT(aryTransform[0][0], aryTransform[0][1], aryTransform[0][2], aryTransform[0][3],
442 aryTransform[1][0], aryTransform[1][1], aryTransform[1][2], aryTransform[1][3],
443 aryTransform[2][0], aryTransform[2][1], aryTransform[2][2], aryTransform[2][3],
444 aryTransform[3][0], aryTransform[3][1], aryTransform[3][2], aryTransform[3][3]);
446 osg::Matrix osgFinal;
452 osg::Vec3 vL = osgFinal.getTrans();
453 vPos.Set(vL.x(), vL.y(), vL.z());
454 vPos.ClearNearZero();
456 vRot = EulerRotationFromMatrix(osgFinal);
459 void BlSimulator::Initialize(
int argc,
const char **argv)
461 InitializeBullet(argc, argv);
463 OsgSimulator::Initialize(argc, argv);
466 void BlSimulator::StepSimulation()
478 OsgSimulator::StepSimulation();
480 unsigned long long lStart = GetTimerTick();
483 m_dbgDraw.BeginDraw();
485 m_lpDynamicsWorld->stepSimulation(m_fltPhysicsTimeStep, m_iPhysicsSubsteps, m_fltPhysicsSubstepTime);
489 m_lpDynamicsWorld->debugDrawWorld();
493 double dblVal = TimerDiff_s(lStart, GetTimerTick());
494 m_fltPhysicsStepTime += dblVal;
496 if(m_lTimeSlice > 10 && m_lTimeSlice < 5000)
498 m_dblTotalVortexStepTime += dblVal;
499 m_lStepVortexTimeCount++;
501 else if(m_lTimeSlice == 5000)
503 double dblAvgStepTime = m_dblTotalVortexStepTime/m_lStepVortexTimeCount;
504 osg::notify(osg::NOTICE) <<
"Average step time: " << dblAvgStepTime << std::endl;
505 osg::notify(osg::NOTICE) <<
"Total vortex step time: " << m_dblTotalVortexStepTime << std::endl;
506 osg::notify(osg::NOTICE) <<
"Slice Time: " << m_lTimeSlice << std::endl;
507 osg::notify(osg::NOTICE) <<
"Sim Time: " << Time() << std::endl;
514 catch(CStdErrorInfo oError)
516 std::string strError =
"An error occurred while step the simulation.\nError: " + oError.m_strError;
517 HandleNonCriticalError(strError);
540 void BlSimulator::SimulateEnd()
545 bool BlSimulator::HasFluidPlane(FluidPlane *lpPlane)
547 std::list<FluidPlane *>::iterator it;
548 for (it=m_aryFluidPlanes.begin(); it!=m_aryFluidPlanes.end(); ++it)
555 bool compare_fluid_planes (FluidPlane *first, FluidPlane *second)
558 return (first->Height() < second->Height());
563 void BlSimulator::AddFluidPlane(FluidPlane *lpPlane)
565 if(!HasFluidPlane(lpPlane))
567 m_aryFluidPlanes.push_back(lpPlane);
568 m_aryFluidPlanes.sort(compare_fluid_planes);
572 void BlSimulator::RemoveFluidPlane(FluidPlane *lpPlane)
574 if(HasFluidPlane(lpPlane))
576 m_aryFluidPlanes.remove(lpPlane);
577 m_aryFluidPlanes.sort(compare_fluid_planes);
581 void BlSimulator::SortFluidPlanes()
583 m_aryFluidPlanes.sort(compare_fluid_planes);
601 std::list<FluidPlane *>::iterator it;
602 for (it=m_aryFluidPlanes.begin(); it!=m_aryFluidPlanes.end(); ++it)
603 if(fltDepth <= (*it)->Height())
virtual void GenerateCollisionMeshFile(std::string strOriginalMeshFile, std::string strCollisionMeshFile, float fltScaleX, float fltScaleY, float fltScaleZ)
Generates a collision mesh file.
Classes for implementing the cm-labs vortex physics engine for AnimatLab.
virtual FluidPlane * FindFluidPlaneForDepth(float fltDepth)
Searches the fluid planes starting at the lowest height and working its way up to find the first one ...
void Std_TraceMsg(const int iLevel, std::string strMessage, std::string strSourceFile, int iSourceLine, bool bLogToFile, bool bPrintHeader)
Traces a message to the debugger window.
bool Std_IsBlank(std::string strVal)
Trims a string and tests if a string is blank.