/****************************************************************************** * render a whole animation (visualization mode) * this function is run in another thread, and communicates * with the parent thread via a mutex *****************************************************************************/ int ntlWorld::renderVisualization( bool multiThreaded ) { #ifndef NOGUI if(getElbeemState() != SIMWORLD_INITED) { return 0; } if(multiThreaded) mThreadRunning = true; // TODO, check global state? while(!getStopRenderVisualization()) { if(mpSims->size() <= 0) { debMsgStd("ntlWorld::renderVisualization",DM_NOTIFY,"No simulations found, stopping...",1); stopSimulationThread(); break; } // determine stepsize if(!mSingleStepDebug) { long startTime = getTime(); advanceSims(mFrameCnt); mFrameCnt++; long stopTime = getTime(); debMsgStd("ntlWorld::renderVisualization",DM_MSG,"Time for t="<<mSimulationTime<<": "<< getTimeString(stopTime-startTime) <<" ", 10); } else { double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getTimestep(); singleStepSims(targetTime); // check paniced sims (normally done by advanceSims bool allPanic = true; for(size_t i=0;i<mpSims->size();i++) { if(!(*mpSims)[i]->getPanic()) allPanic = false; } if(allPanic) { warnMsg("ntlWorld::advanceSims","All sims panicked... stopping thread" ); setStopRenderVisualization( true ); } if(! isSimworldOk() ) { warnMsg("ntlWorld::advanceSims","World state error... stopping" ); setStopRenderVisualization( true ); } } // save frame if(mpOpenGLRenderer) mpOpenGLRenderer->saveAnimationFrame( mSimulationTime ); // for non-threaded check events if(!multiThreaded) { Fl::check(); gpElbeemFrame->SceneDisplay->doOnlyForcedRedraw(); } } mThreadRunning = false; stopSimulationRestoreGui(); #else multiThreaded = false; // remove warning #endif return 0; }
/****************************************************************************** * advance simulations by time t *****************************************************************************/ int ntlWorld::advanceSims(int framenum) { bool done = false; bool allPanic = true; // stop/quit, dont display/render if(getElbeemState()==SIMWORLD_STOP) { return 1; } for(size_t i=0;i<mpSims->size();i++) { (*mpSims)[i]->setFrameNum(framenum); } double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getFrameTime(framenum); // time stopped? nothing else to do... if( (*mpSims)[mFirstSim]->getFrameTime(framenum) <= 0.0 ){ done=true; allPanic=false; } int gstate = 0; myTime_t advsstart = getTime(); // step all the sims, and check for panic debMsgStd("ntlWorld::advanceSims",DM_MSG, " sims "<<mpSims->size()<<" t"<<targetTime<<" done:"<<done<<" panic:"<<allPanic<<" gstate:"<<gstate, 10); // debug // timedebug while(!done) { double nextTargetTime = (*mpSims)[mFirstSim]->getCurrentTime() + (*mpSims)[mFirstSim]->getTimestep(); singleStepSims(nextTargetTime); // check target times done = true; allPanic = false; if((*mpSims)[mFirstSim]->getTimestep() <1e-9 ) { // safety check, avoid timesteps that are too small errMsg("ntlWorld::advanceSims","Invalid time step, causing panic! curr:"<<(*mpSims)[mFirstSim]->getCurrentTime()<<" next:"<<nextTargetTime<<", stept:"<< (*mpSims)[mFirstSim]->getTimestep() ); allPanic = true; } else { for(size_t i=0;i<mpSims->size();i++) { if(!(*mpSims)[i]->getVisible()) continue; if((*mpSims)[i]->getPanic()) allPanic = true; // do any panic now!? debMsgStd("ntlWorld::advanceSims",DM_MSG, "Sim "<<i<<", currt:"<<(*mpSims)[i]->getCurrentTime()<<", nt:"<<nextTargetTime<<", panic:"<<(*mpSims)[i]->getPanic()<<", targett:"<<targetTime, 10); // debug // timedebug } } if( (targetTime - (*mpSims)[mFirstSim]->getCurrentTime()) > LBM_TIME_EPSILON) done=false; if(allPanic) done = true; } if(allPanic) { warnMsg("ntlWorld::advanceSims","All sims panicked... stopping thread" ); setStopRenderVisualization( true ); return 1; } myTime_t advsend = getTime(); debMsgStd("ntlWorld::advanceSims",DM_MSG,"Overall steps so far took:"<< getTimeString(advsend-advsstart)<<" for sim time "<<targetTime, 4); // finish step for(size_t i=0;i<mpSims->size();i++) { SimulationObject *sim = (*mpSims)[i]; if(!sim->getVisible()) continue; if(sim->getPanic()) continue; sim->prepareVisualization(); } return 0; }
/****************************************************************************** * advance simulations by time t *****************************************************************************/ int ntlWorld::advanceSims(int framenum) { bool done = false; bool allPanic = true; // stop/quit (abort), dont display/render if(!isSimworldOk()) { return 1; } for(size_t i=0;i<mpSims->size();i++) { (*mpSims)[i]->setFrameNum(framenum); } // time stopped? nothing else to do... if( (*mpSims)[mFirstSim]->getFrameTime(framenum) <= 0.0 ){ done=true; allPanic=false; /* DG: Need to check for user cancel here (fix for [#30298]) */ (*mpSims)[mFirstSim]->checkCallerStatus(FLUIDSIM_CBSTATUS_STEP, 0); } // Prevent bug [#29186] Object contribute to fluid sim animation start earlier than keyframe // Was: double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getFrameTime(framenum); - DG double totalTime = 0.0, targetTime = 0.0; for(size_t i = 0; i < mSimFrameCnt; i++) { /* We need an intermediate array "mSimFrameValue" because otherwise if we don't start with starttime = 0, the sim gets out of sync - DG */ totalTime += (*mpSims)[mFirstSim]->getFrameTime(mSimFrameValue[i]); } targetTime = totalTime + (*mpSims)[mFirstSim]->getFrameTime(framenum); int gstate = 0; myTime_t advsstart = getTime(); // step all the sims, and check for panic debMsgStd("ntlWorld::advanceSims",DM_MSG, " sims "<<mpSims->size()<<" t"<<targetTime<<" done:"<<done<<" panic:"<<allPanic<<" gstate:"<<gstate, 10); // debug // timedebug while(!done) { double nextTargetTime = (*mpSims)[mFirstSim]->getCurrentTime() + (*mpSims)[mFirstSim]->getTimestep(); singleStepSims(nextTargetTime); // check target times done = true; allPanic = false; if((*mpSims)[mFirstSim]->getTimestep() <1e-9 ) { // safety check, avoid timesteps that are too small errMsg("ntlWorld::advanceSims","Invalid time step, causing panic! curr:"<<(*mpSims)[mFirstSim]->getCurrentTime()<<" next:"<<nextTargetTime<<", stept:"<< (*mpSims)[mFirstSim]->getTimestep() ); allPanic = true; } else { for(size_t i=0;i<mpSims->size();i++) { if(!(*mpSims)[i]->getVisible()) continue; if((*mpSims)[i]->getPanic()) allPanic = true; // do any panic now!? debMsgStd("ntlWorld::advanceSims",DM_MSG, "Sim "<<i<<", currt:"<<(*mpSims)[i]->getCurrentTime()<<", nt:"<<nextTargetTime<<", panic:"<<(*mpSims)[i]->getPanic()<<", targett:"<<targetTime, 10); // debug // timedebug } } if( (targetTime - (*mpSims)[mFirstSim]->getCurrentTime()) > LBM_TIME_EPSILON) done=false; if(allPanic) done = true; } if(allPanic) { warnMsg("ntlWorld::advanceSims","All sims panicked... stopping thread" ); setStopRenderVisualization( true ); return 1; } myTime_t advsend = getTime(); debMsgStd("ntlWorld::advanceSims",DM_MSG,"Overall steps so far took:"<< getTimeString(advsend-advsstart)<<" for sim time "<<targetTime, 4); // finish step for(size_t i=0;i<mpSims->size();i++) { SimulationObject *sim = (*mpSims)[i]; if(!sim->getVisible()) continue; if(sim->getPanic()) continue; sim->prepareVisualization(); } mSimFrameValue.push_back(framenum); mSimFrameCnt++; return 0; }