void dgWorld::TickCallback (dgInt32 threadID) { if (threadID == DG_MUTEX_THREAD_ID) { StepDynamics (m_savetimestep); } else { Update (m_savetimestep); } }
void dgWorld::TickCallback (dgInt32 threadID) { if (threadID == DG_MUTEX_THREAD_ID) { StepDynamics (m_savetimestep); memcpy (m_perfomanceCountersBack, m_perfomanceCounters, sizeof (m_perfomanceCounters)); } else { Update (m_savetimestep); } }
void dgWorld::UpdateAsync (dgFloat32 timestep) { m_savetimestep = timestep; #ifdef DG_USE_THREAD_EMULATION StepDynamics (m_savetimestep); #else // execute one update, but do not wait for the update to finish, instead return immediately to the caller dgAsyncThread::Tick(); #endif }
void ODESimulator::Step(Real dt) { Assert(timestep == 0); //Timer timer; //double collisionTime,stepTime,updateTime; gContacts.clear(); timestep=dt; DetectCollisions(); //printf(" %d contacts detected\n",gContacts.size()); //collisionTime = timer.ElapsedTime(); //timer.Reset(); StepDynamics(dt); //stepTime = timer.ElapsedTime(); //timer.Reset(); for(map<pair<ODEObjectID,ODEObjectID>,ODEContactList>::iterator i=contactList.begin();i!=contactList.end();i++) { ODEContactList& cl=i->second; cl.forces.clear(); for(size_t j=0;j<cl.feedbackIndices.size();j++) { int k=cl.feedbackIndices[j]; Assert(k >= 0 && k < (int)gContacts.size()); list<ODEContactResult>::iterator cres=gContacts.begin(); advance(cres,k); Vector3 temp; for(size_t i=0;i<cres->feedback.size();i++) { CopyVector(temp,cres->feedback[i].f1); cl.forces.push_back(temp); /* if(!cl.points.back().isValidForce(-temp)) { printf("ODESimulator: Warning, solved contact force %d %d is invalid\n",k,i); cout<<" Force: "<<-temp<<", normal "<<cl.points.back().n<<" kFriction "<<cl.points.back().kFriction<<endl; } */ } } if(!cl.feedbackIndices.empty()) Assert(cl.points.size() == cl.forces.size()); } timestep = 0; //KH: commented this out so GetContacts() would work for ContactSensor simulation. Be careful about loading state //gContacts.clear(); //updateTime = timer.ElapsedTime(); //printf("ODE simulation step: %g collision, %g step, %g update\n",collisionTime,stepTime,updateTime); }
void dgWorld::Update (dgFloat32 timestep) { m_savetimestep = timestep; #ifdef DG_USE_THREAD_EMULATION dgFloatExceptions exception; dgSetPrecisionDouble precision; // run update in same thread as the calling application as if it was a separate thread StepDynamics (m_savetimestep); #else // runs the update in a separate thread and wait until the update is completed before it returns. // this will run well on single core systems, since the two thread are mutually exclusive dgMutexThread::Tick(); #endif }
void dgWorld::RunStep () { static int zzzz; if (zzzz == 50) { DG_START_RECORDING("../../../../sdk/dProfiler/xxxx.tt"); } if (zzzz == 500) { DG_STOP_RECORDING(); } zzzz++; DG_TRACKTIME(__FUNCTION__); dgUnsigned64 timeAcc = dgGetTimeInMicrosenconds(); dgFloat32 step = m_savetimestep / m_numberOfSubsteps; for (dgUnsigned32 i = 0; i < m_numberOfSubsteps; i ++) { dgInterlockedExchange(&m_delayDelateLock, 1); StepDynamics (step); dgInterlockedExchange(&m_delayDelateLock, 0); dgDeadBodies& bodyList = *this; dgDeadJoints& jointList = *this; jointList.DestroyJoints (*this); bodyList.DestroyBodies (*this); } const dgBodyMasterList* const masterList = this; dgBodyMasterList::dgListNode* node = masterList->GetFirst(); const dgInt32 threadsCount = GetThreadCount(); for (dgInt32 i = 0; i < threadsCount; i++) { QueueJob(UpdateTransforms, this, node, "dgWorld::UpdateTransforms"); node = node ? node->GetNext() : NULL; } SynchronizationBarrier(); if (m_postUpdateCallback) { m_postUpdateCallback (this, m_savetimestep); } m_lastExecutionTime = (dgGetTimeInMicrosenconds() - timeAcc) * dgFloat32 (1.0e-6f); if (!m_concurrentUpdate) { m_mutex.Release(); } }