Added particles first implementation

Former-commit-id: 2b98ce2f007927690bdecd4092e211013bf568cb
This commit is contained in:
Lynix
2014-08-08 17:17:58 +02:00
parent 4acd61cf30
commit e9267d7f43
16 changed files with 1071 additions and 4 deletions

View File

@@ -43,6 +43,40 @@ enum nzMaterialUniform
nzMaterialUniform_Max = nzMaterialUniform_SpecularMap
};
enum nzParticleComponent
{
nzParticleComponent_Unused = -1,
nzParticleComponent_Color,
nzParticleComponent_Life,
nzParticleComponent_Normal,
nzParticleComponent_Position,
nzParticleComponent_Radius,
nzParticleComponent_Rotation,
nzParticleComponent_Size,
nzParticleComponent_Velocity,
nzParticleComponent_Userdata0,
nzParticleComponent_Userdata1,
nzParticleComponent_Userdata2,
nzParticleComponent_Userdata3,
nzParticleComponent_Userdata4,
nzParticleComponent_Userdata5,
nzParticleComponent_Userdata6,
nzParticleComponent_Userdata7,
nzParticleComponent_Userdata8,
nzParticleComponent_Max = nzParticleComponent_Userdata8
};
enum nzParticleLayout
{
nzParticleLayout_Billboard,
nzParticleLayout_Model,
nzParticleLayout_Sprite,
nzParticleLayout_Max = nzParticleLayout_Sprite
};
enum nzRenderPassType
{
nzRenderPassType_AA,
@@ -71,10 +105,11 @@ enum nzRenderTechniqueType
enum nzSceneNodeType
{
nzSceneNodeType_Light, // NzLight
nzSceneNodeType_Model, // NzModel
nzSceneNodeType_Root, // NzSceneRoot
nzSceneNodeType_Sprite, // NzSprite
nzSceneNodeType_Light, // NzLight
nzSceneNodeType_Model, // NzModel
nzSceneNodeType_ParticleEmitter, // NzParticleEmitter
nzSceneNodeType_Root, // NzSceneRoot
nzSceneNodeType_Sprite, // NzSprite
nzSceneNodeType_User,
nzSceneNodeType_Max = nzSceneNodeType_User

View File

@@ -0,0 +1,31 @@
// Copyright (C) 2014 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_PARTICLECONTROLLER_HPP
#define NAZARA_PARTICLECONTROLLER_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Resource.hpp>
#include <Nazara/Core/ResourceRef.hpp>
class NzParticleController;
class NzParticleEmitter;
class NzParticleMapper;
using NzParticleControllerConstRef = NzResourceRef<const NzParticleController>;
using NzParticleControllerRef = NzResourceRef<NzParticleController>;
class NAZARA_API NzParticleController : public NzResource
{
public:
NzParticleController() = default;
NzParticleController(const NzParticleController& controller);
virtual ~NzParticleController();
virtual void Apply(NzParticleEmitter& emitter, NzParticleMapper& mapper, unsigned int offset, unsigned int particleCount, float elapsedTime) = 0;
};
#endif // NAZARA_PARTICLECONTROLLER_HPP

View File

@@ -0,0 +1,67 @@
// Copyright (C) 2014 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_PARTICLEDECLARATION_HPP
#define NAZARA_PARTICLEDECLARATION_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Resource.hpp>
#include <Nazara/Core/ResourceRef.hpp>
#include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Utility/Enums.hpp>
class NzParticleDeclaration;
using NzParticleDeclarationConstRef = NzResourceRef<const NzParticleDeclaration>;
using NzParticleDeclarationRef = NzResourceRef<NzParticleDeclaration>;
class NAZARA_API NzParticleDeclaration : public NzResource
{
friend class NzGraphics;
public:
NzParticleDeclaration();
NzParticleDeclaration(const NzParticleDeclaration& declaration);
~NzParticleDeclaration();
void DisableComponent(nzParticleComponent component);
void EnableComponent(nzParticleComponent component, nzComponentType type, unsigned int offset);
void GetComponent(nzParticleComponent component, bool* enabled, nzComponentType* type, unsigned int* offset) const;
unsigned int GetStride() const;
void SetStride(unsigned int stride);
NzParticleDeclaration& operator=(const NzParticleDeclaration& declaration);
static NzParticleDeclaration* Get(nzParticleLayout layout);
static bool IsTypeSupported(nzComponentType type);
private:
static bool Initialize();
static void Uninitialize();
struct Component
{
nzComponentType type;
bool enabled = false;
unsigned int offset;
/*
** -Lynix:
** Il serait aussi possible de préciser le stride de façon indépendante, ce que je ne permets pas
** pour décomplexifier l'interface en enlevant quelque chose que je juge inutile.
** Si vous pensez que ça peut être utile, n'hésitez pas à me le faire savoir !
*/
};
Component m_components[nzParticleComponent_Max+1];
unsigned int m_stride;
static NzParticleDeclaration s_declarations[nzParticleLayout_Max+1];
};
#endif // NAZARA_PARTICLEDECLARATION_HPP

View File

@@ -0,0 +1,91 @@
// Copyright (C) 2014 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_PARTICLEEMITTER_HPP
#define NAZARA_PARTICLEEMITTER_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Updatable.hpp>
#include <Nazara/Graphics/ParticleController.hpp>
#include <Nazara/Graphics/ParticleDeclaration.hpp>
#include <Nazara/Graphics/ParticleGenerator.hpp>
#include <Nazara/Graphics/ParticleRenderer.hpp>
#include <Nazara/Graphics/SceneNode.hpp>
#include <Nazara/Math/BoundingVolume.hpp>
#include <memory>
#include <set>
#include <vector>
class NAZARA_API NzParticleEmitter : public NzSceneNode, NzUpdatable
{
public:
NzParticleEmitter(unsigned int maxParticleCount, nzParticleLayout layout);
NzParticleEmitter(unsigned int maxParticleCount, NzParticleDeclaration* declaration);
NzParticleEmitter(const NzParticleEmitter& emitter);
NzParticleEmitter(NzParticleEmitter&& emitter) = default;
~NzParticleEmitter();
void AddController(NzParticleController* controller);
void AddGenerator(NzParticleGenerator* generator);
void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const;
void* CreateParticle();
void* CreateParticles(unsigned int count);
void* GenerateParticle();
void* GenerateParticles(unsigned int count);
const NzBoundingVolumef& GetBoundingVolume() const override;
unsigned int GetEmissionCount() const;
float GetEmissionRate() const;
unsigned int GetMaxParticleCount() const;
unsigned int GetParticleCount() const;
unsigned int GetParticleSize() const;
nzSceneNodeType GetSceneNodeType() const override;
bool IsDrawable() const;
void KillParticle(unsigned int index);
void KillParticles();
void RemoveController(NzParticleController* controller);
void RemoveGenerator(NzParticleGenerator* generator);
void SetEmissionCount(unsigned int count);
void SetEmissionRate(float rate);
void SetRenderer(NzParticleRenderer* renderer);
NzParticleEmitter& operator=(const NzParticleEmitter& emitter);
NzParticleEmitter& operator=(NzParticleEmitter&& emitter);
private:
void GenerateAABB() const;
void Register() override;
void ResizeBuffer();
void Unregister() override;
void UpdateBoundingVolume() const;
void Update() override;
std::set<unsigned int, std::greater<unsigned int>> m_dyingParticles;
mutable std::vector<nzUInt8> m_buffer;
std::vector<NzParticleControllerRef> m_controllers;
std::vector<NzParticleGeneratorRef> m_generators;
mutable NzBoundingVolumef m_boundingVolume;
NzParticleDeclarationConstRef m_declaration;
NzParticleRendererRef m_renderer;
mutable bool m_boundingVolumeUpdated;
bool m_processing;
float m_emissionAccumulator;
float m_emissionRate;
unsigned int m_emissionCount;
unsigned int m_maxParticleCount;
unsigned int m_particleCount;
unsigned int m_particleSize;
};
#endif // NAZARA_PARTICLEEMITTER_HPP

View File

@@ -0,0 +1,31 @@
// Copyright (C) 2014 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_PARTICLEGENERATOR_HPP
#define NAZARA_PARTICLEGENERATOR_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Resource.hpp>
#include <Nazara/Core/ResourceRef.hpp>
class NzParticleEmitter;
class NzParticleGenerator;
class NzParticleMapper;
using NzParticleGeneratorConstRef = NzResourceRef<const NzParticleGenerator>;
using NzParticleGeneratorRef = NzResourceRef<NzParticleGenerator>;
class NAZARA_API NzParticleGenerator : public NzResource
{
public:
NzParticleGenerator() = default;
NzParticleGenerator(const NzParticleGenerator& generator);
virtual ~NzParticleGenerator();
virtual void Generate(NzParticleEmitter& emitter, NzParticleMapper& mapper, unsigned int offset, unsigned int particleCount) = 0;
};
#endif // NAZARA_PARTICLEGENERATOR_HPP

View File

@@ -0,0 +1,31 @@
// Copyright (C) 2014 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_PARTICLEMAPPER_HPP
#define NAZARA_PARTICLEMAPPER_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/SparsePtr.hpp>
#include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/ParticleDeclaration.hpp>
class NAZARA_API NzParticleMapper
{
public:
NzParticleMapper(void* buffer, const NzParticleDeclaration* declaration);
~NzParticleMapper();
template<typename T> NzSparsePtr<T> GetComponentPtr(nzParticleComponent component);
template<typename T> NzSparsePtr<const T> GetComponentPtr(nzParticleComponent component) const;
private:
const NzParticleDeclaration* m_declaration;
nzUInt8* m_ptr;
};
#include <Nazara/Graphics/ParticleMapper.inl>
#endif // NAZARA_PARTICLEMAPPER_HPP

View File

@@ -0,0 +1,50 @@
// Copyright (C) 2014 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Error.hpp>
#include <Nazara/Graphics/Debug.hpp>
template <typename T>
NzSparsePtr<T> NzParticleMapper::GetComponentPtr(nzParticleComponent component)
{
// Ensuite le composant qui nous intéresse
bool enabled;
nzComponentType type;
unsigned int offset;
m_declaration->GetComponent(component, &enabled, &type, &offset);
if (enabled)
{
///TODO: Vérifier le rapport entre le type de l'attribut et le type template ?
return NzSparsePtr<T>(m_ptr + offset, m_declaration->GetStride());
}
else
{
NazaraError("Attribute 0x" + NzString::Number(component, 16) + " is not enabled");
return NzSparsePtr<T>();
}
}
template <typename T>
NzSparsePtr<const T> NzParticleMapper::GetComponentPtr(nzParticleComponent component) const
{
// Ensuite le composant qui nous intéresse
bool enabled;
nzComponentType type;
unsigned int offset;
m_declaration->GetComponent(component, &enabled, &type, &offset);
if (enabled)
{
///TODO: Vérifier le rapport entre le type de l'attribut et le type template ?
return NzSparsePtr<const T>(m_ptr + offset, m_declaration->GetStride());
}
else
{
NazaraError("Attribute 0x" + NzString::Number(component, 16) + " is not enabled");
return NzSparsePtr<const T>();
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@@ -0,0 +1,32 @@
// Copyright (C) 2014 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_PARTICLERENDERER_HPP
#define NAZARA_PARTICLERENDERER_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Resource.hpp>
#include <Nazara/Core/ResourceRef.hpp>
class NzAbstractRenderQueue;
class NzParticleEmitter;
class NzParticleMapper;
class NzParticleRenderer;
using NzParticleRendererConstRef = NzResourceRef<const NzParticleRenderer>;
using NzParticleRendererRef = NzResourceRef<NzParticleRenderer>;
class NAZARA_API NzParticleRenderer : public NzResource
{
public:
NzParticleRenderer() = default;
NzParticleRenderer(const NzParticleRenderer& renderer);
virtual ~NzParticleRenderer();
virtual void Render(const NzParticleEmitter& emitter, const NzParticleMapper& mapper, unsigned int offset, unsigned int particleCount, NzAbstractRenderQueue* renderQueue) = 0;
};
#endif // NAZARA_PARTICLERENDERER_HPP

View File

@@ -0,0 +1,42 @@
// Copyright (C) 2014 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_PARTICLESTRUCT_HPP
#define NAZARA_PARTICLESTRUCT_HPP
#include <Nazara/Core/Color.hpp>
#include <Nazara/Math/Quaternion.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Math/Vector3.hpp>
struct NzParticleStruct_Billboard
{
NzColor color;
NzVector3f normal;
NzVector3f position;
NzVector3f velocity;
nzUInt32 life;
float rotation;
};
struct NzParticleStruct_Model
{
NzVector3f position;
NzVector3f velocity;
nzUInt32 life;
NzQuaternionf rotation;
};
struct NzParticleStruct_Sprite
{
NzColor color;
NzVector2f position;
NzVector2f velocity;
nzUInt32 life;
float rotation;
};
#endif // NAZARA_PARTICLESTRUCT_HPP