Merge remote-tracking branch 'origin/particles' into havok

Conflicts:
	src/Components/Vehicle.h
This commit is contained in:
ViktorLjung
2014-05-13 01:57:28 +02:00
35 changed files with 571 additions and 39 deletions
+2
View File
@@ -7,6 +7,8 @@
struct Component
{
EntityID Entity;
virtual Component* Clone() const = 0;
};
class ComponentFactory : public Factory<Component*> { };
+2
View File
@@ -14,6 +14,8 @@ struct BoxShape : Component
float Width;
float Height;
float Depth;
virtual BoxShape* Clone() const override { return new BoxShape(*this); }
};
}
+2
View File
@@ -17,6 +17,8 @@ struct Camera : Component
float FOV;
float NearClip;
float FarClip;
virtual Camera* Clone() const override { return new Camera(*this); }
};
}
+2
View File
@@ -13,6 +13,8 @@ struct DirectionalLight : Component
float MaxRange;
float SpecularIntensity;
Color Color;
virtual DirectionalLight* Clone() const override { return new DirectionalLight(*this); }
};
}
+2
View File
@@ -9,6 +9,8 @@ struct FreeSteering : Component
{
FreeSteering() : Speed(35) { }
float Speed;
virtual FreeSteering* Clone() const override { return new FreeSteering(*this); }
};
}
+2
View File
@@ -11,6 +11,8 @@ namespace Components
EntityID LinkedEntity;
glm::vec3 Pivot;
glm::vec3 Axis;
virtual HingeConstraint* Clone() const override { return new HingeConstraint(*this); }
};
}
+2
View File
@@ -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); }
};
}
+2
View File
@@ -11,6 +11,8 @@ namespace Components
struct MeshShape : Component
{
std::string ResourceName;
virtual MeshShape* Clone() const override { return new MeshShape(*this); }
};
}
+2
View File
@@ -16,6 +16,8 @@ struct Model : Component
Color Color;
bool Visible;
bool ShadowCaster;
virtual Model* Clone() const override { return new Model(*this); }
};
}
+25
View File
@@ -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__
+24 -5
View File
@@ -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;
};
}
+2
View File
@@ -13,6 +13,8 @@ struct Physics : Component
float Mass;
bool Static;
virtual Physics* Clone() const override { return new Physics(*this); }
};
}
+2
View File
@@ -16,6 +16,8 @@ struct PointLight : Component
float constantAttenuation, linearAttenuation, quadraticAttenuation;
float spotExponent;
Color color;
virtual PointLight* Clone() const override { return new PointLight(*this); }
};
}
+2
View File
@@ -17,6 +17,8 @@ struct SoundEmitter : Component
float Pitch;
bool Loop;
std::string Path;
virtual SoundEmitter* Clone() const override { return new SoundEmitter(*this); }
};
}
+2
View File
@@ -12,6 +12,8 @@ struct SphereShape : Component
: Radius(1.f){ }
float Radius;
virtual SphereShape* Clone() const override { return new SphereShape(*this); }
};
}
+2
View File
@@ -13,6 +13,8 @@ struct Sprite : Component
{
std::string SpriteFile;
Color Color;
virtual Sprite* Clone() const override { return new Sprite(*this); }
};
}
+1 -1
View File
@@ -7,7 +7,7 @@ namespace Components
{
struct TankSteering : Component
{
TankSteering* Clone() const override { return new TankSteering(*this); }
};
}
+6 -1
View File
@@ -6,7 +6,12 @@
namespace Components
{
struct Template : Component { };
struct Template
: public Component
{
virtual Template* Clone() const override { return nullptr; }
};
}
#endif // !Components_Template_h__
+3 -1
View File
@@ -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); }
};
}
+2
View File
@@ -23,6 +23,8 @@ struct Vehicle : Component
float TopSpeed;
float MaxSpeedFullSteeringAngle;
float SpringDamping;
Vehicle* Clone() const override { return new Vehicle(*this); }
};
}
+2
View File
@@ -36,6 +36,8 @@ struct Wheel : Component
private:
int ID;
glm::quat OriginalOrientation;
Wheel* Clone() const override { return new Wheel(*this); }
};
}
+2
View File
@@ -9,6 +9,8 @@ namespace Components
struct WheelPair : Component
{
// Flag for pair wheels
virtual WheelPair* Clone() const override { return new WheelPair(*this); }
};
}
+67 -14
View File
@@ -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
View File
@@ -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"
+1
View File
@@ -43,6 +43,7 @@ public:
{
Components::Wheel* WheelComponent;
Components::Transform* TransformComponent;
};
std::vector<WheelData> m_Wheels;
+46
View File
@@ -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();
+2
View File
@@ -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,
+4 -4
View File
@@ -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")
{
+208
View File
@@ -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;
}
+54
View File
@@ -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__
+11
View File
@@ -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
View File
@@ -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
View File
@@ -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())
{
+3
View File
@@ -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>