RESULT ParticleManager::SetEffect( IN HParticleEmitter hParticleEmitter, HEffect hEffect ) { RESULT rval = S_OK; ParticleEmitter* pParticleEmitter = GetObjectPointer( hParticleEmitter ); if (pParticleEmitter) { #ifdef DEBUG string name; EffectMan.GetName( hEffect, &name ); DEBUGMSG(ZONE_PARTICLES, "ParticleManager::SetEffect( %s, %s )", pParticleEmitter->GetName().c_str(), name.c_str()); #endif pParticleEmitter->SetEffect( hEffect ); } else { RETAILMSG(ZONE_ERROR, "ERROR: ParticleManager::SetEffect( 0x%x, 0x%x ): object not found", (UINT32)hParticleEmitter, (UINT32)hEffect); rval = E_INVALID_ARG; } Exit: return rval; }
RESULT ParticleManager::Update( UINT64 elapsedMS ) { RESULT rval = S_OK; // // TODO: if our update frequency is less than 60Hz, we should // spread out the emitter updates, rather than updating ALL of them // every fourth frame (for example). // static UINT64 lastUpdateTimeMS = 0; if ((elapsedMS - lastUpdateTimeMS) < m_updateIntervalMS) { return S_OK; } lastUpdateTimeMS = elapsedMS; // Release ParticleEmitters that were marked as done on previous frame. ParticleEmitterListIterator ppParticleEmitter; for (ppParticleEmitter = m_pendingReleaseParticleEmittersList.begin(); ppParticleEmitter != m_pendingReleaseParticleEmittersList.end(); ++ppParticleEmitter) { ParticleEmitter* pParticleEmitter = *ppParticleEmitter; if (!pParticleEmitter) continue; DEBUGMSG(ZONE_PARTICLES, "Releasing ParticleEmitter [%s], refCount = %d", pParticleEmitter->GetName().c_str(), pParticleEmitter->GetRefCount()); //pParticleEmitter->Stop(); CHR(Release( pParticleEmitter )); } m_pendingReleaseParticleEmittersList.clear(); // Update every running ParticleEmitter. for (ppParticleEmitter = m_runningParticleEmittersList.begin(); ppParticleEmitter != m_runningParticleEmittersList.end(); /*++ppParticleEmitter*/) { ParticleEmitter* pParticleEmitter = *ppParticleEmitter; if (!pParticleEmitter) { ppParticleEmitter = m_runningParticleEmittersList.erase( ppParticleEmitter ); continue; } // if (Log::IsZoneEnabled(ZONE_PARTICLES | ZONE_VERBOSE)) // { // char str[1024]; // sprintf(str, "PE: %s", pParticleEmitter->GetName().c_str()); // DebugRender.Text(str, Color::White(), 1.0f, 1.0f); // } if (FAILED(pParticleEmitter->Update( elapsedMS ))) { pParticleEmitter->Stop(); // // NOTE: if you erase a list member while iterating the list, // be sure to properly increment the iterator as seen below. // ppParticleEmitter = m_runningParticleEmittersList.erase( ppParticleEmitter ); } else { ++ppParticleEmitter; } } Exit: return rval; }
RESULT ParticleManager::Init( IN const string& settingsFilename ) { RETAILMSG(ZONE_PARTICLES, "ParticleManager::Init( %s )", settingsFilename.c_str()); RESULT rval = S_OK; char path[MAX_PATH]; // // Create a Settings object and load the file. // Settings mySettings; if ( FAILED(mySettings.Read( settingsFilename )) ) { RETAILMSG(ZONE_ERROR, "ERROR: ParticleManager::Init( %s ): failed to load settings file", settingsFilename.c_str() ); return E_UNEXPECTED; } // // Create each ParticleEmitter. // UINT32 numParticleEmitters = mySettings.GetInt("/ParticleEmitters.NumParticleEmitters"); for (int i = 0; i < numParticleEmitters; ++i) { sprintf(path, "/ParticleEmitters/ParticleEmitter%d", i); ParticleEmitter *pParticleEmitter = new ParticleEmitter(); CPR(pParticleEmitter); string name = mySettings.GetString( string(path) + ".Name" ); string filename = mySettings.GetString( string(path) + ".Filename" ); bool deleteOnFinish = mySettings.GetBool ( string(path) + ".DeleteOnFinish", false ); pParticleEmitter->SetDeleteOnFinish( deleteOnFinish ); if ( FAILED(pParticleEmitter->InitFromFile( filename ))) { RETAILMSG(ZONE_ERROR, "ERROR: ParticleManager::Init( %s ): failed to init ParticleEmitter from file %s", filename.c_str()); // Continue loading other ParticleEmitters rather than aborting. continue; } RETAILMSG(ZONE_INFO, "ParticleEmitter[%4d]: \"%-32s\"", pParticleEmitter->GetID(), pParticleEmitter->GetName().c_str()); CHR(Add(name, pParticleEmitter)); } Exit: return rval; }