Initial commit
This commit is contained in:
379
engines/hpl1/engine/graphics/ParticleSystem3D.cpp
Normal file
379
engines/hpl1/engine/graphics/ParticleSystem3D.cpp
Normal file
@@ -0,0 +1,379 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2010 - Frictional Games
|
||||
*
|
||||
* This file is part of HPL1 Engine.
|
||||
*/
|
||||
|
||||
#include "hpl1/engine/graphics/ParticleSystem3D.h"
|
||||
|
||||
#include "hpl1/engine/impl/tinyXML/tinyxml.h"
|
||||
|
||||
#include "hpl1/engine/graphics/ParticleEmitter3D_UserData.h"
|
||||
|
||||
#include "hpl1/engine/resources/ParticleManager.h"
|
||||
|
||||
#include "hpl1/engine/game/Game.h"
|
||||
|
||||
#include "hpl1/engine/scene/Scene.h"
|
||||
#include "hpl1/engine/scene/World3D.h"
|
||||
|
||||
namespace hpl {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CREATOR
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cParticleSystemData3D::cParticleSystemData3D(const tString &asName,
|
||||
cResources *apResources, cGraphics *apGraphics)
|
||||
: iResourceBase(asName, 0) {
|
||||
mpResources = apResources;
|
||||
mpGraphics = apGraphics;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cParticleSystemData3D::~cParticleSystemData3D() {
|
||||
STLDeleteAll(mvEmitterData);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cParticleSystemData3D::AddEmitterData(iParticleEmitterData *apData) {
|
||||
mvEmitterData.push_back(apData);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cParticleSystem3D *cParticleSystemData3D::Create(tString asName, cVector3f avSize,
|
||||
const cMatrixf &a_mtxTransform) {
|
||||
if (mvEmitterData.empty()) {
|
||||
Warning("Particle system '%s' has no emitters.\n", msName.c_str());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cParticleSystem3D *pPS = hplNew(cParticleSystem3D, (asName, this, mpResources, mpGraphics));
|
||||
pPS->SetMatrix(a_mtxTransform);
|
||||
|
||||
for (size_t i = 0; i < mvEmitterData.size(); ++i) {
|
||||
///////////////////////////
|
||||
// Create and add
|
||||
iParticleEmitter3D *pPE = static_cast<iParticleEmitter3D *>(mvEmitterData[i]->Create(asName, avSize));
|
||||
pPS->AddEmitter(pPE);
|
||||
pPE->SetSystem(pPS);
|
||||
}
|
||||
|
||||
return pPS;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool cParticleSystemData3D::LoadFromFile(const tString &asFile) {
|
||||
TiXmlDocument *pXmlDoc = hplNew(TiXmlDocument, (asFile.c_str()));
|
||||
if (pXmlDoc->LoadFile() == false) {
|
||||
Warning("Couldn't open XML file %s\n", asFile.c_str());
|
||||
hplDelete(pXmlDoc);
|
||||
return false;
|
||||
}
|
||||
|
||||
TiXmlElement *pRootElem = pXmlDoc->RootElement();
|
||||
|
||||
TiXmlElement *pEmitterElem = pRootElem->FirstChildElement("ParticleEmitter");
|
||||
for (; pEmitterElem != NULL; pEmitterElem = pEmitterElem->NextSiblingElement("ParticleEmitter")) {
|
||||
cParticleEmitterData3D_UserData *pPE = hplNew(cParticleEmitterData3D_UserData, ("",
|
||||
mpResources, mpGraphics));
|
||||
|
||||
pPE->LoadFromElement(pEmitterElem);
|
||||
|
||||
mvEmitterData.push_back(pPE);
|
||||
}
|
||||
|
||||
hplDelete(pXmlDoc);
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CONSTRUCTORS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cParticleSystem3D::cParticleSystem3D(const tString asName,
|
||||
cParticleSystemData3D *apData,
|
||||
cResources *apResources, cGraphics *apGraphics)
|
||||
: iEntity3D(asName) {
|
||||
mpResources = apResources;
|
||||
mpGraphics = apGraphics;
|
||||
mpParticleManager = NULL;
|
||||
mpData = apData;
|
||||
|
||||
mbFirstUpdate = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
cParticleSystem3D::~cParticleSystem3D() {
|
||||
for (size_t i = 0; i < mvEmitters.size(); ++i) {
|
||||
hplDelete(mvEmitters[i]);
|
||||
}
|
||||
if (mpParticleManager)
|
||||
mpParticleManager->Destroy(mpData);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PUBLIC METHODS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cParticleSystem3D::SetVisible(bool abVisible) {
|
||||
if (mbIsVisible == abVisible)
|
||||
return;
|
||||
|
||||
mbIsVisible = abVisible;
|
||||
|
||||
for (size_t i = 0; i < mvEmitters.size(); ++i) {
|
||||
mvEmitters[i]->SetVisible(mbIsVisible);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool cParticleSystem3D::IsDead() {
|
||||
size_t lCount = 0;
|
||||
|
||||
for (size_t i = 0; i < mvEmitters.size(); ++i) {
|
||||
iParticleEmitter3D *pPE = mvEmitters[i];
|
||||
|
||||
if (pPE->IsDead())
|
||||
lCount++;
|
||||
}
|
||||
|
||||
if (lCount == mvEmitters.size())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool cParticleSystem3D::IsDying() {
|
||||
size_t lCount = 0;
|
||||
|
||||
for (size_t i = 0; i < mvEmitters.size(); ++i) {
|
||||
iParticleEmitter3D *pPE = mvEmitters[i];
|
||||
|
||||
if (pPE->IsDying())
|
||||
lCount++;
|
||||
}
|
||||
|
||||
if (lCount == mvEmitters.size())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cParticleSystem3D::Kill() {
|
||||
SetIsSaved(false);
|
||||
for (size_t i = 0; i < mvEmitters.size(); ++i) {
|
||||
iParticleEmitter3D *pPE = mvEmitters[i];
|
||||
|
||||
pPE->Kill();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cParticleSystem3D::KillInstantly() {
|
||||
SetIsSaved(false);
|
||||
for (size_t i = 0; i < mvEmitters.size(); ++i) {
|
||||
iParticleEmitter3D *pPE = mvEmitters[i];
|
||||
|
||||
pPE->KillInstantly();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cParticleSystem3D::UpdateLogic(float afTimeStep) {
|
||||
if (IsActive() == false)
|
||||
return;
|
||||
|
||||
for (size_t i = 0; i < mvEmitters.size(); ++i) {
|
||||
iParticleEmitter3D *pPE = mvEmitters[i];
|
||||
|
||||
//////////////////////////
|
||||
// Warm Up
|
||||
if (mbFirstUpdate) {
|
||||
iParticleEmitterData *pData = mpData->GetEmitterData((int)i);
|
||||
|
||||
if (pData->GetWarmUpTime() > 0) {
|
||||
float fTime = pData->GetWarmUpTime();
|
||||
float fStepSize = 1.0f / pData->GetWarmUpStepsPerSec();
|
||||
|
||||
while (fTime > 0) {
|
||||
pPE->UpdateLogic(fStepSize);
|
||||
fTime -= fStepSize;
|
||||
}
|
||||
}
|
||||
mbFirstUpdate = false;
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
// Update
|
||||
pPE->UpdateLogic(afTimeStep);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cParticleSystem3D::AddEmitter(iParticleEmitter3D *apEmitter) {
|
||||
mvEmitters.push_back(apEmitter);
|
||||
|
||||
AddChild(apEmitter);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
iParticleEmitter3D *cParticleSystem3D::GetEmitter(int alIdx) {
|
||||
return mvEmitters[alIdx];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
int cParticleSystem3D::GetEmitterNum() {
|
||||
return (int)mvEmitters.size();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// PRIVATE METHODS
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SAVE OBJECT STUFF
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
kBeginSerializeBase(cSaveData_ParticleEmitter3D)
|
||||
kSerializeVar(mbActive, eSerializeType_Bool)
|
||||
kSerializeVar(mbDying, eSerializeType_Bool)
|
||||
kEndSerialize()
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
kBeginSerialize(cSaveData_cParticleSystem3D, cSaveData_iEntity3D)
|
||||
kSerializeVar(msDataName, eSerializeType_String)
|
||||
kSerializeVar(mvDataSize, eSerializeType_Vector3f)
|
||||
|
||||
kSerializeClassContainer(mvEmitters, cSaveData_ParticleEmitter3D, eSerializeType_Class)
|
||||
kEndSerialize()
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
iSaveObject *cSaveData_cParticleSystem3D::CreateSaveObject(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame) {
|
||||
cWorld3D *pWorld = apGame->GetScene()->GetWorld3D();
|
||||
|
||||
cParticleSystem3D *pPS = pWorld->CreateParticleSystem(msName, msDataName, mvDataSize,
|
||||
m_mtxLocalTransform);
|
||||
|
||||
return pPS;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
int cSaveData_cParticleSystem3D::GetSaveCreatePrio() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
iSaveData *cParticleSystem3D::CreateSaveData() {
|
||||
return hplNew(cSaveData_cParticleSystem3D, ());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cParticleSystem3D::SaveToSaveData(iSaveData *apSaveData) {
|
||||
kSaveData_SaveToBegin(cParticleSystem3D);
|
||||
|
||||
kSaveData_SaveTo(msDataName);
|
||||
kSaveData_SaveTo(mvDataSize);
|
||||
|
||||
pData->mvEmitters.Resize(GetEmitterNum());
|
||||
for (int i = 0; i < GetEmitterNum(); ++i) {
|
||||
iParticleEmitter3D *pPE = GetEmitter(i);
|
||||
|
||||
pData->mvEmitters[i].mbDying = pPE->IsDying();
|
||||
pData->mvEmitters[i].mbActive = pPE->IsActive();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cParticleSystem3D::LoadFromSaveData(iSaveData *apSaveData) {
|
||||
kSaveData_LoadFromBegin(cParticleSystem3D);
|
||||
|
||||
kSaveData_LoadFrom(msDataName);
|
||||
kSaveData_LoadFrom(mvDataSize);
|
||||
|
||||
if (GetEmitterNum() != (int)pData->mvEmitters.Size()) {
|
||||
Error("Saved emitter number in %s/%d does not match loaded, killing system!\n",
|
||||
GetName().c_str(),
|
||||
GetSaveObjectId());
|
||||
|
||||
for (int i = 0; i < GetEmitterNum(); ++i) {
|
||||
iParticleEmitter3D *pPE = GetEmitter(i);
|
||||
pPE->KillInstantly();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < GetEmitterNum(); ++i) {
|
||||
iParticleEmitter3D *pPE = GetEmitter(i);
|
||||
|
||||
pPE->SetActive(pData->mvEmitters[i].mbActive);
|
||||
|
||||
if (pData->mvEmitters[i].mbDying)
|
||||
pPE->KillInstantly();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void cParticleSystem3D::SaveDataSetup(cSaveObjectHandler *apSaveObjectHandler, cGame *apGame) {
|
||||
kSaveData_SetupBegin(cParticleSystem3D);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
} // namespace hpl
|
||||
Reference in New Issue
Block a user