void CParticleEditor::update() { if (!_ActiveNode) return; if (_PW == NULL) return; NL3D::CParticleSystem *currPS = _ActiveNode->getPSPointer(); // compute BBox if (_DisplayBBox) { if (_AutoUpdateBBox) { NLMISC::CAABBox currBBox; currPS->forceComputeBBox(currBBox); if (_EmptyBBox) { _EmptyBBox = false; _CurrBBox = currBBox; } else { _CurrBBox = NLMISC::CAABBox::computeAABBoxUnion(currBBox, _CurrBBox); } currPS->setPrecomputedBBox(_CurrBBox); } } // auto repeat feature if (_AutoRepeat) { if (isRunning()) { bool allFXFinished = true; bool fxStarted = false; TPWNodeItr itr = _PlayingNodes.begin(); while(itr != _PlayingNodes.end()) { CWorkspaceNode *node = (*itr); if (node->isLoaded()) { if (isRunning(node)) { fxStarted = true; if (node->getPSPointer()->getSystemDate() <= node->getPSPointer()->evalDuration()) { allFXFinished = false; break; } else { if (node->getPSPointer()->getCurrNumParticles() != 0) { allFXFinished = false; break; } } } } itr++; } if (fxStarted && allFXFinished) restartAllFX(); } } // draw PSmodel TPWNodeItr itr = _PW->getNodeList().begin(); while(itr != _PW->getNodeList().end()) { CWorkspaceNode *node = (*itr); if (node->isLoaded()) { if (node == _ActiveNode) node->getPSModel()->enableDisplayTools(!isRunning(node) || _DisplayHelpers); else node->getPSModel()->enableDisplayTools(false); // hide / show the node if (_State == State::RunningMultiple || _State == State::PausedMultiple) { if (isRunning(node)) node->getPSModel()->show(); else node->getPSModel()->hide(); } else { if (node == _ActiveNode) node->getPSModel()->show(); else node->getPSModel()->hide(); } } itr++; } }
//****************************************************************************************************** void CStartStopParticleSystem::goPreRender() { if (!_ActiveNode) return; NL3D::CParticleSystem *ps = _ActiveNode->getPSPointer(); sint currNumParticles = (sint) ps->getCurrNumParticles(); sint maxNumParticles = (sint) ps->getMaxNumParticles(); // if linked with scene animation, restart if animation ends if (m_LinkPlayToScenePlay) // is scene animation subordinated to the fx animation { // start animation for the scene too if (_AnimationDLG && isRunning()) { if (_LastSceneAnimFrame > _AnimationDLG->CurrentFrame) // did animation restart ? { restartAllFX(); } _LastSceneAnimFrame = _AnimationDLG->CurrentFrame; } } else if (_AutoRepeat && !m_LinkPlayToScenePlay) // auto repeat feature { if (isRunning()) { bool allFXFinished = true; bool fxStarted = false; for(uint k = 0; k < _PlayingNodes.size(); ++k) { if (_PlayingNodes[k]) { if (isRunning(_PlayingNodes[k])) { fxStarted = true; if (_PlayingNodes[k]->getPSPointer()->getSystemDate() <= _PlayingNodes[k]->getPSPointer()->evalDuration()) { allFXFinished = false; break; } else { if (_PlayingNodes[k]->getPSPointer()->getCurrNumParticles() != 0) { allFXFinished = false; break; } } } } } if (fxStarted && allFXFinished) { restartAllFX(); } } } if (_State == RunningMultiple || _State == PausedMultiple) { std::set<std::string> currAnims; CObjectViewer *ov = _ParticleDlg->getObjectViewer(); for(uint k = 0; k < ov->getNumInstance(); ++k) { CInstanceInfo *ci = ov->getInstance(k); uint animIndex = ci->Playlist.getAnimation(0); if (animIndex != NL3D::CAnimationSet::NotFound) { std::string animName = ci->AnimationSet.getAnimationName(animIndex); if (!animName.empty()) { currAnims.insert(animName); } } } // check fx that have a trigger anim for(uint k = 0; k < _PlayingNodes.size(); ++k) { if (_PlayingNodes[k]) { if (!isRunning(_PlayingNodes[k]) || !_PlayingNodes[k]->getPSModel()->hasActiveEmitters()) { // see if chosen anim is currently running if (_PlayingNodes[k]->getTriggerAnim().empty() || currAnims.count(_PlayingNodes[k]->getTriggerAnim())) { // if the fx was shutting down, stop then restart it if (!_PlayingNodes[k]->getPSModel()->hasActiveEmitters()) { nlassert(isRunning(_PlayingNodes[k])); stop(*_PlayingNodes[k]); } // yes -> trigger the fx play(*_PlayingNodes[k]); } else if (!_PlayingNodes[k]->getPSPointer()->hasParticles()) // fx is being shut down, stop it when necessary { stop(*_PlayingNodes[k]); // no more particles so stop the system } } else { if (!_PlayingNodes[k]->getTriggerAnim().empty()) { if (_PlayingNodes[k]->getPSModel()->hasActiveEmitters()) { // see if anim if already playing. If this is not the case then shutdown the emitters if (!currAnims.count(_PlayingNodes[k]->getTriggerAnim())) { _PlayingNodes[k]->getPSModel()->activateEmitters(false); } } } } } } } if (_ActiveNode) { // display number of particles for the currently active node if (currNumParticles != _LastCurrNumParticles || maxNumParticles != _LastMaxNumParticles) { CString numParts; numParts.LoadString(IDS_NUM_PARTICLES); numParts += CString(NLMISC::toString("%d / %d",(int) currNumParticles, (int) maxNumParticles).c_str()); GetDlgItem(IDC_NUM_PARTICLES)->SetWindowText((LPCTSTR) numParts); _LastCurrNumParticles = currNumParticles; _LastMaxNumParticles = maxNumParticles; } // display max number of wanted faces NLMISC::CMatrix camMat = ps->getScene()->getCam()->getMatrix(); sint numWantedFaces = (uint) ps->getWantedNumTris((ps->getSysMat().getPos() - camMat.getPos()).norm()); if (numWantedFaces != _LastNumWantedFaces) { CString numWF; numWF.LoadString(IDS_NUM_WANTED_FACES); numWF += CString(NLMISC::toString("%d",(int) numWantedFaces).c_str()); GetDlgItem(IDC_NUM_ASKED_FACES)->SetWindowText((LPCTSTR) numWF); _LastNumWantedFaces = numWantedFaces; } // display system date if (ps->getSystemDate() != _LastSystemDate) { _LastSystemDate = ps->getSystemDate(); CString sysDate; sysDate.LoadString(IDS_SYSTEM_DATE); sysDate += CString(NLMISC::toString("%.2f s",_LastSystemDate).c_str()); GetDlgItem(IDC_SYSTEM_DATE)->SetWindowText((LPCTSTR) sysDate); } } if (_ParticleDlg) { CParticleWorkspace *pws = _ParticleDlg->getParticleWorkspace(); if (pws) { for(uint k = 0; k < pws->getNumNode(); ++k) { if (pws->getNode(k)->isLoaded()) { if (pws->getNode(k) == _ActiveNode) { pws->getNode(k)->getPSModel()->enableDisplayTools(!isRunning(pws->getNode(k)) || m_DisplayHelpers); } else { pws->getNode(k)->getPSModel()->enableDisplayTools(false); } // hide / show the node if (_State == RunningMultiple || _State == PausedMultiple) { if (isRunning(pws->getNode(k))) { pws->getNode(k)->getPSModel()->show(); } else { pws->getNode(k)->getPSModel()->hide(); } } else { if (pws->getNode(k) == _ActiveNode) { pws->getNode(k)->getPSModel()->show(); } else { pws->getNode(k)->getPSModel()->hide(); } } } } } } }