From 4a251fe7aee4f968766763d555f18775c676486c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=B5=A9=E5=A4=A9?= <88096545+OVOAOVO@users.noreply.github.com> Date: Tue, 12 Dec 2023 22:34:49 +0800 Subject: [PATCH] init EffekseerProducer about parsing sprite effect node (#250) --- .../Effekseer/EffekseerToCD/Main.cpp | 2 +- .../EffekseerProducerImpl.cpp | 175 ++++++++++++++++-- .../EffekseerProducer/EffekseerProducerImpl.h | 28 +++ private/Scene/ParticleEmitter.cpp | 170 +++++++++++++++++ private/Scene/ParticleEmitterImpl.cpp | 17 ++ private/Scene/ParticleEmitterImpl.h | 98 ++++++++++ private/Scene/SceneDatabase.cpp | 38 ++++ private/Scene/SceneDatabaseImpl.cpp | 29 +++ private/Scene/SceneDatabaseImpl.h | 30 ++- public/Scene/ObjectID.h | 1 + public/Scene/ObjectType.h | 1 + public/Scene/ParticleEmitter.h | 79 ++++++++ public/Scene/SceneDatabase.h | 10 + 13 files changed, 660 insertions(+), 18 deletions(-) create mode 100644 private/Scene/ParticleEmitter.cpp create mode 100644 private/Scene/ParticleEmitterImpl.cpp create mode 100644 private/Scene/ParticleEmitterImpl.h create mode 100644 public/Scene/ParticleEmitter.h diff --git a/examples/Prototype/Effekseer/EffekseerToCD/Main.cpp b/examples/Prototype/Effekseer/EffekseerToCD/Main.cpp index ddc43f5f..8b6f952a 100644 --- a/examples/Prototype/Effekseer/EffekseerToCD/Main.cpp +++ b/examples/Prototype/Effekseer/EffekseerToCD/Main.cpp @@ -18,7 +18,7 @@ int main(int argc, char** argv) PerformanceProfiler profiler("AssetPipeline"); // TODO : how to input char16_t string from argv? - const char16_t* pInputFilePath = u"S:/Effekseer/Examples/Resources/Laser01.efkefc"; + const char16_t* pInputFilePath = u"D:/Effekseer/sample/03_01_Sample/03_01_Sample/effect.efkefc"; const char* pOutputFilePath = argv[2]; EffekseerProducer producer(pInputFilePath); CDConsumer consumer(pOutputFilePath); diff --git a/private/Producers/EffekseerProducer/EffekseerProducerImpl.cpp b/private/Producers/EffekseerProducer/EffekseerProducerImpl.cpp index eaa20744..8c0fad37 100644 --- a/private/Producers/EffekseerProducer/EffekseerProducerImpl.cpp +++ b/private/Producers/EffekseerProducer/EffekseerProducerImpl.cpp @@ -1,37 +1,182 @@ #include "EffekseerProducerImpl.h" +#include "Producers/EffekseerProducer/EffekseerProducer.h" + #include #include +#include + namespace cdtools { +static std::map EffectNodeTypeMapping = { + { Effekseer::EffectNodeType::Root, cd::ParticleEmitterType::Root }, + { Effekseer::EffectNodeType::NoneType, cd::ParticleEmitterType::None }, + { Effekseer::EffectNodeType::Sprite, cd::ParticleEmitterType::Sprite }, + { Effekseer::EffectNodeType::Ribbon, cd::ParticleEmitterType::Ribbon }, + { Effekseer::EffectNodeType::Ring, cd::ParticleEmitterType::Ring }, + { Effekseer::EffectNodeType::Model, cd::ParticleEmitterType::Model }, + { Effekseer::EffectNodeType::Track, cd::ParticleEmitterType::Track }, +}; + EffekseerProducerImpl::EffekseerProducerImpl(const char16_t* pFilePath) : m_pFilePath(pFilePath) { } +void EffekseerProducerImpl::PushAllColor(Effekseer::AllTypeColorParameter* pAllColor) +{ + if (pAllColor->type == pAllColor->Fixed) + { + m_fixedColor.push_back(pAllColor->fixed.all); + } + else if (pAllColor->type == pAllColor->Random) + { + + } + else if (pAllColor->type == pAllColor->Easing) + { + + } + //TODO : there still have some num to analysis +} + +void EffekseerProducerImpl::JudgeRotationType(Effekseer::RotationParameter* pParameter) +{ + if (pParameter->RotationType == Effekseer::ParameterRotationType::ParameterRotationType_Fixed) + { + m_fixedRotation.push_back(pParameter->RotationFixed.Position); + } + else if (pParameter->RotationType == Effekseer::ParameterRotationType::ParameterRotationType_PVA) + { + + } + else if (pParameter->RotationType == Effekseer::ParameterRotationType::ParameterRotationType_Easing) + { + + } + ///TODO: there still some num to analysis +} + +void EffekseerProducerImpl::PushRotate(Effekseer::EffectNodeSprite* pNode) +{ + + if (pNode->Billboard == Effekseer::BillboardType::Billboard) + { + //NO Rotation + JudgeRotationType(&pNode->RotationParam); + } + else if (pNode->Billboard == Effekseer::BillboardType::RotatedBillboard) + { + //Z Rotation + JudgeRotationType(&pNode->RotationParam); + } + else if (pNode->Billboard == Effekseer::BillboardType::YAxisFixed) + { + //Y Rotation + JudgeRotationType(&pNode->RotationParam); + } + else if (pNode->Billboard == Effekseer::BillboardType::Fixed) + { + // XYZ Rotation + JudgeRotationType(&pNode->RotationParam); + } +} + +void EffekseerProducerImpl::PushScale(Effekseer::EffectNodeSprite* pNode) +{ + if (pNode->ScalingParam.ScalingType == Effekseer::ParameterScalingType::ParameterScalingType_Fixed) + { + m_fixedScale.push_back(pNode->ScalingParam.ScalingFixed.Position); + } + else if (pNode->ScalingParam.ScalingType == Effekseer::ParameterScalingType::ParameterScalingType_PVA) + { + + } + ///TODO: there still some num to analysis +} + +void EffekseerProducerImpl::TraverseNodeRecursively(Effekseer::EffectNode* pNode) +{ + Effekseer::EffectNodeType nodeType = pNode->GetType(); + if (Effekseer::EffectNodeType::Sprite == nodeType) + { + //PVA + m_particleType.push_back(nodeType); + auto* pSpriteNode = static_cast(pNode); + m_particlePos.push_back(pSpriteNode->TranslationParam.TranslationPVA.location); + m_particleVelocity.push_back(pSpriteNode->TranslationParam.TranslationPVA.velocity); + m_particleAccelerate.push_back(pSpriteNode->TranslationParam.TranslationPVA.acceleration); + PushAllColor(&pSpriteNode->SpriteAllColor); + PushRotate(pSpriteNode); + PushScale(pSpriteNode); + return; + } + else if (Effekseer::EffectNodeType::Ribbon == nodeType) + { + + } + else if (Effekseer::EffectNodeType::Track == nodeType) + { + + } + else if (Effekseer::EffectNodeType::Ring == nodeType) + { + + } + else if (Effekseer::EffectNodeType::Model == nodeType) + { + + } + + + int childNodeCount = pNode->GetChildrenCount(); + for (int childIndex = 0; childIndex < childNodeCount; ++childIndex) + { + TraverseNodeRecursively(pNode->GetChild(childIndex)); + } +} + + void EffekseerProducerImpl::Execute(cd::SceneDatabase* pSceneDatabase) { auto efkManager = ::Effekseer::Manager::Create(8000); auto effect = Effekseer::Effect::Create(efkManager, m_pFilePath); auto* pEffectData = effect.Get(); - // Mesh - pEffectData->GetProceduralModelCount(); - pEffectData->GetWaveCount(); - - // Materials and ParticleEmitter - pEffectData->GetMaterialCount(); - pEffectData->GetLoadingParameter(); - pEffectData->GetDefaultDynamicInputs(); - - // Texture - pEffectData->GetColorImageCount(); - pEffectData->GetDistortionImageCount(); - - // Track - pEffectData->GetCurveCount(); + //ID name + const char16_t* pEffectName = pEffectData->GetName(); + std::wstring_convert, char16_t> converter; + std::u16string u16str = pEffectName; + std::string str = converter.to_bytes(u16str); + const char* pAllParticleEmitterName = str.c_str(); + + // pos velocity scale + // TODO : check other properties. + TraverseNodeRecursively(pEffectData->GetRoot()); + for (int i = 0; i < pEffectData->GetRoot()->GetChildrenCount(); i++) + { + cd::ParticleEmitterID::ValueType particleEmitterHash = cd::StringHash(pAllParticleEmitterName + i); + cd::ParticleEmitterID particleEmitterID = m_particleEmitterIDGenerator.AllocateID(particleEmitterHash); + + cd::ParticleEmitter particleEmitter(particleEmitterID, std::format("{}{}", pAllParticleEmitterName, i).c_str()); + particleEmitter.SetType(EffectNodeTypeMapping[static_cast(m_particleType[i])]); + particleEmitter.SetPosition(MeanXYZ(m_particlePos[i].max, m_particlePos[i].min)); + particleEmitter.SetVelocity(MeanXYZ(m_particleVelocity[i].max, m_particleVelocity[i].min)); + particleEmitter.SetAccelerate(MeanXYZ(m_particleAccelerate[i].max, m_particleAccelerate[i].min)); + particleEmitter.SetColor(cd::Vec4f(m_fixedColor[i].R, m_fixedColor[i].G, m_fixedColor[i].B, m_fixedColor[i].A)); + particleEmitter.SetFixedRotation(cd::Vec3f(m_fixedRotation[i].X, m_fixedRotation[i].Y, m_fixedRotation[i].Z)); + particleEmitter.SetFixedScale(cd::Vec3f(m_fixedScale[i].X, m_fixedScale[i].Y, m_fixedScale[i].Z)); + + pSceneDatabase->AddParticleEmitter(cd::MoveTemp(particleEmitter)); + } + //// Mesh + //auto a = pEffectData->GetName(); + + //auto b = pEffectData->GetColorImageCount(); + // + //auto c = pEffectData->GetColorImagePath(0); } } \ No newline at end of file diff --git a/private/Producers/EffekseerProducer/EffekseerProducerImpl.h b/private/Producers/EffekseerProducer/EffekseerProducerImpl.h index 7bd220cb..7645f814 100644 --- a/private/Producers/EffekseerProducer/EffekseerProducerImpl.h +++ b/private/Producers/EffekseerProducer/EffekseerProducerImpl.h @@ -1,8 +1,14 @@ #pragma once #include "Base/Template.h" +#include "Hashers/StringHash.hpp" +#include "Scene/ObjectIDGenerator.h" #include "Scene/SceneDatabase.h" +#include "Effekseer/Effekseer.EffectImplemented.h" +#include "Effekseer/Effekseer.EffectNode.h" +#include "Effekseer/Effekseer.EffectNodeSprite.h" + namespace cdtools { @@ -17,10 +23,32 @@ class EffekseerProducerImpl final EffekseerProducerImpl& operator=(EffekseerProducerImpl&&) = delete; ~EffekseerProducerImpl() = default; + void TraverseNodeRecursively(Effekseer::EffectNode* pNode); + + void PushAllColor(Effekseer::AllTypeColorParameter* AllColor); + + void PushRotate(Effekseer::EffectNodeSprite* pNode); + + void PushScale(Effekseer::EffectNodeSprite* pNode); + + void JudgeRotationType(Effekseer::RotationParameter* Type); + void Execute(cd::SceneDatabase* pSceneDatabase); + cd::Vec3f MeanXYZ(Effekseer::vector3d max, Effekseer::vector3d min) { return cd::Vec3f(((max.x + min.x) / 2), ((max.y + min.y) / 2), ((max.z + min.z) / 2)); } + cd::Vec3f DevXYZ(Effekseer::vector3d max, Effekseer::vector3d min) { return cd::Vec3f(((max.x - min.x) / 2), ((max.y - min.y) / 2), ((max.z - min.z) / 2)); } + private: const char16_t* m_pFilePath; + std::vector m_particleType; + std::vector m_particlePos; + std::vector m_particleVelocity; + std::vector m_particleAccelerate; + std::vector m_fixedColor; + std::vector m_fixedRotation; + std::vector m_fixedScale; + + cd::ObjectIDGenerator m_particleEmitterIDGenerator; }; } \ No newline at end of file diff --git a/private/Scene/ParticleEmitter.cpp b/private/Scene/ParticleEmitter.cpp new file mode 100644 index 00000000..0aa5b068 --- /dev/null +++ b/private/Scene/ParticleEmitter.cpp @@ -0,0 +1,170 @@ +#include "ParticleEmitterImpl.h" + +#include "Scene/ParticleEmitter.h" + +namespace cd +{ + +ParticleEmitter::ParticleEmitter(InputArchive& inputArchive) +{ + m_pParticleEmitterImpl = new ParticleEmitterImpl(inputArchive); +} + +ParticleEmitter::ParticleEmitter(InputArchiveSwapBytes& inputArchive) +{ + m_pParticleEmitterImpl = new ParticleEmitterImpl(inputArchive); +} + +ParticleEmitter::ParticleEmitter(ParticleEmitterID id, const char* pName) +{ + m_pParticleEmitterImpl = new ParticleEmitterImpl(id, cd::MoveTemp(pName)); +} + +ParticleEmitter::ParticleEmitter(ParticleEmitter&& rhs) +{ + *this = cd::MoveTemp(rhs); +} + +ParticleEmitter& ParticleEmitter::operator=(ParticleEmitter&& rhs) +{ + std::swap(m_pParticleEmitterImpl, rhs.m_pParticleEmitterImpl); + return *this; +} + +ParticleEmitter::~ParticleEmitter() +{ + if (m_pParticleEmitterImpl) + { + delete m_pParticleEmitterImpl; + m_pParticleEmitterImpl = nullptr; + } +} + +PIMPL_ID_APIS(ParticleEmitter); +PIMPL_NAME_APIS(ParticleEmitter); + +void ParticleEmitter::SetType(ParticleEmitterType type) +{ + m_pParticleEmitterImpl->SetType(type); +} + +ParticleEmitterType ParticleEmitter::GetType() const +{ + return m_pParticleEmitterImpl->GetType(); +} + +void ParticleEmitter::SetPosition(cd::Vec3f position) +{ + m_pParticleEmitterImpl->SetPosition(cd::MoveTemp(position)); +} + +Vec3f& ParticleEmitter::GetPosition() +{ + return m_pParticleEmitterImpl->GetPosition(); +} + +const cd::Vec3f& ParticleEmitter::GetPosition() const +{ + return m_pParticleEmitterImpl->GetPosition(); +} + +void ParticleEmitter::SetVelocity(cd::Vec3f velocity) +{ + m_pParticleEmitterImpl->SetVelocity(cd::MoveTemp(velocity)); +} + +Vec3f& ParticleEmitter::GetVelocity() +{ + return m_pParticleEmitterImpl->GetVelocity(); +} + +const cd::Vec3f& ParticleEmitter::GetVelocity() const +{ + return m_pParticleEmitterImpl->GetVelocity(); +} + +void ParticleEmitter::SetAccelerate(cd::Vec3f accelerate) +{ + m_pParticleEmitterImpl->SetAccelerate(cd::MoveTemp(accelerate)); +} + +Vec3f& ParticleEmitter::GetAccelerate() +{ + return m_pParticleEmitterImpl->GetAccelerate(); +} + +const cd::Vec3f& ParticleEmitter::GetAccelerate() const +{ + return m_pParticleEmitterImpl->GetAccelerate(); +} + +void ParticleEmitter::SetColor(cd::Vec4f color) +{ + m_pParticleEmitterImpl->SetColor(cd::MoveTemp(color)); +} + +Vec4f& ParticleEmitter::GetColor() +{ + return m_pParticleEmitterImpl->GetColor(); +} + +const cd::Vec4f& ParticleEmitter::GetColor() const +{ + return m_pParticleEmitterImpl->GetColor(); +} + +void ParticleEmitter::SetFixedRotation(cd::Vec3f rotation) +{ + m_pParticleEmitterImpl->SetFixedRotation(cd::MoveTemp(rotation)); +} + +Vec3f& ParticleEmitter::GetFixedRotation() +{ + return m_pParticleEmitterImpl->GetFixedRotation(); +} + +const cd::Vec3f& ParticleEmitter::GetFixedRotation() const +{ + return m_pParticleEmitterImpl->GetFixedRotation(); +} + +void ParticleEmitter::SetFixedScale(cd::Vec3f scale) +{ + m_pParticleEmitterImpl->SetFixedScale(cd::MoveTemp(scale)); +} + +Vec3f& ParticleEmitter::GetFixedScale() +{ + return m_pParticleEmitterImpl->GetFixedScale(); +} + +const cd::Vec3f& ParticleEmitter::GetFixedScale() const +{ + return m_pParticleEmitterImpl->GetFixedScale(); +} + +ParticleEmitter& ParticleEmitter::operator<<(InputArchive& inputArchive) +{ + *m_pParticleEmitterImpl << inputArchive; + return *this; +} + +ParticleEmitter& ParticleEmitter::operator<<(InputArchiveSwapBytes& inputArchive) +{ + *m_pParticleEmitterImpl << inputArchive; + return *this; +} + +const ParticleEmitter& ParticleEmitter::operator>>(OutputArchive& outputArchive) const +{ + *m_pParticleEmitterImpl >> outputArchive; + return *this; +} + +const ParticleEmitter& ParticleEmitter::operator>>(OutputArchiveSwapBytes& outputArchive) const +{ + *m_pParticleEmitterImpl >> outputArchive; + return *this; +} + +} \ No newline at end of file diff --git a/private/Scene/ParticleEmitterImpl.cpp b/private/Scene/ParticleEmitterImpl.cpp new file mode 100644 index 00000000..bddafe40 --- /dev/null +++ b/private/Scene/ParticleEmitterImpl.cpp @@ -0,0 +1,17 @@ +#include "ParticleEmitterImpl.h" + +namespace cd +{ + +ParticleEmitterImpl::ParticleEmitterImpl(ParticleEmitterID id, std::string name) +{ + Init(id, cd::MoveTemp(name)); +} + +void ParticleEmitterImpl::Init(ParticleEmitterID id, std::string name) +{ + m_id = id; + m_name = cd::MoveTemp(name); +} + +} \ No newline at end of file diff --git a/private/Scene/ParticleEmitterImpl.h b/private/Scene/ParticleEmitterImpl.h new file mode 100644 index 00000000..091ab62d --- /dev/null +++ b/private/Scene/ParticleEmitterImpl.h @@ -0,0 +1,98 @@ +#pragma once + +#include "Base/Template.h" +#include "IO/InputArchive.hpp" +#include "IO/OutputArchive.hpp" +#include "Scene/ObjectID.h" +#include "Scene/ParticleEmitter.h" +#include "Scene/VertexFormat.h" + +namespace cd +{ + +class ParticleEmitterImpl final +{ +public: + ParticleEmitterImpl() = delete; + template + explicit ParticleEmitterImpl(TInputArchive& inputArchive) + { + *this << inputArchive; + } + explicit ParticleEmitterImpl(ParticleEmitterID id, std::string name); + ParticleEmitterImpl(const ParticleEmitterImpl&) = default; + ParticleEmitterImpl& operator=(const ParticleEmitterImpl&) = default; + ParticleEmitterImpl(ParticleEmitterImpl&&) = default; + ParticleEmitterImpl& operator=(ParticleEmitterImpl&&) = default; + ~ParticleEmitterImpl() = default; + + void Init(ParticleEmitterID id, std::string name); + + IMPLEMENT_ID_APIS(ParticleEmitterID, m_id); + IMPLEMENT_NAME_APIS(m_name); + + void SetType(ParticleEmitterType type) { m_type = type; } + ParticleEmitterType GetType() const { return m_type; } + + void SetPosition(Vec3f position) { m_position = MoveTemp(position); } + Vec3f& GetPosition() { return m_position; } + const Vec3f& GetPosition() const { return m_position; } + + void SetVelocity(Vec3f velocity) { m_velocity = MoveTemp(velocity); } + Vec3f& GetVelocity() { return m_velocity; } + const Vec3f& GetVelocity() const { return m_velocity; } + + void SetAccelerate(Vec3f accelerate) { m_accelerate = MoveTemp(accelerate); } + Vec3f& GetAccelerate() { return m_accelerate; } + const Vec3f& GetAccelerate() const { return m_accelerate; } + + void SetColor(Vec4f color) { m_color = MoveTemp(color); } + Vec4f& GetColor() { return m_color; } + const Vec4f& GetColor() const { return m_color; } + + void SetFixedRotation(Vec3f rotation) { m_fixedRotation = MoveTemp(rotation); } + Vec3f& GetFixedRotation() { return m_fixedRotation; } + const Vec3f& GetFixedRotation() const { return m_fixedRotation; } + + void SetFixedScale(Vec3f scale) { m_fixedScale = MoveTemp(scale); } + Vec3f& GetFixedScale() { return m_fixedScale; } + const Vec3f& GetFixedScale() const { return m_fixedScale; } + + template + ParticleEmitterImpl& operator<<(TInputArchive& inputArchive) + { + uint32_t emitterID; + std::string emitterName; + uint32_t emitterType; + inputArchive >> emitterID >> emitterName >> emitterType; + Init(ParticleEmitterID(emitterID), cd::MoveTemp(emitterName)); + SetType(static_cast(emitterType)); + inputArchive >> GetPosition() >> GetVelocity() >> GetAccelerate() + >> GetColor() >> GetFixedRotation() >> GetFixedScale(); + return *this; + } + + template + const ParticleEmitterImpl& operator>>(TOutputArchive& outputArchive) const + { + outputArchive << GetID().Data() << GetName() << static_cast(GetType()) + << GetPosition() << GetVelocity() << GetAccelerate() + << GetColor() << GetFixedRotation() << GetFixedScale(); + return *this; + } + +private: + ParticleEmitterID m_id; + std::string m_name; + + cd::VertexFormat m_vertexFormat; + cd::ParticleEmitterType m_type; + cd::Vec3f m_position; + cd::Vec3f m_velocity; + cd::Vec3f m_accelerate; + cd::Vec4f m_color; + cd::Vec3f m_fixedRotation; + cd::Vec3f m_fixedScale; +}; + +} \ No newline at end of file diff --git a/private/Scene/SceneDatabase.cpp b/private/Scene/SceneDatabase.cpp index 503731ea..6f5dbdc1 100644 --- a/private/Scene/SceneDatabase.cpp +++ b/private/Scene/SceneDatabase.cpp @@ -491,6 +491,44 @@ uint32_t SceneDatabase::GetTrackCount() const return m_pSceneDatabaseImpl->GetTrackCount(); } +/////////////////////////////////////////////////////////////////// +// ParticleEmitter +/////////////////////////////////////////////////////////////////// +void SceneDatabase::AddParticleEmitter(ParticleEmitter emitter) +{ + return m_pSceneDatabaseImpl->AddParticleEmitter(cd::MoveTemp(emitter)); +} + +std::vector& SceneDatabase::GetParticleEmitters() +{ + return m_pSceneDatabaseImpl->GetParticleEmitters(); +} + +const std::vector& SceneDatabase::GetParticleEmitters() const +{ + return m_pSceneDatabaseImpl->GetParticleEmitters(); +} + +void SceneDatabase::SetParticleEmitterCount(uint32_t emitterCount) +{ + return m_pSceneDatabaseImpl->SetParticleEmitterCount(emitterCount); +} + +ParticleEmitter& SceneDatabase::GetParticleEmitter(uint32_t index) +{ + return m_pSceneDatabaseImpl->GetParticleEmitter(index); +} + +const ParticleEmitter& SceneDatabase::GetParticleEmitter(uint32_t index) const +{ + return m_pSceneDatabaseImpl->GetParticleEmitter(index); +} + +uint32_t SceneDatabase::GetParticleEmitterCount() const +{ + return m_pSceneDatabaseImpl->GetParticleEmitterCount(); +} + /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// void SceneDatabase::Dump() const diff --git a/private/Scene/SceneDatabaseImpl.cpp b/private/Scene/SceneDatabaseImpl.cpp index b620c313..7cdbb439 100644 --- a/private/Scene/SceneDatabaseImpl.cpp +++ b/private/Scene/SceneDatabaseImpl.cpp @@ -158,6 +158,7 @@ void SceneDatabaseImpl::Dump() const printf("\tBone count : %d\n", GetBoneCount()); printf("\tAnimation count : %d\n", GetAnimationCount()); printf("\tTrack count : %d\n", GetTrackCount()); + printf("\tParticleEmitter count : %d\n", GetParticleEmitterCount()); if (GetNodeCount() > 0U) { printf("\n"); @@ -358,6 +359,22 @@ void SceneDatabaseImpl::Dump() const details::Dump("\tFirstScaleKey", track.GetScaleKeys()[0].GetValue()); } } + + if (GetParticleEmitterCount() > 0U) + { + printf("\n"); + for (const auto& particle : GetParticleEmitters()) + { + printf("[ParticleEmitter %u] Name : %s\n", particle.GetID().Data(), particle.GetName()); + printf("\tType : %s\n", nameof::nameof_enum(particle.GetType()).data()); + details::Dump("\tPosition", particle.GetPosition()); + details::Dump("\tVelocity", particle.GetVelocity()); + details::Dump("\tAccelerate", particle.GetAccelerate()); + details::Dump("\tColor", particle.GetColor()); + details::Dump("\tRotation", particle.GetFixedRotation()); + details::Dump("\tScale", particle.GetFixedScale()); + } + } } void SceneDatabaseImpl::Validate() const @@ -441,6 +458,12 @@ void SceneDatabaseImpl::Validate() const //assert(GetBoneByName(track.GetName())); CheckKeyFramesTimeOrder(track); } + + for (uint32_t particleIndex = 0U; particleIndex < GetParticleEmitterCount(); ++particleIndex) + { + const cd::ParticleEmitter& PE = GetParticleEmitter(particleIndex); + assert(particleIndex == PE.GetID().Data()); + } } void SceneDatabaseImpl::Merge(cd::SceneDatabaseImpl&& sceneDatabaseImpl) @@ -544,6 +567,12 @@ void SceneDatabaseImpl::Merge(cd::SceneDatabaseImpl&& sceneDatabaseImpl) light.SetID(GetCameraCount()); AddLight(cd::MoveTemp(light)); } + + for (auto& particle : sceneDatabaseImpl.GetParticleEmitters()) + { + particle.SetID(GetParticleEmitterCount()); + AddParticleEmitter(cd::MoveTemp(particle)); + } } void SceneDatabaseImpl::UpdateAABB() diff --git a/private/Scene/SceneDatabaseImpl.h b/private/Scene/SceneDatabaseImpl.h index 2b3a2e78..060fefe8 100644 --- a/private/Scene/SceneDatabaseImpl.h +++ b/private/Scene/SceneDatabaseImpl.h @@ -13,6 +13,7 @@ #include "Scene/Node.h" #include "Scene/Texture.h" #include "Scene/Track.h" +#include "Scene/ParticleEmitter.h" #include #include @@ -147,6 +148,15 @@ class SceneDatabaseImpl const Track* GetTrackByName(const char* pName) const; uint32_t GetTrackCount() const { return static_cast(m_tracks.size()); } + // ParticleEmitter + void AddParticleEmitter(ParticleEmitter emitter) { m_particleEmitters.emplace_back(MoveTemp(emitter)); } + std::vector& GetParticleEmitters() { return m_particleEmitters; } + const std::vector& GetParticleEmitters() const { return m_particleEmitters; } + void SetParticleEmitterCount(uint32_t count) { m_particleEmitters.reserve(count); } + ParticleEmitter& GetParticleEmitter(uint32_t index) { return m_particleEmitters[index]; } + const ParticleEmitter& GetParticleEmitter(uint32_t index) const { return m_particleEmitters[index]; } + uint32_t GetParticleEmitterCount() const { return static_cast(m_particleEmitters.size()); } + void Dump() const; void Validate() const; void Merge(cd::SceneDatabaseImpl&& sceneDatabaseImpl); @@ -181,11 +191,12 @@ class SceneDatabaseImpl uint32_t animationCount; uint32_t trackCount; uint32_t morphCount; + uint32_t particleCount; inputArchive >> nodeCount >> meshCount >> morphCount >> materialCount >> textureCount >> cameraCount >> lightCount - >> boneCount >> animationCount >> trackCount; + >> boneCount >> animationCount >> trackCount >> particleCount; SetNodeCount(nodeCount); SetMeshCount(meshCount); @@ -197,6 +208,7 @@ class SceneDatabaseImpl SetBoneCount(boneCount); SetAnimationCount(animationCount); SetTrackCount(trackCount); + SetParticleEmitterCount(particleCount); for (uint32_t nodeIndex = 0U; nodeIndex < nodeCount; ++nodeIndex) { @@ -248,6 +260,11 @@ class SceneDatabaseImpl AddTrack(Track(inputArchive)); } + for (uint32_t particleIndex = 0U; particleIndex < particleCount; ++particleIndex) + { + AddParticleEmitter(ParticleEmitter(inputArchive)); + } + return *this; } @@ -258,7 +275,7 @@ class SceneDatabaseImpl << GetNodeCount() << GetMeshCount() << GetMorphCount() << GetMaterialCount() << GetTextureCount() << GetCameraCount() << GetLightCount() - << GetBoneCount() << GetAnimationCount() << GetTrackCount(); + << GetBoneCount() << GetAnimationCount() << GetTrackCount()<> outputArchive; } + for (uint32_t particleIndex = 0U; particleIndex < GetParticleEmitterCount(); ++particleIndex) + { + const ParticleEmitter& particle = GetParticleEmitter(particleIndex); + particle >> outputArchive; + } + return *this; } @@ -348,6 +371,9 @@ class SceneDatabaseImpl std::vector m_bones; std::vector m_animations; std::vector m_tracks; + + //Particle data + std::vector m_particleEmitters; }; } \ No newline at end of file diff --git a/public/Scene/ObjectID.h b/public/Scene/ObjectID.h index 160e4dde..800edc4f 100644 --- a/public/Scene/ObjectID.h +++ b/public/Scene/ObjectID.h @@ -69,6 +69,7 @@ using BoneID = ObjectID; using AnimationID = ObjectID; using TrackID = ObjectID; using MorphID = ObjectID; +using ParticleEmitterID = ObjectID; static_assert(sizeof(VertexID) == sizeof(uint32_t)); diff --git a/public/Scene/ObjectType.h b/public/Scene/ObjectType.h index e639f291..42548f7d 100644 --- a/public/Scene/ObjectType.h +++ b/public/Scene/ObjectType.h @@ -20,6 +20,7 @@ enum class ObjectType Animation, Track, Morph, + ParticleEmitter }; } \ No newline at end of file diff --git a/public/Scene/ParticleEmitter.h b/public/Scene/ParticleEmitter.h new file mode 100644 index 00000000..86b7a0a5 --- /dev/null +++ b/public/Scene/ParticleEmitter.h @@ -0,0 +1,79 @@ +#pragma once + +#include "Base/Export.h" +#include "IO/InputArchive.hpp" +#include "IO/OutputArchive.hpp" +#include "Scene/ObjectID.h" + +namespace cd +{ + +enum class ParticleEmitterType +{ + Root, + None, + Sprite, + Ribbon, + Ring, + Model, + Track +}; + +class ParticleEmitterImpl; + +class CORE_API ParticleEmitter final +{ +public: + static const char* GetClassName() { return "ParticleEmitter"; } + +public: + ParticleEmitter() = delete; + explicit ParticleEmitter(InputArchive& inputArchive); + explicit ParticleEmitter(InputArchiveSwapBytes& inputArchive); + explicit ParticleEmitter(ParticleEmitterID id, const char* pName); + ParticleEmitter(const ParticleEmitter&) = delete; + ParticleEmitter& operator=(const ParticleEmitter&) = delete; + ParticleEmitter(ParticleEmitter&&); + ParticleEmitter& operator=(ParticleEmitter&&); + ~ParticleEmitter(); + + EXPORT_OBJECT_ID_APIS(ParticleEmitterID); + EXPORT_NAME_APIS(); + + void SetType(ParticleEmitterType type); + ParticleEmitterType GetType() const; + + void SetPosition(cd::Vec3f position); + Vec3f& GetPosition(); + const cd::Vec3f& GetPosition() const; + + void SetVelocity(cd::Vec3f velocity); + Vec3f& GetVelocity(); + const cd::Vec3f& GetVelocity() const; + + void SetAccelerate(cd::Vec3f accelerate); + Vec3f& GetAccelerate(); + const cd::Vec3f& GetAccelerate() const; + + void SetColor(cd::Vec4f color); + Vec4f& GetColor(); + const cd::Vec4f& GetColor() const; + + void SetFixedRotation(cd::Vec3f rotation); + Vec3f& GetFixedRotation(); + const cd::Vec3f& GetFixedRotation() const; + + void SetFixedScale(cd::Vec3f scale); + Vec3f& GetFixedScale(); + const cd::Vec3f& GetFixedScale() const; + + ParticleEmitter& operator<<(InputArchive& inputArchive); + ParticleEmitter& operator<<(InputArchiveSwapBytes& inputArchive); + const ParticleEmitter& operator>>(OutputArchive& outputArchive) const; + const ParticleEmitter& operator>>(OutputArchiveSwapBytes& outputArchive) const; + +private: + ParticleEmitterImpl* m_pParticleEmitterImpl = nullptr; +}; + +} \ No newline at end of file diff --git a/public/Scene/SceneDatabase.h b/public/Scene/SceneDatabase.h index eaa0c83b..496a0533 100644 --- a/public/Scene/SceneDatabase.h +++ b/public/Scene/SceneDatabase.h @@ -13,6 +13,7 @@ #include "Scene/Mesh.h" #include "Scene/Morph.h" #include "Scene/Node.h" +#include "Scene/ParticleEmitter.h" #include "Scene/Texture.h" #include "Scene/Track.h" @@ -150,6 +151,15 @@ class CORE_API SceneDatabase final const Track* GetTrackByName(const char* pName) const; uint32_t GetTrackCount() const; + //ParticleEmitter + void AddParticleEmitter(ParticleEmitter emitter); + std::vector& GetParticleEmitters(); + const std::vector& GetParticleEmitters() const; + void SetParticleEmitterCount(uint32_t emitterCount); + ParticleEmitter& GetParticleEmitter(uint32_t index); + const ParticleEmitter& GetParticleEmitter(uint32_t index) const; + uint32_t GetParticleEmitterCount() const; + // Operations void Dump() const; void Validate() const;