Merge remote-tracking branch 'origin/particles' into havok
Conflicts: src/Components/Vehicle.h
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
struct Component
|
||||
{
|
||||
EntityID Entity;
|
||||
|
||||
virtual Component* Clone() const = 0;
|
||||
};
|
||||
|
||||
class ComponentFactory : public Factory<Component*> { };
|
||||
|
||||
@@ -14,6 +14,8 @@ struct BoxShape : Component
|
||||
float Width;
|
||||
float Height;
|
||||
float Depth;
|
||||
|
||||
virtual BoxShape* Clone() const override { return new BoxShape(*this); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ struct Camera : Component
|
||||
float FOV;
|
||||
float NearClip;
|
||||
float FarClip;
|
||||
|
||||
virtual Camera* Clone() const override { return new Camera(*this); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ struct DirectionalLight : Component
|
||||
float MaxRange;
|
||||
float SpecularIntensity;
|
||||
Color Color;
|
||||
|
||||
virtual DirectionalLight* Clone() const override { return new DirectionalLight(*this); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ struct FreeSteering : Component
|
||||
{
|
||||
FreeSteering() : Speed(35) { }
|
||||
float Speed;
|
||||
|
||||
virtual FreeSteering* Clone() const override { return new FreeSteering(*this); }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ namespace Components
|
||||
EntityID LinkedEntity;
|
||||
glm::vec3 Pivot;
|
||||
glm::vec3 Axis;
|
||||
|
||||
virtual HingeConstraint* Clone() const override { return new HingeConstraint(*this); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ struct Input : Component
|
||||
std::array<int, GLFW_MOUSE_BUTTON_LAST+1> LastMouseState;
|
||||
float dX, dY;
|
||||
float WheelDelta;
|
||||
|
||||
virtual Input* Clone() const override { return new Input(*this); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ namespace Components
|
||||
struct MeshShape : Component
|
||||
{
|
||||
std::string ResourceName;
|
||||
|
||||
virtual MeshShape* Clone() const override { return new MeshShape(*this); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ struct Model : Component
|
||||
Color Color;
|
||||
bool Visible;
|
||||
bool ShadowCaster;
|
||||
|
||||
virtual Model* Clone() const override { return new Model(*this); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef Components_Particle_h__
|
||||
#define Components_Particle_h__
|
||||
|
||||
#include "System.h"
|
||||
#include "Component.h"
|
||||
#include "Color.h"
|
||||
#include <vector>
|
||||
|
||||
namespace Components
|
||||
{
|
||||
|
||||
struct Particle : Component
|
||||
{
|
||||
std::vector<Color> ColorSpectrum;
|
||||
std::vector<glm::vec3> ScaleSpectrum;
|
||||
double LifeTime;
|
||||
std::vector<glm::vec3> VelocitySpectrum;
|
||||
std::vector<float> AngularVelocitySpectrum;
|
||||
std::vector<glm::vec3> OrientationSpectrum; //Keep?
|
||||
|
||||
virtual Particle* Clone() const override { return new Particle(*this); }
|
||||
};
|
||||
|
||||
}
|
||||
#endif // !Components_Particle_h__
|
||||
@@ -5,20 +5,39 @@
|
||||
#include "Color.h"
|
||||
#include <vector>
|
||||
|
||||
namespace Systems { class ParticleSystem; }
|
||||
|
||||
namespace Components
|
||||
{
|
||||
|
||||
struct ParticleEmitter : Component
|
||||
{
|
||||
int ParticleTemplate;
|
||||
friend class Systems::ParticleSystem;
|
||||
|
||||
ParticleEmitter()
|
||||
: SpawnFrequency(0)
|
||||
, SpawnCount(0)
|
||||
, SpreadAngle(0)
|
||||
, LifeTime(0)
|
||||
, TimeSinceLastSpawn(0) { }
|
||||
|
||||
EntityID ParticleTemplate;
|
||||
float SpawnFrequency;
|
||||
float Speed;
|
||||
int SpawnCount;
|
||||
std::vector<Color> ColorSpectrum;
|
||||
std::vector<float> ScaleSpectrum;
|
||||
std::vector<glm::vec3> ScaleSpectrum;
|
||||
float SpreadAngle;
|
||||
float LifeTime;
|
||||
std::vector<float[3]> VelocitySpectrum;
|
||||
std::vector<float[3]> AngularVelocitySpectrum;
|
||||
double LifeTime;
|
||||
bool UseGoalVelocity;
|
||||
glm::vec3 GoalVelocity;
|
||||
std::vector<float> AngularVelocitySpectrum;
|
||||
std::vector<glm::vec3> OrientationSpectrum; //Keep?
|
||||
|
||||
virtual ParticleEmitter* Clone() const override { return new ParticleEmitter(*this); }
|
||||
|
||||
private:
|
||||
double TimeSinceLastSpawn;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ struct Physics : Component
|
||||
|
||||
float Mass;
|
||||
bool Static;
|
||||
|
||||
virtual Physics* Clone() const override { return new Physics(*this); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ struct PointLight : Component
|
||||
float constantAttenuation, linearAttenuation, quadraticAttenuation;
|
||||
float spotExponent;
|
||||
Color color;
|
||||
|
||||
virtual PointLight* Clone() const override { return new PointLight(*this); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ struct SoundEmitter : Component
|
||||
float Pitch;
|
||||
bool Loop;
|
||||
std::string Path;
|
||||
|
||||
virtual SoundEmitter* Clone() const override { return new SoundEmitter(*this); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ struct SphereShape : Component
|
||||
: Radius(1.f){ }
|
||||
|
||||
float Radius;
|
||||
|
||||
virtual SphereShape* Clone() const override { return new SphereShape(*this); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ struct Sprite : Component
|
||||
{
|
||||
std::string SpriteFile;
|
||||
Color Color;
|
||||
|
||||
virtual Sprite* Clone() const override { return new Sprite(*this); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Components
|
||||
{
|
||||
struct TankSteering : Component
|
||||
{
|
||||
|
||||
TankSteering* Clone() const override { return new TankSteering(*this); }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,12 @@
|
||||
namespace Components
|
||||
{
|
||||
|
||||
struct Template : Component { };
|
||||
struct Template
|
||||
: public Component
|
||||
{
|
||||
virtual Template* Clone() const override { return nullptr; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // !Components_Template_h__
|
||||
@@ -6,7 +6,7 @@
|
||||
namespace Components
|
||||
{
|
||||
|
||||
struct Transform : Component
|
||||
struct Transform : public Component
|
||||
{
|
||||
Transform()
|
||||
: Scale(glm::vec3(1.f)) { }
|
||||
@@ -15,6 +15,8 @@ struct Transform : Component
|
||||
glm::quat Orientation;
|
||||
glm::vec3 Velocity;
|
||||
glm::vec3 Scale;
|
||||
|
||||
virtual Transform* Clone() const override { return new Transform(*this); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ struct Vehicle : Component
|
||||
float TopSpeed;
|
||||
float MaxSpeedFullSteeringAngle;
|
||||
float SpringDamping;
|
||||
|
||||
Vehicle* Clone() const override { return new Vehicle(*this); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ struct Wheel : Component
|
||||
private:
|
||||
int ID;
|
||||
glm::quat OriginalOrientation;
|
||||
|
||||
Wheel* Clone() const override { return new Wheel(*this); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ namespace Components
|
||||
struct WheelPair : Component
|
||||
{
|
||||
// Flag for pair wheels
|
||||
|
||||
virtual WheelPair* Clone() const override { return new WheelPair(*this); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+67
-14
@@ -85,18 +85,7 @@ void GameWorld::Initialize()
|
||||
CommitEntity(ground);
|
||||
}
|
||||
|
||||
{
|
||||
auto camera = CreateEntity();
|
||||
auto transform = AddComponent<Components::Transform>(camera, "Transform");
|
||||
transform->Position.z = 20.f;
|
||||
transform->Position.y = 10.f;
|
||||
transform->Orientation = glm::quat(glm::vec3(-glm::pi<float>() / 8.f, 0.f, 0.f));
|
||||
auto cameraComp = AddComponent<Components::Camera>(camera, "Camera");
|
||||
cameraComp->FarClip = 2000.f;
|
||||
AddComponent(camera, "Input");
|
||||
auto freeSteering = AddComponent<Components::FreeSteering>(camera, "FreeSteering");
|
||||
CommitEntity(camera);
|
||||
}
|
||||
|
||||
|
||||
/*{
|
||||
auto jeep = CreateEntity();
|
||||
@@ -511,6 +500,30 @@ void GameWorld::Initialize()
|
||||
CommitEntity(shape);
|
||||
}
|
||||
CommitEntity(wheel);
|
||||
|
||||
auto entity = CreateEntity(tank);
|
||||
auto transformComponent = AddComponent<Components::Transform>(entity, "Transform");
|
||||
transformComponent->Position = glm::vec3(2,-1.7,2.0);
|
||||
transformComponent->Scale = glm::vec3(3,3,3);
|
||||
transformComponent->Orientation = glm::angleAxis(glm::pi<float>()/2, glm::vec3(1,0,0));
|
||||
auto emitterComponent = AddComponent<Components::ParticleEmitter>(entity, "ParticleEmitter");
|
||||
emitterComponent->SpawnCount = 2;
|
||||
emitterComponent->SpawnFrequency = 0.005;
|
||||
emitterComponent->SpreadAngle = glm::pi<float>();
|
||||
emitterComponent->UseGoalVelocity = false;
|
||||
emitterComponent->LifeTime = 0.5;
|
||||
//emitterComponent->AngularVelocitySpectrum.push_back(glm::pi<float>() / 100);
|
||||
emitterComponent->ScaleSpectrum.push_back(glm::vec3(0.05));
|
||||
CommitEntity(entity);
|
||||
|
||||
auto particleEntity = CreateEntity(entity);
|
||||
auto TEMP = AddComponent<Components::Transform>(particleEntity, "Transform");
|
||||
TEMP->Scale = glm::vec3(0);
|
||||
auto spriteComponent = AddComponent<Components::Sprite>(particleEntity, "Sprite");
|
||||
spriteComponent->SpriteFile = "Models/Textures/Sprites/Dust.png";
|
||||
emitterComponent->ParticleTemplate = particleEntity;
|
||||
|
||||
CommitEntity(particleEntity);
|
||||
}
|
||||
|
||||
{
|
||||
@@ -571,11 +584,50 @@ void GameWorld::Initialize()
|
||||
CommitEntity(shape);
|
||||
}
|
||||
CommitEntity(wheel);
|
||||
|
||||
auto entity = CreateEntity(tank);
|
||||
auto transformComponent = AddComponent<Components::Transform>(entity, "Transform");
|
||||
transformComponent->Position = glm::vec3(-2,-1.7,2.0);
|
||||
transformComponent->Scale = glm::vec3(3,3,3);
|
||||
transformComponent->Orientation = glm::angleAxis(glm::pi<float>()/2, glm::vec3(1,0,0));
|
||||
auto emitterComponent = AddComponent<Components::ParticleEmitter>(entity, "ParticleEmitter");
|
||||
emitterComponent->SpawnCount = 2;
|
||||
emitterComponent->SpawnFrequency = 0.005;
|
||||
emitterComponent->SpreadAngle = glm::pi<float>();
|
||||
emitterComponent->UseGoalVelocity = false;
|
||||
emitterComponent->LifeTime = 0.5;
|
||||
//emitterComponent->AngularVelocitySpectrum.push_back(glm::pi<float>() / 100);
|
||||
emitterComponent->ScaleSpectrum.push_back(glm::vec3(0.05));
|
||||
CommitEntity(entity);
|
||||
|
||||
auto particleEntity = CreateEntity(entity);
|
||||
auto TEMP = AddComponent<Components::Transform>(particleEntity, "Transform");
|
||||
TEMP->Scale = glm::vec3(0);
|
||||
auto spriteComponent = AddComponent<Components::Sprite>(particleEntity, "Sprite");
|
||||
spriteComponent->SpriteFile = "Models/Textures/Sprites/Dust.png";
|
||||
emitterComponent->ParticleTemplate = particleEntity;
|
||||
|
||||
CommitEntity(particleEntity);
|
||||
}
|
||||
|
||||
CommitEntity(tank);
|
||||
{
|
||||
auto camera = CreateEntity(tank);
|
||||
auto transform = AddComponent<Components::Transform>(camera, "Transform");
|
||||
transform->Position.z = 20.f;
|
||||
transform->Position.y = 7.f;
|
||||
//transform->Orientation = glm::quat(glm::vec3(-glm::pi<float>() / 8.f, 0.f, 0.f));
|
||||
transform->Orientation = glm::angleAxis(glm::pi<float>() / 100, glm::vec3(1,0,0));
|
||||
auto cameraComp = AddComponent<Components::Camera>(camera, "Camera");
|
||||
cameraComp->FarClip = 2000.f;
|
||||
AddComponent(camera, "Input");
|
||||
auto freeSteering = AddComponent<Components::FreeSteering>(camera, "FreeSteering");
|
||||
CommitEntity(camera);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
for(int i = 0; i < 10; i++)
|
||||
{
|
||||
@@ -663,6 +715,7 @@ void GameWorld::Initialize()
|
||||
GetSystem<Systems::SoundSystem>("SoundSystem")->PlaySound(emitter);
|
||||
CommitEntity(entity);
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
void GameWorld::Update(double dt)
|
||||
@@ -683,7 +736,7 @@ void GameWorld::RegisterSystems()
|
||||
m_SystemFactory.Register("InputSystem", [this]() { return new Systems::InputSystem(this, m_EventBroker); });
|
||||
m_SystemFactory.Register("DebugSystem", [this]() { return new Systems::DebugSystem(this, m_EventBroker); });
|
||||
//m_SystemFactory.Register("CollisionSystem", [this]() { return new Systems::CollisionSystem(this); });
|
||||
////m_SystemFactory.Register("ParticleSystem", [this]() { return new Systems::ParticleSystem(this); });
|
||||
m_SystemFactory.Register("ParticleSystem", [this]() { return new Systems::ParticleSystem(this, m_EventBroker); });
|
||||
//m_SystemFactory.Register("PlayerSystem", [this]() { return new Systems::PlayerSystem(this); });
|
||||
m_SystemFactory.Register("FreeSteeringSystem", [this]() { return new Systems::FreeSteeringSystem(this, m_EventBroker); });
|
||||
m_SystemFactory.Register("TankSteeringSystem", [this]() { return new Systems::TankSteeringSystem(this, m_EventBroker); });
|
||||
@@ -699,7 +752,7 @@ void GameWorld::AddSystems()
|
||||
AddSystem("InputSystem");
|
||||
AddSystem("DebugSystem");
|
||||
//AddSystem("CollisionSystem");
|
||||
////AddSystem("ParticleSystem");
|
||||
AddSystem("ParticleSystem");
|
||||
//AddSystem("PlayerSystem");
|
||||
AddSystem("FreeSteeringSystem");
|
||||
AddSystem("TankSteeringSystem");
|
||||
|
||||
+2
-1
@@ -9,7 +9,7 @@
|
||||
#include "Systems/InputSystem.h"
|
||||
#include "Systems/DebugSystem.h"
|
||||
//#include "Systems/LevelGenerationSystem.h"
|
||||
//#include "Systems/ParticleSystem.h"
|
||||
#include "Systems/ParticleSystem.h"
|
||||
//#include "Systems/PlayerSystem.h"
|
||||
#include "Systems/FreeSteeringSystem.h"
|
||||
#include "Systems/TankSteeringSystem.h"
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "Components/Input.h"
|
||||
#include "Components/Model.h"
|
||||
#include "Components/ParticleEmitter.h"
|
||||
#include "Components/Particle.h"
|
||||
#include "Components/PointLight.h"
|
||||
#include "Components/SoundEmitter.h"
|
||||
#include "Components/Sprite.h"
|
||||
|
||||
@@ -43,6 +43,7 @@ public:
|
||||
{
|
||||
Components::Wheel* WheelComponent;
|
||||
Components::Transform* TransformComponent;
|
||||
|
||||
};
|
||||
|
||||
std::vector<WheelData> m_Wheels;
|
||||
|
||||
@@ -267,6 +267,31 @@ void Renderer::DrawScene()
|
||||
}
|
||||
}
|
||||
|
||||
for (auto tuple : TexturesToRender)
|
||||
{
|
||||
Texture* texture;
|
||||
glm::mat4 modelMatrix;
|
||||
glm::mat4 billboardMatrix;
|
||||
std::tie(texture, modelMatrix, billboardMatrix) = tuple;
|
||||
|
||||
//MVP = cameraMatrix * glm::inverse(glm::toMat4(m_Camera->Orientation()) * modelMatrix );
|
||||
MVP = cameraMatrix * modelMatrix * billboardMatrix;
|
||||
|
||||
depthMVP = depthCameraMatrix * modelMatrix;
|
||||
glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "MVP"), 1, GL_FALSE, glm::value_ptr(MVP));
|
||||
glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "DepthMVP"), 1, GL_FALSE, glm::value_ptr(depthMVP));
|
||||
glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "model"), 1, GL_FALSE, glm::value_ptr(modelMatrix));
|
||||
glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "view"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix()));
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, *texture);
|
||||
glBindVertexArray(m_ScreenQuad);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
// Debug draw model normals
|
||||
if (m_DrawNormals)
|
||||
@@ -318,6 +343,8 @@ void Renderer::DrawShadowMap()
|
||||
glDrawArrays(GL_TRIANGLES, texGroup.StartIndex, texGroup.EndIndex - texGroup.StartIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void Renderer::DrawDebugShadowMap()
|
||||
@@ -376,6 +403,24 @@ void Renderer::AddModelToDraw(Model* model, glm::vec3 position, glm::quat orient
|
||||
ModelsToRender.push_back(std::make_tuple(model, modelMatrix, visible, shadowCaster));
|
||||
}
|
||||
|
||||
void Renderer::AddTextureToDraw(Texture* texture, glm::vec3 position, glm::quat orientation, glm::vec3 scale)
|
||||
{
|
||||
glm::mat4 modelMatrix = glm::translate(glm::mat4(), position) * glm::toMat4(orientation) * glm::scale(scale);
|
||||
|
||||
glm::vec3 camToParticle = glm::normalize(m_Camera->Position() - position);
|
||||
glm::vec3 up = glm::vec3(0,1,0);
|
||||
glm::vec3 rightVec = glm::normalize(glm::cross(up, camToParticle));
|
||||
glm::vec3 up2 = glm::normalize(glm::cross(camToParticle, rightVec));
|
||||
|
||||
glm::mat4 billboardMatrix;
|
||||
billboardMatrix[0] = glm::vec4(rightVec, 0);
|
||||
billboardMatrix[1] = glm::vec4(up2, 0);
|
||||
billboardMatrix[2] = glm::vec4(camToParticle, 0);
|
||||
//billboardMatrix[3] = glm::vec4(position, 0);
|
||||
|
||||
TexturesToRender.push_back(std::make_tuple(texture, modelMatrix, billboardMatrix));
|
||||
}
|
||||
|
||||
void Renderer::AddPointLightToDraw(
|
||||
glm::vec3 _position,
|
||||
glm::vec3 _specular,
|
||||
@@ -536,6 +581,7 @@ void Renderer::ClearStuff()
|
||||
{
|
||||
AABBsToRender.clear();
|
||||
ModelsToRender.clear();
|
||||
TexturesToRender.clear();
|
||||
Light_position.clear();
|
||||
Light_specular.clear();
|
||||
Light_diffuse.clear();
|
||||
|
||||
@@ -25,6 +25,7 @@ public:
|
||||
int Height() const { return m_Height; }
|
||||
|
||||
std::list<std::tuple<Model*, glm::mat4, bool, bool>> ModelsToRender;
|
||||
std::list<std::tuple<Texture*, glm::mat4, glm::mat4>> TexturesToRender;
|
||||
int Lights;
|
||||
std::vector<float> Light_position;
|
||||
std::vector<float> Light_specular;
|
||||
@@ -42,6 +43,7 @@ public:
|
||||
void DrawText();
|
||||
|
||||
void AddModelToDraw(Model* model, glm::vec3 position, glm::quat orientation, glm::vec3 scale, bool visible, bool shadowCaster);
|
||||
void AddTextureToDraw(Texture* texture, glm::vec3 position, glm::quat orientation, glm::vec3 scale);
|
||||
void AddTextToDraw();
|
||||
void AddPointLightToDraw(
|
||||
glm::vec3 _position,
|
||||
|
||||
@@ -56,19 +56,19 @@ bool Systems::FreeSteeringSystem::FreeSteeringInputController::OnCommand(const E
|
||||
}
|
||||
else if (event.Command == "+cam_right")
|
||||
{
|
||||
Movement.x += 1.f;
|
||||
Movement.x -= 1.f;
|
||||
}
|
||||
else if (event.Command == "-cam_right")
|
||||
{
|
||||
Movement.x -= 1.f;
|
||||
Movement.x += 1.f;
|
||||
}
|
||||
else if (event.Command == "+cam_left")
|
||||
{
|
||||
Movement.x += -1.f;
|
||||
Movement.x -= -1.f;
|
||||
}
|
||||
else if (event.Command == "-cam_left")
|
||||
{
|
||||
Movement.x -= -1.f;
|
||||
Movement.x += -1.f;
|
||||
}
|
||||
else if (event.Command == "+up")
|
||||
{
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "ParticleSystem.h"
|
||||
|
||||
|
||||
#include "World.h"
|
||||
|
||||
void Systems::ParticleSystem::Initialize()
|
||||
{
|
||||
m_TransformSystem = m_World->GetSystem<Systems::TransformSystem>("TransformSystem");
|
||||
}
|
||||
|
||||
void Systems::ParticleSystem::Update(double dt)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Systems::ParticleSystem::UpdateEntity(double dt, EntityID entity, EntityID parent)
|
||||
{
|
||||
auto transformComponent = m_World->GetComponent<Components::Transform>(entity, "Transform");
|
||||
if(!transformComponent)
|
||||
return;
|
||||
|
||||
auto emitterComponent = m_World->GetComponent<Components::ParticleEmitter>(entity, "ParticleEmitter");
|
||||
if(emitterComponent)
|
||||
{
|
||||
emitterComponent->TimeSinceLastSpawn += dt;
|
||||
auto emitterTransformComponent = m_World->GetComponent<Components::Transform>(entity, "Transform");
|
||||
if(emitterComponent->TimeSinceLastSpawn > emitterComponent->SpawnFrequency)
|
||||
{
|
||||
SpawnParticles(entity);
|
||||
emitterComponent->TimeSinceLastSpawn = 0;
|
||||
}
|
||||
|
||||
std::list<ParticleData>::iterator it;
|
||||
for(it = m_ParticleEmitter[entity].begin(); it != m_ParticleEmitter[entity].end();)
|
||||
{
|
||||
EntityID particleID = (it)->ParticleID;
|
||||
auto transformComponent = m_World->GetComponent<Components::Transform>(particleID, "Transform");
|
||||
auto particleComponent = m_World->GetComponent<Components::Particle>(particleID, "Particle");
|
||||
|
||||
double timeLived = glfwGetTime() - it->SpawnTime;
|
||||
if(timeLived > particleComponent->LifeTime)
|
||||
{
|
||||
m_World->RemoveEntity(particleID);
|
||||
it = m_ParticleEmitter[entity].erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIX: calculate once
|
||||
float timeProgress = timeLived / particleComponent->LifeTime;
|
||||
// ColorInterpolation(timeProgress, particleComponent->ColorSpectrum, color);
|
||||
// Scale interpolation
|
||||
if(particleComponent->ScaleSpectrum.size() > 1)
|
||||
VectorInterpolation(timeProgress, particleComponent->ScaleSpectrum, transformComponent->Scale);
|
||||
// Velocity interpolation
|
||||
if(particleComponent->VelocitySpectrum.size() > 1)
|
||||
VectorInterpolation(timeProgress, particleComponent->VelocitySpectrum, transformComponent->Velocity);
|
||||
|
||||
// Angular velocity interpolation
|
||||
if (particleComponent->AngularVelocitySpectrum.size() != 0)
|
||||
{
|
||||
if(particleComponent->AngularVelocitySpectrum.size() > 1)
|
||||
{
|
||||
ScalarInterpolation(timeProgress, particleComponent->AngularVelocitySpectrum, it->AngularVelocity);
|
||||
transformComponent->Orientation = glm::angleAxis(it->AngularVelocity, it->Orientation);
|
||||
}
|
||||
else
|
||||
{
|
||||
transformComponent->Orientation *= glm::angleAxis(it->AngularVelocity, it->Orientation);
|
||||
//it->Orientation = glm::angleAxis(it->AngularVelocity, it->Orientation);
|
||||
}
|
||||
}
|
||||
|
||||
//Angular velocity interpolation
|
||||
if(particleComponent->OrientationSpectrum.size() > 1)
|
||||
{
|
||||
VectorInterpolation(timeProgress, particleComponent->OrientationSpectrum, it->Orientation);
|
||||
glm::vec3 v1 = (particleComponent->OrientationSpectrum[0]);
|
||||
glm::vec3 v2 = (it->Orientation);
|
||||
glm::vec3 v3 = glm::normalize(glm::cross(v1,v2));
|
||||
float angle = glm::acos(glm::dot(v1, v2) / (glm::length(v1) * glm::length(v2)));
|
||||
|
||||
transformComponent->Orientation = glm::angleAxis(angle, v3);
|
||||
}
|
||||
|
||||
|
||||
transformComponent->Position += transformComponent->Velocity * (float)dt;
|
||||
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Systems::ParticleSystem::RegisterComponents(ComponentFactory* cf)
|
||||
{
|
||||
cf->Register("ParticleEmitter", []() { return new Components::ParticleEmitter(); });
|
||||
cf->Register("Particle", []() { return new Components::Particle(); });
|
||||
}
|
||||
|
||||
|
||||
void Systems::ParticleSystem::SpawnParticles(EntityID emitterID)
|
||||
{
|
||||
auto emitterComponent = m_World->GetComponent<Components::ParticleEmitter>(emitterID, "ParticleEmitter");
|
||||
auto emitterTransform = m_World->GetComponent<Components::Transform>(emitterID, "Transform");
|
||||
glm::vec3 emitterPos = m_TransformSystem->AbsolutePosition(emitterID);
|
||||
glm::quat emitterOrientation = emitterTransform->Orientation;
|
||||
|
||||
float tempSpeed = 4;
|
||||
glm::vec3 speed = glm::vec3(tempSpeed);
|
||||
|
||||
for(int i = 0; i < emitterComponent->SpawnCount; i++)
|
||||
{
|
||||
auto ent = m_World->CloneEntity(emitterComponent->ParticleTemplate);
|
||||
|
||||
auto particleTransform = m_World->GetComponent<Components::Transform>(ent, "Transform");
|
||||
particleTransform->Position = emitterPos;
|
||||
|
||||
particleTransform->Orientation = emitterOrientation;
|
||||
//The emitter's orientation as "start value" times the default direction for emitter. Times the speed, and then rotate on x and y axis with the randomized spread angle.
|
||||
float spreadAngle = emitterComponent->SpreadAngle;
|
||||
particleTransform->Velocity = emitterOrientation * glm::vec3(0, 0, -1) * speed *
|
||||
glm::normalize(glm::angleAxis(RandomizeAngle(spreadAngle), glm::vec3(1, 0, 0))) *
|
||||
glm::normalize(glm::angleAxis(RandomizeAngle(spreadAngle), glm::vec3(0, 1, 0))) *
|
||||
glm::normalize(glm::angleAxis(RandomizeAngle(spreadAngle), glm::vec3(0, 0, 1)));
|
||||
|
||||
auto particle = m_World->AddComponent<Components::Particle>(ent, "Particle");
|
||||
particle->LifeTime = emitterComponent->LifeTime;
|
||||
particle->ScaleSpectrum = emitterComponent->ScaleSpectrum;
|
||||
particle->VelocitySpectrum.push_back(particleTransform->Velocity);
|
||||
|
||||
if (emitterComponent->ScaleSpectrum.size() > 0)
|
||||
{
|
||||
if (emitterComponent->ScaleSpectrum.size() > 1)
|
||||
{
|
||||
particle->ScaleSpectrum = emitterComponent->ScaleSpectrum;
|
||||
}
|
||||
else
|
||||
{
|
||||
particleTransform->Scale = emitterComponent->ScaleSpectrum[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
particleTransform->Scale = glm::vec3(1, 1, 1);
|
||||
}
|
||||
|
||||
if(emitterComponent->UseGoalVelocity)
|
||||
particle->VelocitySpectrum.push_back(emitterComponent->GoalVelocity);
|
||||
particle->OrientationSpectrum = emitterComponent->OrientationSpectrum;
|
||||
if(particle->OrientationSpectrum.size() != 0)
|
||||
particleTransform->Orientation = glm::angleAxis(0.f, particle->OrientationSpectrum[0]);
|
||||
particle->AngularVelocitySpectrum = emitterComponent->AngularVelocitySpectrum;
|
||||
|
||||
|
||||
ParticleData data;
|
||||
data.ParticleID = ent;
|
||||
data.SpawnTime = glfwGetTime();
|
||||
if (particle->AngularVelocitySpectrum.size() != 0)
|
||||
data.AngularVelocity = particle->AngularVelocitySpectrum[0];
|
||||
if (particle->OrientationSpectrum.size() != 0)
|
||||
data.Orientation = particle->OrientationSpectrum[0];
|
||||
else data.Orientation = emitterOrientation * glm::vec3(0,0,-1);
|
||||
|
||||
m_ParticleEmitter[emitterID].push_back(data);
|
||||
}
|
||||
}
|
||||
|
||||
//Randomizes between -spreadAngle/2 and spreadAngle/2
|
||||
float Systems::ParticleSystem::RandomizeAngle(float spreadAngle)
|
||||
{
|
||||
return ((float)rand() / ((float)RAND_MAX + 1) * spreadAngle) - spreadAngle/2;
|
||||
}
|
||||
|
||||
//Interpolates the velocity of the particle
|
||||
void Systems::ParticleSystem::VectorInterpolation(double timeProgress, std::vector<glm::vec3> spectrum, glm::vec3 &v)
|
||||
{
|
||||
float dAxisValue = glm::abs(spectrum[0].x - spectrum[1].x);
|
||||
if(spectrum[0].x > spectrum[1].x)
|
||||
dAxisValue *= -1;
|
||||
v.x = spectrum[0].x + dAxisValue * timeProgress;
|
||||
dAxisValue = glm::abs(spectrum[0].y - spectrum[1].y);
|
||||
if (spectrum[0].y > spectrum[1].y)
|
||||
dAxisValue *= -1;
|
||||
v.y = spectrum[0].y + dAxisValue * timeProgress;
|
||||
dAxisValue = glm::abs(spectrum[0].z - spectrum[1].z);
|
||||
if(spectrum[0].z > spectrum[1].z)
|
||||
dAxisValue *= -1;
|
||||
v.z = spectrum[0].z + dAxisValue * timeProgress;
|
||||
}
|
||||
|
||||
// void Systems::ParticleSystem::ColorInterpolation(double timeProgress, std::vector<Color> spectrum, Color &c)
|
||||
// {
|
||||
// float dColor = glm::abs(spectrum[0].r - spectrum[1].r);
|
||||
// c.r = spectrum[0].r + dColor * timeProgress;
|
||||
// dColor = glm::abs(spectrum[0].g - spectrum[1].g);
|
||||
// c.g = spectrum[0].g + dColor * timeProgress;
|
||||
// dColor = glm::abs(spectrum[0].b - spectrum[1].b);
|
||||
// c.b = spectrum[0].b + dColor * timeProgress;
|
||||
// }
|
||||
|
||||
void Systems::ParticleSystem::ScalarInterpolation(double timeProgress, std::vector<float> spectrum, float &alpha)
|
||||
{
|
||||
float dAlpha = glm::abs(spectrum[0] - spectrum[1]);
|
||||
if(spectrum[0] > spectrum[1])
|
||||
dAlpha *= -1;
|
||||
alpha = spectrum[0] + dAlpha * timeProgress;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
#ifndef ParticleSystem_h__
|
||||
#define ParticleSystem_h__
|
||||
|
||||
#include "System.h"
|
||||
#include "Systems/TransformSystem.h"
|
||||
#include "Components/Transform.h"
|
||||
#include "Components/ParticleEmitter.h"
|
||||
#include "Components/Particle.h"
|
||||
#include "Components/Model.h"
|
||||
#include "Components/PointLight.h"
|
||||
#include "Color.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
namespace Systems
|
||||
{
|
||||
|
||||
struct ParticleData
|
||||
{
|
||||
EntityID ParticleID;
|
||||
double SpawnTime;
|
||||
float AngularVelocity;
|
||||
glm::vec3 Orientation;
|
||||
Color color;
|
||||
};
|
||||
|
||||
class ParticleSystem : public System
|
||||
{
|
||||
public:
|
||||
ParticleSystem(World* world, std::shared_ptr<::EventBroker> eventBroker)
|
||||
: System(world, eventBroker) { }
|
||||
|
||||
void RegisterComponents(ComponentFactory* cf) override;
|
||||
void Update(double dt) override;
|
||||
void UpdateEntity(double dt, EntityID entity, EntityID parent) override;
|
||||
void Initialize() override;
|
||||
private:
|
||||
void SpawnParticles(EntityID emitterID);
|
||||
float RandomizeAngle(float spreadAngle);
|
||||
//void ScaleInterpolation(double timeProgress, std::vector<float> spectrum, glm::vec3 &scale);
|
||||
void VectorInterpolation(double timeProgress, std::vector<glm::vec3> spectrum, glm::vec3 &velocity);
|
||||
//void ColorInterpolation(double timeProgress, std::vector<Color> spectrum, Color &color);
|
||||
void ScalarInterpolation(double timeProgress, std::vector<float> spectrum, float &alpha);
|
||||
void Billboard();
|
||||
std::map<EntityID, std::list<ParticleData>> m_ParticleEmitter;
|
||||
std::map<EntityID, double> m_TimeSinceLastSpawn;
|
||||
std::shared_ptr<Systems::TransformSystem> m_TransformSystem;
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // !ParticleSystem_h__
|
||||
@@ -55,6 +55,17 @@ void Systems::RenderSystem::UpdateEntity(double dt, EntityID entity, EntityID pa
|
||||
m_Renderer->GetCamera()->NearClip(cameraComponent->NearClip);
|
||||
m_Renderer->GetCamera()->FarClip(cameraComponent->FarClip);
|
||||
}
|
||||
|
||||
auto spriteComponent = m_World->GetComponent<Components::Sprite>(entity, "Sprite");
|
||||
if(spriteComponent != nullptr)
|
||||
{
|
||||
//TEMP
|
||||
Texture* texture = m_World->GetResourceManager()->Load<Texture>("Texture", spriteComponent->SpriteFile);
|
||||
//glBindTexture(GL_TEXTURE_2D, texture);
|
||||
auto transform = m_World->GetComponent<Components::Transform>(spriteComponent->Entity, "Transform");
|
||||
glm::quat orientation2D = glm::angleAxis(glm::eulerAngles(transform->Orientation).z, glm::vec3(0, 0, -1));
|
||||
m_Renderer->AddTextureToDraw(texture, transform->Position, orientation2D, transform->Scale);
|
||||
}
|
||||
}
|
||||
|
||||
void Systems::RenderSystem::Initialize()
|
||||
|
||||
+54
-1
@@ -90,6 +90,7 @@ void World::ProcessEntityRemovals()
|
||||
for (auto entity : m_EntitiesToRemove)
|
||||
{
|
||||
m_EntityParents.erase(entity);
|
||||
m_EntityChildren.erase(entity);
|
||||
// Remove components
|
||||
for (auto pair : m_EntityComponents[entity])
|
||||
{
|
||||
@@ -113,7 +114,8 @@ void World::ProcessEntityRemovals()
|
||||
EntityID World::CreateEntity(EntityID parent /*= 0*/)
|
||||
{
|
||||
EntityID newEntity = GenerateEntityID();
|
||||
m_EntityParents.insert(std::pair<EntityID, EntityID>(newEntity, parent));
|
||||
m_EntityParents[newEntity] = parent;
|
||||
m_EntityChildren[parent].push_back(newEntity);
|
||||
return newEntity;
|
||||
}
|
||||
|
||||
@@ -144,7 +146,58 @@ void World::CommitEntity(EntityID entity)
|
||||
}
|
||||
}
|
||||
|
||||
void World::AddComponent(EntityID entity, std::string componentType, std::shared_ptr<Component> component)
|
||||
{
|
||||
component->Entity = entity;
|
||||
m_ComponentsOfType[componentType].push_back(component);
|
||||
m_EntityComponents[entity][componentType] = component;
|
||||
for (auto pair : m_Systems)
|
||||
{
|
||||
auto system = pair.second;
|
||||
system->OnComponentCreated(componentType, component);
|
||||
}
|
||||
}
|
||||
|
||||
void World::AddSystem(std::string systemType)
|
||||
{
|
||||
m_Systems[systemType] = std::shared_ptr<System>(m_SystemFactory.Create(systemType));
|
||||
}
|
||||
|
||||
EntityID World::CloneEntity(EntityID entity, EntityID parent /* = 0 */)
|
||||
{
|
||||
int clone = CreateEntity(parent);
|
||||
|
||||
for (auto pair : m_EntityComponents[entity])
|
||||
{
|
||||
auto type = pair.first;
|
||||
auto component = std::shared_ptr<Component>(pair.second->Clone());
|
||||
if (component != nullptr)
|
||||
{
|
||||
AddComponent(clone, type, component);
|
||||
}
|
||||
}
|
||||
|
||||
auto itChildren = m_EntityChildren.find(entity);
|
||||
if (itChildren != m_EntityChildren.end())
|
||||
{
|
||||
for (EntityID child : itChildren->second)
|
||||
{
|
||||
CloneEntity(child, clone);
|
||||
}
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
std::list<EntityID> World::GetEntityChildren(EntityID entity)
|
||||
{
|
||||
auto it = m_EntityChildren.find(entity);
|
||||
if (it == m_EntityChildren.end())
|
||||
{
|
||||
return std::list<EntityID>();
|
||||
}
|
||||
else
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
||||
+17
-11
@@ -37,6 +37,7 @@ public:
|
||||
std::shared_ptr<T> GetSystem(std::string systemType);
|
||||
|
||||
EntityID CreateEntity(EntityID parent = 0);
|
||||
EntityID CloneEntity(EntityID entity, EntityID parent = 0);
|
||||
|
||||
void RemoveEntity(EntityID entity);
|
||||
|
||||
@@ -44,6 +45,7 @@ public:
|
||||
|
||||
EntityID GetEntityParent(EntityID entity);
|
||||
EntityID GetEntityBaseParent(EntityID entity);
|
||||
std::list<EntityID> GetEntityChildren(EntityID entity);
|
||||
|
||||
template <class T>
|
||||
T GetProperty(EntityID entity, std::string property)
|
||||
@@ -95,13 +97,16 @@ protected:
|
||||
|
||||
EntityID m_LastEntityID;
|
||||
std::stack<EntityID> m_RecycledEntityIDs;
|
||||
// A bottom to top tree. A map of child entities to parent entities.
|
||||
std::unordered_map<EntityID, EntityID> m_EntityParents;
|
||||
std::unordered_map<EntityID, std::unordered_map<std::string, boost::any>> m_EntityProperties;
|
||||
|
||||
std::unordered_map<EntityID, EntityID> m_EntityParents; // child -> parent
|
||||
std::unordered_map<EntityID, std::list<EntityID>> m_EntityChildren; // parent -> child
|
||||
std::unordered_map<EntityID, std::unordered_map<std::string, boost::any>> m_EntityProperties;
|
||||
std::unordered_map<std::string, std::list<std::shared_ptr<Component>>> m_ComponentsOfType;
|
||||
std::unordered_map<EntityID, std::map<std::string, std::shared_ptr<Component>>> m_EntityComponents;
|
||||
|
||||
// Internal: Add a component to an entity
|
||||
void AddComponent(EntityID entity, std::string componentType, std::shared_ptr<Component> component);
|
||||
|
||||
std::list<EntityID> m_EntitiesToRemove;
|
||||
void ProcessEntityRemovals();
|
||||
|
||||
@@ -133,14 +138,8 @@ std::shared_ptr<T> World::AddComponent(EntityID entity, std::string componentTyp
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
component->Entity = entity;
|
||||
m_ComponentsOfType[componentType].push_back(component);
|
||||
m_EntityComponents[entity][componentType] = component;
|
||||
for (auto pair : m_Systems)
|
||||
{
|
||||
auto system = pair.second;
|
||||
system->OnComponentCreated(componentType, component);
|
||||
}
|
||||
AddComponent(entity, componentType, component);
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
@@ -148,7 +147,14 @@ std::shared_ptr<T> World::AddComponent(EntityID entity, std::string componentTyp
|
||||
template <class T>
|
||||
T* World::GetComponent(EntityID entity, std::string componentType)
|
||||
{
|
||||
|
||||
/*auto it0 = m_EntityComponents.find(entity);
|
||||
|
||||
if (it0 == m_EntityComponents.end())
|
||||
return nullptr;*/
|
||||
|
||||
auto components = m_EntityComponents[entity];
|
||||
|
||||
auto it = components.find(componentType);
|
||||
if (it != components.end())
|
||||
{
|
||||
|
||||
@@ -112,6 +112,7 @@
|
||||
<ClCompile Include="..\..\src\Systems\DebugSystem.cpp" />
|
||||
<ClCompile Include="..\..\src\Systems\FreeSteeringSystem.cpp" />
|
||||
<ClCompile Include="..\..\src\Systems\InputSystem.cpp" />
|
||||
<ClCompile Include="..\..\src\Systems\ParticleSystem.cpp" />
|
||||
<ClCompile Include="..\..\src\Systems\PhysicsSystem.cpp" />
|
||||
<ClCompile Include="..\..\src\Systems\RenderSystem.cpp" />
|
||||
<ClCompile Include="..\..\src\Systems\SoundSystem.cpp" />
|
||||
@@ -134,6 +135,7 @@
|
||||
<ClInclude Include="..\..\src\Components\Input.h" />
|
||||
<ClInclude Include="..\..\src\Components\MeshShape.h" />
|
||||
<ClInclude Include="..\..\src\Components\Model.h" />
|
||||
<ClInclude Include="..\..\src\Components\Particle.h" />
|
||||
<ClInclude Include="..\..\src\Components\ParticleEmitter.h" />
|
||||
<ClInclude Include="..\..\src\Components\Physics.h" />
|
||||
<ClInclude Include="..\..\src\Components\PointLight.h" />
|
||||
@@ -183,6 +185,7 @@
|
||||
<ClInclude Include="..\..\src\Systems\DebugSystem.h" />
|
||||
<ClInclude Include="..\..\src\Systems\FreeSteeringSystem.h" />
|
||||
<ClInclude Include="..\..\src\Systems\InputSystem.h" />
|
||||
<ClInclude Include="..\..\src\Systems\ParticleSystem.h" />
|
||||
<ClInclude Include="..\..\src\Systems\PhysicsSystem.h" />
|
||||
<ClInclude Include="..\..\src\Systems\RenderSystem.h" />
|
||||
<ClInclude Include="..\..\src\Systems\SoundSystem.h" />
|
||||
|
||||
@@ -50,6 +50,9 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ResourceManager.cpp" />
|
||||
<ClCompile Include="..\..\src\Sound.cpp" />
|
||||
<ClCompile Include="..\..\src\Systems\ParticleSystem.cpp">
|
||||
<Filter>Particle System\Systems</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\EventBroker.cpp" />
|
||||
<ClCompile Include="..\..\src\Physics\VehicleSetup.cpp">
|
||||
<Filter>Physics</Filter>
|
||||
@@ -264,6 +267,12 @@
|
||||
<ClInclude Include="..\..\src\Components\WheelPair.h">
|
||||
<Filter>Physics\Components</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\Systems\ParticleSystem.h">
|
||||
<Filter>Particle System\Systems</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\Components\Particle.h">
|
||||
<Filter>Particle System\Components</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\GUI\Frame.h">
|
||||
<Filter>GUI</Filter>
|
||||
</ClInclude>
|
||||
|
||||
Reference in New Issue
Block a user