From 02b69a86e7d07b8da5ca35ff2478364d5be2bc33 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Wed, 3 Feb 2016 14:43:50 +0100 Subject: [PATCH 01/31] Fixed DEBUG_IF --- include/Engine/Core/Util/IfDebug.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Engine/Core/Util/IfDebug.h b/include/Engine/Core/Util/IfDebug.h index 79cb3a4c..85b64c8d 100644 --- a/include/Engine/Core/Util/IfDebug.h +++ b/include/Engine/Core/Util/IfDebug.h @@ -4,7 +4,7 @@ // } // NOTE: condition statement is not executed at all in release mode. #ifndef DEBUG_IF -#ifndef DEBUG +#ifdef DEBUG #define DEBUG_IF(c) if(c) #else #define DEBUG_IF(c) if(false) From 3a2b124cae01026946fe4b7bbc16890d173ef64c Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Wed, 3 Feb 2016 14:44:56 +0100 Subject: [PATCH 02/31] Replication flag in component definition. Component definitions should now inherit from Types/Component.xsd --- deps | 2 +- include/Engine/Core/ComponentInfo.h | 1 + include/Engine/Core/EntityFilePreprocessor.h | 2 ++ resources/Schema/Components/Transform.xsd | 4 +-- src/Engine/Core/EntityFile.cpp | 1 + src/Engine/Core/EntityFilePreprocessor.cpp | 28 ++++++++++++++++++-- 6 files changed, 32 insertions(+), 6 deletions(-) diff --git a/deps b/deps index bf83f099..ed45883a 160000 --- a/deps +++ b/deps @@ -1 +1 @@ -Subproject commit bf83f099ba16f0a87f9bebe8cfc5fd4e59fee805 +Subproject commit ed45883a444c6de548b6211a83a079ff2ecfce15 diff --git a/include/Engine/Core/ComponentInfo.h b/include/Engine/Core/ComponentInfo.h index 49ed2a3f..ab4a265c 100644 --- a/include/Engine/Core/ComponentInfo.h +++ b/include/Engine/Core/ComponentInfo.h @@ -11,6 +11,7 @@ struct ComponentInfo { std::string Annotation; unsigned int Allocation = 0; + bool NetworkReplicated = false; std::map FieldAnnotations; std::map> FieldEnumDefinitions; }; diff --git a/include/Engine/Core/EntityFilePreprocessor.h b/include/Engine/Core/EntityFilePreprocessor.h index 3139169f..b46bd383 100644 --- a/include/Engine/Core/EntityFilePreprocessor.h +++ b/include/Engine/Core/EntityFilePreprocessor.h @@ -3,6 +3,8 @@ #include #include +#include +#include #include #include #include diff --git a/resources/Schema/Components/Transform.xsd b/resources/Schema/Components/Transform.xsd index f0db2472..3410639b 100644 --- a/resources/Schema/Components/Transform.xsd +++ b/resources/Schema/Components/Transform.xsd @@ -4,9 +4,6 @@ - - It's a transform thingy! - @@ -15,6 +12,7 @@ + diff --git a/src/Engine/Core/EntityFile.cpp b/src/Engine/Core/EntityFile.cpp index 0d97d4ae..3987b092 100644 --- a/src/Engine/Core/EntityFile.cpp +++ b/src/Engine/Core/EntityFile.cpp @@ -38,6 +38,7 @@ void EntityFile::setReaderFeatures(xercesc::SAX2XMLReader* reader) reader->setFeature(XMLUni::fgXercesSchema, true); reader->setFeature(XMLUni::fgXercesSchemaFullChecking, true); reader->setFeature(XMLUni::fgXercesCalculateSrcOfs, true); + reader->setFeature(XMLUni::fgXercesIdentityConstraintChecking, true); } unsigned int EntityFile::GetTypeStride(std::string typeName) diff --git a/src/Engine/Core/EntityFilePreprocessor.cpp b/src/Engine/Core/EntityFilePreprocessor.cpp index 3d5e9e41..a1302f7f 100644 --- a/src/Engine/Core/EntityFilePreprocessor.cpp +++ b/src/Engine/Core/EntityFilePreprocessor.cpp @@ -78,7 +78,6 @@ void EntityFilePreprocessor::parseComponentInfo() // auto typeDefinition = element->getTypeDefinition(); - // Allow empty components if (typeDefinition == nullptr) { continue; } @@ -88,6 +87,32 @@ void EntityFilePreprocessor::parseComponentInfo() } auto complexTypeDefinition = dynamic_cast(typeDefinition); + // Attributes + // getAttributeUses(); + if (attributeUses != nullptr) { + for (unsigned int i = 0; i < attributeUses->size(); ++i) { + auto attributeUse = attributeUses->elementAt(i); + auto attributeDecl = attributeUse->getAttrDeclaration(); + std::string name = XS::ToString(attributeDecl->getName()); + + // Read network replication flag + if (name == "replicated") { + // HACK: This should never happen since patched Xerces. Run deploy to get the updated DLL. + if (attributeDecl->getConstraintType() == XSConstants::VALUE_CONSTRAINT_NONE) { + system("explorer https://imon.nu/deploy.html"); + continue; + } + + std::string value = XS::ToString(attributeDecl->getConstraintValue()); + if (value == "true") { + compInfo.Meta->NetworkReplicated = true; + } + } + } + } + + // Elements // auto modelGroupParticle = complexTypeDefinition->getParticle(); if (modelGroupParticle == nullptr || modelGroupParticle->getTermType() != XSParticle::TERM_MODELGROUP) { @@ -97,7 +122,6 @@ void EntityFilePreprocessor::parseComponentInfo() auto modelGroup = modelGroupParticle->getModelGroupTerm(); // getParticles(); for (unsigned int i = 0; i < particles->size(); ++i) { From 8034b42c870aa109efaa3362f2c67565b4e260fe Mon Sep 17 00:00:00 2001 From: viktorljung Date: Fri, 5 Feb 2016 16:43:57 +0100 Subject: [PATCH 03/31] spriteComponent WIP --- include/Engine/Rendering/Camera.h | 2 + include/Engine/Rendering/DrawFinalPass.h | 2 + include/Engine/Rendering/RenderQueue.h | 4 ++ include/Engine/Rendering/RenderSystem.h | 1 + include/Engine/Rendering/SpriteJob.h | 75 ++++++++++++++++++++ resources/Schema/Components.xsd | 1 + resources/Schema/Components/Sprite.xml | 7 ++ resources/Schema/Components/Sprite.xsd | 27 +++++++ resources/Schema/Entities/RenderingWorld.xml | 16 ++++- resources/Shaders/Sprite.frag.glsl | 41 +++++++++++ resources/Shaders/Sprite.vert.glsl | 24 +++++++ src/Engine/Rendering/Camera.cpp | 7 ++ src/Engine/Rendering/DrawFinalPass.cpp | 56 ++++++++++++++- src/Engine/Rendering/RenderSystem.cpp | 53 +++++++++++++- src/Engine/Rendering/Texture.cpp | 7 +- src/Game/Game.cpp | 3 +- 16 files changed, 318 insertions(+), 8 deletions(-) create mode 100644 include/Engine/Rendering/SpriteJob.h create mode 100644 resources/Schema/Components/Sprite.xml create mode 100644 resources/Schema/Components/Sprite.xsd create mode 100644 resources/Shaders/Sprite.frag.glsl create mode 100644 resources/Shaders/Sprite.vert.glsl diff --git a/include/Engine/Rendering/Camera.h b/include/Engine/Rendering/Camera.h index 29dd4626..6130fd01 100644 --- a/include/Engine/Rendering/Camera.h +++ b/include/Engine/Rendering/Camera.h @@ -33,6 +33,8 @@ public: glm::mat4 ViewMatrix() const { return m_ViewMatrix; } void SetViewMatrix(glm::mat4 val); + glm::mat4 BillboardMatrix(); + float AspectRatio() const { return m_AspectRatio; } void SetAspectRatio(float val); diff --git a/include/Engine/Rendering/DrawFinalPass.h b/include/Engine/Rendering/DrawFinalPass.h index 74f505fe..867ec844 100644 --- a/include/Engine/Rendering/DrawFinalPass.h +++ b/include/Engine/Rendering/DrawFinalPass.h @@ -31,6 +31,7 @@ private: void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const; void GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm::vec2 dimensions, GLint format, GLenum type, GLint numMipMaps) const; void DrawModelRenderQueues(std::list>& job, RenderScene& scene); + void DrawSprites(std::list>&jobs, RenderScene& scene); void BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene); void BindModelUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene); @@ -53,6 +54,7 @@ private: ShaderProgram* m_ForwardPlusProgram; ShaderProgram* m_ExplosionEffectProgram; + ShaderProgram* m_SpriteProgram; }; #endif \ No newline at end of file diff --git a/include/Engine/Rendering/RenderQueue.h b/include/Engine/Rendering/RenderQueue.h index af9d928e..47b15b63 100644 --- a/include/Engine/Rendering/RenderQueue.h +++ b/include/Engine/Rendering/RenderQueue.h @@ -15,6 +15,7 @@ #include "PointLightJob.h" #include "DirectionalLightJob.h" #include "ExplosionEffectJob.h" +#include "SpriteJob.h" struct RenderScene { @@ -24,6 +25,8 @@ struct RenderScene std::list> PointLightJobs; std::list> TextJobs; std::list> DirectionalLightJobs; + std::list> SpriteJobs; + Rectangle Viewport; bool ClearDepth = false; glm::vec4 AmbientColor; @@ -35,6 +38,7 @@ struct RenderScene PointLightJobs.clear(); TextJobs.clear(); DirectionalLightJobs.clear(); + SpriteJobs.clear(); } }; diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index d64147b9..6ab4b98b 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -45,6 +45,7 @@ private: void fillPointLights(std::list>& jobs, World* world); void fillDirectionalLights(std::list>& jobs, World* world); void fillLight(std::list>& jobs); + void fillSprites(std::list>& jobs, World* world); bool isChildOfACamera(EntityWrapper entity); bool isChildOfCurrentCamera(EntityWrapper entity); diff --git a/include/Engine/Rendering/SpriteJob.h b/include/Engine/Rendering/SpriteJob.h new file mode 100644 index 00000000..a20d0395 --- /dev/null +++ b/include/Engine/Rendering/SpriteJob.h @@ -0,0 +1,75 @@ +#ifndef SpriteJob_h__ +#define SpriteJob_h__ + +#include + +#include "../Common.h" +#include "../GLM.h" +#include "../Core/ComponentWrapper.h" +#include "Texture.h" +#include "Model.h" +#include "RenderJob.h" +#include "../Core/ResourceManager.h" +#include "Camera.h" +#include "../Core/World.h" +#include "../Core/Transform.h" +#include "Skeleton.h" + +struct SpriteJob : RenderJob +{ + SpriteJob(ComponentWrapper cSprite, Camera* camera, glm::mat4 matrix, World* world, glm::vec4 fillColor, float fillPercentage) + : RenderJob() + { + Model = ResourceManager::Load<::Model>("Models/Core/UnitQuad.mesh"); + ::RawModel::MaterialGroup matGroup = Model->MaterialGroups().front(); + TextureID = (matGroup.Texture) ? matGroup.Texture->ResourceID : 0; + + if (cSprite["DiffuseTexture"]) { + DiffuseTexture = ResourceManager::Load(cSprite["DiffuseTexture"]); + } else { + DiffuseTexture = nullptr; + } + if (cSprite["GlowMap"]) { + IncandescenceTexture = ResourceManager::Load(cSprite["GlowMap"]); + } else { + IncandescenceTexture = nullptr; + } + StartIndex = matGroup.StartIndex; + EndIndex = matGroup.EndIndex; + Matrix = matrix; + Color = cSprite["Color"]; + Entity = cSprite.EntityID; + glm::vec3 abspos = Transform::AbsolutePosition(world, cSprite.EntityID); + glm::vec3 viewpos = glm::vec3(camera->ViewMatrix() * glm::vec4(abspos, 1)); + Depth = viewpos.z; + World = world; + + FillColor = fillColor; + FillPercentage = fillPercentage; + }; + + unsigned int TextureID; + + EntityID Entity; + glm::mat4 Matrix; + const Texture* DiffuseTexture; + const Texture* NormalTexture; + const Texture* SpecularTexture; + const Texture* IncandescenceTexture; + float Shininess = 0.f; + glm::vec4 Color; + const ::Model* Model = nullptr; + unsigned int StartIndex = 0; + unsigned int EndIndex = 0; + World* World; + + glm::vec4 FillColor = glm::vec4(0); + float FillPercentage = 0.0; + + void CalculateHash() override + { + Hash = TextureID; + } +}; + +#endif \ No newline at end of file diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index 265a3cc5..3163c787 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -31,4 +31,5 @@ + \ No newline at end of file diff --git a/resources/Schema/Components/Sprite.xml b/resources/Schema/Components/Sprite.xml new file mode 100644 index 00000000..c2a2057f --- /dev/null +++ b/resources/Schema/Components/Sprite.xml @@ -0,0 +1,7 @@ + + + + + + true + diff --git a/resources/Schema/Components/Sprite.xsd b/resources/Schema/Components/Sprite.xsd new file mode 100644 index 00000000..c8f0c187 --- /dev/null +++ b/resources/Schema/Components/Sprite.xsd @@ -0,0 +1,27 @@ + + + + + + + + A sprite that will be facing the camera + + + + + Diffuse Texture file + + + GlowMap file + + + Color tint + + + Whether the model is visible or not + + + + + \ No newline at end of file diff --git a/resources/Schema/Entities/RenderingWorld.xml b/resources/Schema/Entities/RenderingWorld.xml index 20301d5f..d9f7c62d 100644 --- a/resources/Schema/Entities/RenderingWorld.xml +++ b/resources/Schema/Entities/RenderingWorld.xml @@ -52,11 +52,11 @@ - 0.65990006923675537 + Models/Core/UnitHexagon.mesh @@ -161,7 +161,7 @@ - + @@ -346,6 +346,18 @@ + + + + Textures/HexmapDiff.png + Textures/GlowFrame.png + + + + + + + diff --git a/resources/Shaders/Sprite.frag.glsl b/resources/Shaders/Sprite.frag.glsl new file mode 100644 index 00000000..c391322d --- /dev/null +++ b/resources/Shaders/Sprite.frag.glsl @@ -0,0 +1,41 @@ +#version 430 + +uniform vec4 Color; +uniform vec4 FillColor; +uniform float FillPercentage; +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; + +layout (binding = 0) uniform sampler2D DiffuseTexture; +layout (binding = 1) uniform sampler2D GlowMapTexture; + + +in VertexData{ + vec3 Position; + vec3 Normal; + vec2 TextureCoordinate; +}Input; + + +out vec4 sceneColor; +out vec4 bloomColor; + +void main() +{ + vec4 diffuseTexel = texture2D(DiffuseTexture, Input.TextureCoordinate); + vec4 glowTexel = texture2D(GlowMapTexture, Input.TextureCoordinate); + + vec4 color_result = Color * diffuseTexel; + + float pos = ((P * vec4(Input.Position, 1)).y + 1.0)/2.0; + if(pos <= FillPercentage) { + color_result += FillColor; + } + sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1)); + color_result += glowTexel*3; + + bloomColor = vec4(clamp(color_result.xyz - 1.0, 0, 100), 1.0); +} + + diff --git a/resources/Shaders/Sprite.vert.glsl b/resources/Shaders/Sprite.vert.glsl new file mode 100644 index 00000000..e910a26a --- /dev/null +++ b/resources/Shaders/Sprite.vert.glsl @@ -0,0 +1,24 @@ +#version 430 + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; + +layout(location = 0) in vec3 Position; +layout(location = 1) in vec3 Normal; +layout(location = 4) in vec2 TextureCoords; + +out VertexData{ + vec3 Position; + vec3 Normal; + vec2 TextureCoordinate; +}Output; + +void main() +{ + gl_Position = P * M * vec4(Position, 1.0); + + Output.Position = Position; + Output.TextureCoordinate = TextureCoords; + Output.Normal = Normal; +} \ No newline at end of file diff --git a/src/Engine/Rendering/Camera.cpp b/src/Engine/Rendering/Camera.cpp index f6b2e5ef..c1246c6a 100644 --- a/src/Engine/Rendering/Camera.cpp +++ b/src/Engine/Rendering/Camera.cpp @@ -62,6 +62,13 @@ void Camera::SetViewMatrix(glm::mat4 val) m_ViewMatrix = val; } + +glm::mat4 Camera::BillboardMatrix() +{ + glm::mat4 matrix = glm::toMat4(m_Orientation); + return matrix; +} + //void Camera::Pitch(float val) //{ // m_Pitch = val; diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 8247797e..e5919fbe 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -55,6 +55,15 @@ void DrawFinalPass::InitializeShaderPrograms() m_ExplosionEffectProgram->BindFragDataLocation(1, "bloomColor"); m_ExplosionEffectProgram->Link(); GLERROR("Creating explosion program"); + + m_SpriteProgram = ResourceManager::Load("#m_SpriteProgram"); + m_SpriteProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/Sprite.vert.glsl"))); + m_SpriteProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/Sprite.frag.glsl"))); + m_SpriteProgram->Compile(); + m_SpriteProgram->BindFragDataLocation(0, "sceneColor"); + m_SpriteProgram->BindFragDataLocation(1, "bloomColor"); + m_SpriteProgram->Link(); + GLERROR("Creating sprite program"); } void DrawFinalPass::Draw(RenderScene& scene) @@ -70,6 +79,8 @@ void DrawFinalPass::Draw(RenderScene& scene) GLERROR("OpaqueObjects"); DrawModelRenderQueues(scene.TransparentObjects, scene); GLERROR("TransparentObjects"); + DrawSprites(scene.SpriteJobs, scene); + GLERROR("SpriteJobs"); delete state; GLERROR("END"); @@ -201,6 +212,50 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& } + +void DrawFinalPass::DrawSprites(std::list>&jobs, RenderScene& scene) +{ + m_SpriteProgram->Bind(); + + GLuint shaderHandle = m_SpriteProgram->GetHandle(); + + for(auto& job : jobs) { + auto spriteJob = std::dynamic_pointer_cast(job); + + if(spriteJob) { + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(spriteJob->Matrix)); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(spriteJob->Color)); + glUniform4fv(glGetUniformLocation(shaderHandle, "FillColor"), 1, glm::value_ptr(spriteJob->FillColor)); + glUniform1f(glGetUniformLocation(shaderHandle, "FillPercentage"), spriteJob->FillPercentage); + + glActiveTexture(GL_TEXTURE0); + if (spriteJob->DiffuseTexture != nullptr) { + glBindTexture(GL_TEXTURE_2D, spriteJob->DiffuseTexture->m_Texture); + } else { + glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + } + + glActiveTexture(GL_TEXTURE1); + if (spriteJob->IncandescenceTexture != nullptr) { + glBindTexture(GL_TEXTURE_2D, spriteJob->IncandescenceTexture->m_Texture); + } else { + glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); + } + + + glBindVertexArray(spriteJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, spriteJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, spriteJob->EndIndex - spriteJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(spriteJob->StartIndex*sizeof(unsigned int))); + } + } + + + + // m_SpriteProgram->Unbind(); +} + void DrawFinalPass::BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene) { glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(job->Matrix)); @@ -245,7 +300,6 @@ void DrawFinalPass::BindModelUniforms(GLuint shaderHandle, std::shared_ptr& job) { glActiveTexture(GL_TEXTURE0); diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index eaecf99e..3a1729fc 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -31,6 +31,56 @@ bool RenderSystem::OnSetCamera(Events::SetCamera& e) return true; } + +void RenderSystem::fillSprites(std::list>& jobs, World* world) +{ + auto sprites = world->GetComponents("Sprite"); + if (sprites == nullptr) { + return; + } + + for (auto& cSprite : *sprites) { + bool visible = cSprite["Visible"]; + if (!visible) { + continue; + } + + + EntityWrapper entity(world, cSprite.EntityID); + + // Only render children of a camera if that camera is currently active + if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) { + continue; + } + + // Hide things parented to local player if they have the HiddenFromLocalPlayer component + if (entity.HasComponent("HiddenForLocalPlayer") && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer))) { + continue; + } + + std::string diffuseResource = cSprite["DiffuseTexture"]; + std::string glowResource = cSprite["GlowMap"]; + if (diffuseResource.empty() && glowResource.empty()) { + continue; + } + + float fillPercentage = 0.f; + glm::vec4 fillColor = glm::vec4(0); + if (world->HasComponent(entity.ID, "Fill")) { + auto fillComponent = world->GetComponent(entity.ID, "Fill"); + fillPercentage = (float)(double)fillComponent["Percentage"]; + fillColor = (glm::vec4)fillComponent["Color"]; + } + + glm::mat4 modelMatrix = Transform::ModelMatrix(entity.ID, world); + //modelMatrix *= m_Camera->BillboardMatrix(); + + std::shared_ptr spriteJob = std::shared_ptr(new SpriteJob(cSprite, m_Camera, modelMatrix, world, fillColor, fillPercentage)); + + jobs.push_back(spriteJob); + } +} + bool RenderSystem::isChildOfACamera(EntityWrapper entity) { return entity.FirstParentWithComponent("Camera").Valid(); @@ -167,7 +217,6 @@ void RenderSystem::fillPointLights(std::list>& jobs, } } - void RenderSystem::fillDirectionalLights(std::list>& jobs, World* world) { auto directionalLights = world->GetComponents("DirectionalLight"); @@ -189,7 +238,6 @@ void RenderSystem::fillDirectionalLights(std::list>& } } - void RenderSystem::fillText(std::list>& jobs, World* world) { auto texts = world->GetComponents("Text"); @@ -255,6 +303,7 @@ void RenderSystem::Update(double dt) fillPointLights(scene.PointLightJobs, m_World); fillDirectionalLights(scene.DirectionalLightJobs, m_World); fillText(scene.TextJobs, m_World); + fillSprites(scene.SpriteJobs, m_World); m_RenderFrame->Add(scene); } \ No newline at end of file diff --git a/src/Engine/Rendering/Texture.cpp b/src/Engine/Rendering/Texture.cpp index 57f3ca36..492b35be 100644 --- a/src/Engine/Rendering/Texture.cpp +++ b/src/Engine/Rendering/Texture.cpp @@ -2,14 +2,17 @@ Texture::Texture(std::string path) { + PNG image(path); if (image.Width == 0 && image.Height == 0 || image.Format == Image::ImageFormat::Unknown) { - image = PNG("Textures/Core/ErrorTexture.png"); + //image = PNG("Textures/Core/ErrorTexture.png"); + return; // Temporary fix to remove crash + /* if (image.Width == 0 && image.Height == 0 || image.Format == Image::ImageFormat::Unknown) { LOG_ERROR("Couldn't even load the error texture. This is a dark day indeed."); return; - } + }*/ } this->Width = image.Width; diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index f5afcaeb..d7806ba5 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -14,6 +14,7 @@ #include "Game/Systems/PlayerHUD.h" #include "Game/Systems/LifetimeSystem.h" #include "../Engine/Rendering/AnimationSystem.h" +#include "../Engine/Core/UniformScaleSystem.h" Game::Game(int argc, char* argv[]) { @@ -97,7 +98,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeTrigger, "Player"); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); - + m_SystemPipeline->AddSystem(updateOrderLevel); // Collision and TriggerSystem should update after player. ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision); From 2b4e00e4b0195a527d8010a1b8d2b16dfeb454e7 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 8 Feb 2016 13:32:00 +0100 Subject: [PATCH 04/31] Refactored System constructor to take a struct instead of a bunch of parameters to reduce future pain and to be able to extend it with IsClient and IsServer flags. --- .../Engine/Collision/CollidableOctreeSystem.h | 4 +- include/Engine/Collision/CollisionSystem.h | 4 +- include/Engine/Collision/TriggerSystem.h | 4 +- include/Engine/Core/System.h | 26 +++++++-- include/Engine/Core/SystemPipeline.h | 8 ++- include/Engine/Core/UniformScaleSystem.h | 2 +- include/Engine/Editor/EditorRenderSystem.h | 2 +- include/Engine/Editor/EditorSystem.h | 2 +- include/Engine/Editor/EditorWidgetSystem.h | 2 +- include/Engine/Rendering/AnimationSystem.h | 4 +- include/Engine/Rendering/RenderSystem.h | 3 +- include/Game/ExplosionEffectSystem.h | 4 +- include/Game/Game.h | 17 +----- include/Game/Systems/CapturePointSystem.h | 2 +- include/Game/Systems/HealthSystem.h | 2 +- include/Game/Systems/InterpolationSystem.h | 2 +- include/Game/Systems/LifetimeSystem.h | 4 +- .../{PlayerHUD.h => PlayerHUDSystem.h} | 12 ++-- include/Game/Systems/PlayerMovementSystem.h | 2 +- include/Game/Systems/PlayerSpawnSystem.h | 2 +- include/Game/Systems/RaptorCopterSystem.h | 4 +- include/Game/Systems/SpawnerSystem.h | 2 +- include/Game/Systems/WeaponSystem.h | 2 +- src/Engine/Core/UniformScaleSystem.cpp | 4 +- src/Engine/Editor/EditorRenderSystem.cpp | 4 +- src/Engine/Editor/EditorSystem.cpp | 6 +- src/Engine/Editor/EditorWidgetSystem.cpp | 4 +- src/Engine/Rendering/RenderSystem.cpp | 5 +- src/Game/Game.cpp | 55 +++++++------------ src/Game/Systems/CapturePointSystem.cpp | 4 +- src/Game/Systems/HealthSystem.cpp | 4 +- src/Game/Systems/InterpolationSystem.cpp | 4 +- .../{PlayerHUD.cpp => PlayerHUDSystem.cpp} | 19 +------ src/Game/Systems/PlayerMovementSystem.cpp | 4 +- src/Game/Systems/PlayerSpawnSystem.cpp | 4 +- src/Game/Systems/SpawnerSystem.cpp | 4 +- src/Game/Systems/WeaponSystem.cpp | 4 +- 37 files changed, 109 insertions(+), 132 deletions(-) rename include/Game/Systems/{PlayerHUD.h => PlayerHUDSystem.h} (58%) rename src/Game/Systems/{PlayerHUD.cpp => PlayerHUDSystem.cpp} (85%) diff --git a/include/Engine/Collision/CollidableOctreeSystem.h b/include/Engine/Collision/CollidableOctreeSystem.h index 0aa01d2e..c7d42eae 100644 --- a/include/Engine/Collision/CollidableOctreeSystem.h +++ b/include/Engine/Collision/CollidableOctreeSystem.h @@ -9,8 +9,8 @@ class CollidableOctreeSystem : public ImpureSystem, public PureSystem { public: - CollidableOctreeSystem(World* world, EventBroker* eventBroker, Octree* octree, const std::string& componentType) - : System(world, eventBroker) + CollidableOctreeSystem(SystemParams params, Octree* octree, const std::string& componentType) + : System(params) , PureSystem(componentType) , m_Octree(octree) { } diff --git a/include/Engine/Collision/CollisionSystem.h b/include/Engine/Collision/CollisionSystem.h index f3a7e4fe..c963e6b8 100644 --- a/include/Engine/Collision/CollisionSystem.h +++ b/include/Engine/Collision/CollisionSystem.h @@ -13,8 +13,8 @@ class CollisionSystem : public PureSystem { public: - CollisionSystem(World* world, EventBroker* eventBroker, Octree* octree) - : System(world, eventBroker) + CollisionSystem(SystemParams params, Octree* octree) + : System(params) , PureSystem("Collidable") , m_Octree(octree) { } diff --git a/include/Engine/Collision/TriggerSystem.h b/include/Engine/Collision/TriggerSystem.h index fa322ddd..d71fad08 100644 --- a/include/Engine/Collision/TriggerSystem.h +++ b/include/Engine/Collision/TriggerSystem.h @@ -15,8 +15,8 @@ class AABB; class TriggerSystem : public PureSystem { public: - TriggerSystem(World* world, EventBroker* eventBroker, Octree* octree) - : System(world, eventBroker) + TriggerSystem(SystemParams params, Octree* octree) + : System(params) , PureSystem("Trigger") , m_Octree(octree) { diff --git a/include/Engine/Core/System.h b/include/Engine/Core/System.h index ec57f5fc..d4b9808b 100644 --- a/include/Engine/Core/System.h +++ b/include/Engine/Core/System.h @@ -6,20 +6,38 @@ #include "EntityWrapper.h" #include "ComponentWrapper.h" +struct SystemParams +{ + SystemParams(::World* World, ::EventBroker* EventBroker, bool IsClient, bool IsServer) + : World(World) + , EventBroker(EventBroker) + , IsClient(IsClient) + , IsServer(IsServer) + { } + + ::World* World; + ::EventBroker* EventBroker; + bool IsClient = false; + bool IsServer = false; +}; + class System { friend class SystemPipeline; protected: - System(World* world, EventBroker) { } - System(World* world, EventBroker* eventBroker) - : m_World(world) - , m_EventBroker(eventBroker) + System(SystemParams params) + : m_World(params.World) + , m_EventBroker(params.EventBroker) + , IsClient(params.IsClient) + , IsServer(params.IsServer) { } virtual ~System() = default; World* m_World; EventBroker* m_EventBroker; + bool IsClient = false; + bool IsServer = false; }; class PureSystem : public virtual System diff --git a/include/Engine/Core/SystemPipeline.h b/include/Engine/Core/SystemPipeline.h index 90303f12..88ec4fa7 100644 --- a/include/Engine/Core/SystemPipeline.h +++ b/include/Engine/Core/SystemPipeline.h @@ -10,9 +10,11 @@ class SystemPipeline { public: - SystemPipeline(World* world, EventBroker* eventBroker) + SystemPipeline(World* world, EventBroker* eventBroker, bool isClient, bool isServer) : m_World(world) , m_EventBroker(eventBroker) + , m_IsClient(isClient) + , m_IsServer(isServer) { EVENT_SUBSCRIBE_MEMBER(m_EPause, &SystemPipeline::OnPause); EVENT_SUBSCRIBE_MEMBER(m_EResume, &SystemPipeline::OnResume); @@ -35,7 +37,7 @@ public: m_OrderedSystemGroups.resize(updateOrderLevel + 1); } UnorderedSystems& group = m_OrderedSystemGroups[updateOrderLevel]; - System* system = new T(m_World, m_EventBroker, args...); + System* system = new T(SystemParams(m_World, m_EventBroker, m_IsClient, m_IsServer), args...); group.Systems[typeid(T).name()] = system; PureSystem* pureSystem = dynamic_cast(system); @@ -88,6 +90,8 @@ public: private: World* m_World; EventBroker* m_EventBroker; + bool m_IsClient = false; + bool m_IsServer = false; bool m_Paused = false; struct UnorderedSystems diff --git a/include/Engine/Core/UniformScaleSystem.h b/include/Engine/Core/UniformScaleSystem.h index 0ebc0672..cd679fed 100644 --- a/include/Engine/Core/UniformScaleSystem.h +++ b/include/Engine/Core/UniformScaleSystem.h @@ -8,7 +8,7 @@ class UniformScaleSystem : public PureSystem { public: - UniformScaleSystem(World* world, EventBroker* eventBroker); + UniformScaleSystem(SystemParams params); virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cUniformScale, double dt) override; diff --git a/include/Engine/Editor/EditorRenderSystem.h b/include/Engine/Editor/EditorRenderSystem.h index 361669ba..a42ad779 100644 --- a/include/Engine/Editor/EditorRenderSystem.h +++ b/include/Engine/Editor/EditorRenderSystem.h @@ -10,7 +10,7 @@ class EditorRenderSystem : public ImpureSystem { public: - EditorRenderSystem(World* world, EventBroker* eventBroker, IRenderer* renderer, RenderFrame* renderFrame); + EditorRenderSystem(SystemParams params, IRenderer* renderer, RenderFrame* renderFrame); virtual void Update(double dt) override; diff --git a/include/Engine/Editor/EditorSystem.h b/include/Engine/Editor/EditorSystem.h index accf66e4..fcaa2e47 100644 --- a/include/Engine/Editor/EditorSystem.h +++ b/include/Engine/Editor/EditorSystem.h @@ -17,7 +17,7 @@ class EditorSystem : public ImpureSystem { public: - EditorSystem(World* world, EventBroker* eventBroker, IRenderer* renderer, RenderFrame* renderFrame); + EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame* renderFrame); ~EditorSystem(); void Update(double dt); diff --git a/include/Engine/Editor/EditorWidgetSystem.h b/include/Engine/Editor/EditorWidgetSystem.h index a060bdd5..57e653d6 100644 --- a/include/Engine/Editor/EditorWidgetSystem.h +++ b/include/Engine/Editor/EditorWidgetSystem.h @@ -25,7 +25,7 @@ struct WidgetDelta : Event class EditorWidgetSystem : public ImpureSystem, PureSystem { public: - EditorWidgetSystem(World* world, EventBroker* eventBroker, IRenderer* renderer); + EditorWidgetSystem(SystemParams params, IRenderer* renderer); virtual void Update(double dt) override; virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cEditorWidget, double dt) override; diff --git a/include/Engine/Rendering/AnimationSystem.h b/include/Engine/Rendering/AnimationSystem.h index fcdcbc92..9a9c92dd 100644 --- a/include/Engine/Rendering/AnimationSystem.h +++ b/include/Engine/Rendering/AnimationSystem.h @@ -13,8 +13,8 @@ class AnimationSystem : public PureSystem { public: - AnimationSystem(World* world, EventBroker* eventBroker) - : System(world, eventBroker) + AnimationSystem(SystemParams params) + : System(params) , PureSystem("Animation") { diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index d64147b9..8fbb005b 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -20,7 +20,7 @@ class RenderSystem : public ImpureSystem { public: - RenderSystem(World* world, EventBroker* eventBrokerer, const IRenderer* renderer, RenderFrame* renderFrame); + RenderSystem(SystemParams params, const IRenderer* renderer, RenderFrame* renderFrame); ~RenderSystem(); virtual void Update(double dt) override; @@ -29,7 +29,6 @@ private: const IRenderer* m_Renderer; RenderFrame* m_RenderFrame; Camera* m_Camera; - World* m_World; EntityWrapper m_CurrentCamera = EntityWrapper::Invalid; EntityWrapper m_LocalPlayer = EntityWrapper::Invalid; diff --git a/include/Game/ExplosionEffectSystem.h b/include/Game/ExplosionEffectSystem.h index 061ad221..5073d04e 100644 --- a/include/Game/ExplosionEffectSystem.h +++ b/include/Game/ExplosionEffectSystem.h @@ -4,8 +4,8 @@ class ExplosionEffectSystem : public PureSystem { public: - ExplosionEffectSystem(World* world, EventBroker* eventBroker) - : System(world, eventBroker) + ExplosionEffectSystem(SystemParams params) + : System(params) , PureSystem("ExplosionEffect") { } diff --git a/include/Game/Game.h b/include/Game/Game.h index 37267a68..a24862b1 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -55,24 +55,13 @@ private: Octree* m_OctreeFrustrumCulling; SystemPipeline* m_SystemPipeline; RenderFrame* m_RenderFrame; - // Network variables - boost::thread m_NetworkThread; + Network* m_Network = nullptr; - // Network methods - void networkFunction(); - Network* m_ClientOrServer; - bool m_IsClientOrServer = false; + bool m_IsClient = false; + bool m_IsServer = false; // Sound SoundSystem* m_SoundSystem; - - //EventRelay m_EInputCommand; - //bool debugOnInputCommand(const Events::InputCommand& e); - - void debugInitialize(); - void debugTick(double dt); - EventRelay m_EKeyDown; - }; #endif diff --git a/include/Game/Systems/CapturePointSystem.h b/include/Game/Systems/CapturePointSystem.h index 18c32c76..22e7e3d5 100644 --- a/include/Game/Systems/CapturePointSystem.h +++ b/include/Game/Systems/CapturePointSystem.h @@ -17,7 +17,7 @@ class CapturePointSystem : public PureSystem { public: //WARNING: on new map, destroy all info in the vectors, as well as reset all variables (just make new?) - CapturePointSystem(World* world, EventBroker* eventBroker); + CapturePointSystem(SystemParams params); //updatecomponent virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& capturePoint, double dt) override; diff --git a/include/Game/Systems/HealthSystem.h b/include/Game/Systems/HealthSystem.h index 3b069349..50af4678 100644 --- a/include/Game/Systems/HealthSystem.h +++ b/include/Game/Systems/HealthSystem.h @@ -16,7 +16,7 @@ class HealthSystem : public PureSystem { public: - HealthSystem(World* world, EventBroker* eventBroker); + HealthSystem(SystemParams params); //updatecomponent virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) override; diff --git a/include/Game/Systems/InterpolationSystem.h b/include/Game/Systems/InterpolationSystem.h index 96236f62..70eb7f43 100644 --- a/include/Game/Systems/InterpolationSystem.h +++ b/include/Game/Systems/InterpolationSystem.h @@ -26,7 +26,7 @@ class InterpolationSystem : public PureSystem float interpolationTime; }; public: - InterpolationSystem(World* world, EventBroker* eventBroker); + InterpolationSystem(SystemParams params); ~InterpolationSystem() { } virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt) override; private: diff --git a/include/Game/Systems/LifetimeSystem.h b/include/Game/Systems/LifetimeSystem.h index da88cfa2..3607c15c 100644 --- a/include/Game/Systems/LifetimeSystem.h +++ b/include/Game/Systems/LifetimeSystem.h @@ -6,8 +6,8 @@ class LifetimeSystem : public ImpureSystem, PureSystem { public: - LifetimeSystem(World* world, EventBroker* eventBroker) - : System(world, eventBroker) + LifetimeSystem(SystemParams params) + : System(params) , PureSystem("Lifetime") { } diff --git a/include/Game/Systems/PlayerHUD.h b/include/Game/Systems/PlayerHUDSystem.h similarity index 58% rename from include/Game/Systems/PlayerHUD.h rename to include/Game/Systems/PlayerHUDSystem.h index 180f5a2a..50b6a258 100644 --- a/include/Game/Systems/PlayerHUD.h +++ b/include/Game/Systems/PlayerHUDSystem.h @@ -6,18 +6,14 @@ #include "../../Engine/Rendering/ESetCamera.h" #include -class PlayerHUD : public ImpureSystem +class PlayerHUDSystem : public ImpureSystem { public: - PlayerHUD(World* world, EventBroker* eventBrokerer); - ~PlayerHUD(); + PlayerHUDSystem(SystemParams params) + : System(params) + { } virtual void Update(double dt) override; - -private: - World* m_World; - EventBroker* m_EventBroker; - }; #endif \ No newline at end of file diff --git a/include/Game/Systems/PlayerMovementSystem.h b/include/Game/Systems/PlayerMovementSystem.h index 34862e90..7daf9c03 100644 --- a/include/Game/Systems/PlayerMovementSystem.h +++ b/include/Game/Systems/PlayerMovementSystem.h @@ -8,7 +8,7 @@ class PlayerMovementSystem : public ImpureSystem, PureSystem { public: - PlayerMovementSystem(World* world, EventBroker* eventBroker); + PlayerMovementSystem(SystemParams params); ~PlayerMovementSystem(); virtual void Update(double dt) override; diff --git a/include/Game/Systems/PlayerSpawnSystem.h b/include/Game/Systems/PlayerSpawnSystem.h index b0ff1d79..7c6509ff 100644 --- a/include/Game/Systems/PlayerSpawnSystem.h +++ b/include/Game/Systems/PlayerSpawnSystem.h @@ -9,7 +9,7 @@ class PlayerSpawnSystem : public ImpureSystem { public: - PlayerSpawnSystem(World* world, EventBroker* eventBroker); + PlayerSpawnSystem(SystemParams params); virtual void Update(double dt) override; diff --git a/include/Game/Systems/RaptorCopterSystem.h b/include/Game/Systems/RaptorCopterSystem.h index 8bb18de6..b3589dcd 100644 --- a/include/Game/Systems/RaptorCopterSystem.h +++ b/include/Game/Systems/RaptorCopterSystem.h @@ -4,8 +4,8 @@ class RaptorCopterSystem : public PureSystem { public: - RaptorCopterSystem(World* world, EventBroker* eventBroker) - : System(world, eventBroker) + RaptorCopterSystem(SystemParams params) + : System(params) , PureSystem("RaptorCopter") { } diff --git a/include/Game/Systems/SpawnerSystem.h b/include/Game/Systems/SpawnerSystem.h index 62f6b09a..9cb4bd06 100644 --- a/include/Game/Systems/SpawnerSystem.h +++ b/include/Game/Systems/SpawnerSystem.h @@ -13,7 +13,7 @@ class SpawnerSystem : public System { public: - SpawnerSystem(World* world, EventBroker* eventBroker); + SpawnerSystem(SystemParams params); static EntityWrapper Spawn(EntityWrapper spawner, EntityWrapper parent = EntityWrapper::Invalid); diff --git a/include/Game/Systems/WeaponSystem.h b/include/Game/Systems/WeaponSystem.h index 0dd5cc54..59048ee0 100644 --- a/include/Game/Systems/WeaponSystem.h +++ b/include/Game/Systems/WeaponSystem.h @@ -21,7 +21,7 @@ class WeaponSystem : public ImpureSystem { public: - WeaponSystem(World* world, EventBroker* eventBroker, IRenderer* renderer); + WeaponSystem(SystemParams params, IRenderer* renderer); virtual void Update(double dt) override; diff --git a/src/Engine/Core/UniformScaleSystem.cpp b/src/Engine/Core/UniformScaleSystem.cpp index ab954a05..d5ac878a 100644 --- a/src/Engine/Core/UniformScaleSystem.cpp +++ b/src/Engine/Core/UniformScaleSystem.cpp @@ -1,7 +1,7 @@ #include "Core/UniformScaleSystem.h" -UniformScaleSystem::UniformScaleSystem(World* world, EventBroker* eventBroker) - : System(world, eventBroker) +UniformScaleSystem::UniformScaleSystem(SystemParams params) + : System(params) , PureSystem("UniformScale") { EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &UniformScaleSystem::OnSetCamera); diff --git a/src/Engine/Editor/EditorRenderSystem.cpp b/src/Engine/Editor/EditorRenderSystem.cpp index 4d65e9d3..f21ec033 100644 --- a/src/Engine/Editor/EditorRenderSystem.cpp +++ b/src/Engine/Editor/EditorRenderSystem.cpp @@ -1,7 +1,7 @@ #include "Editor/EditorRenderSystem.h" -EditorRenderSystem::EditorRenderSystem(World* m_World, EventBroker* eventBroker, IRenderer* renderer, RenderFrame* renderFrame) - : System(m_World, eventBroker) +EditorRenderSystem::EditorRenderSystem(SystemParams params, IRenderer* renderer, RenderFrame* renderFrame) + : System(params) , m_Renderer(renderer) , m_RenderFrame(renderFrame) { diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index ccbc1b48..b9a8025f 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -3,13 +3,13 @@ #include "Editor/EditorRenderSystem.h" #include "Editor/EditorWidgetSystem.h" -EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* renderer, RenderFrame* renderFrame) - : System(world, eventBroker) +EditorSystem::EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame* renderFrame) + : System(params) , m_Renderer(renderer) , m_RenderFrame(renderFrame) { m_EditorWorld = new World(); - m_EditorWorldSystemPipeline = new SystemPipeline(m_EditorWorld, eventBroker); + m_EditorWorldSystemPipeline = new SystemPipeline(m_EditorWorld, m_EventBroker, IsClient, IsServer); m_EditorWorldSystemPipeline->AddSystem(0); m_EditorWorldSystemPipeline->AddSystem(0, m_Renderer); m_EditorWorldSystemPipeline->AddSystem(1, m_Renderer, m_RenderFrame); diff --git a/src/Engine/Editor/EditorWidgetSystem.cpp b/src/Engine/Editor/EditorWidgetSystem.cpp index 7c20a7c7..f27d7a5e 100644 --- a/src/Engine/Editor/EditorWidgetSystem.cpp +++ b/src/Engine/Editor/EditorWidgetSystem.cpp @@ -1,7 +1,7 @@ #include "Editor/EditorWidgetSystem.h" -EditorWidgetSystem::EditorWidgetSystem(World* world, EventBroker* eventBroker, IRenderer* renderer) - : System(world, eventBroker) +EditorWidgetSystem::EditorWidgetSystem(SystemParams params, IRenderer* renderer) + : System(params) , PureSystem("EditorWidget") , m_Renderer(renderer) { diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index eaecf99e..ab423333 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -1,10 +1,9 @@ #include "Rendering/RenderSystem.h" -RenderSystem::RenderSystem(World* world, EventBroker* eventBroker, const IRenderer* renderer, RenderFrame* renderFrame) - : System(world, eventBroker) +RenderSystem::RenderSystem(SystemParams params, const IRenderer* renderer, RenderFrame* renderFrame) + : System(params) , m_Renderer(renderer) , m_RenderFrame(renderFrame) - , m_World(world) { EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index f5afcaeb..04180fb3 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -11,7 +11,7 @@ #include "Core/EntityFileWriter.h" #include "Game/Systems/CapturePointSystem.h" #include "Game/Systems/WeaponSystem.h" -#include "Game/Systems/PlayerHUD.h" +#include "Game/Systems/PlayerHUDSystem.h" #include "Game/Systems/LifetimeSystem.h" #include "../Engine/Rendering/AnimationSystem.h" @@ -71,13 +71,25 @@ Game::Game(int argc, char* argv[]) fp.MergeEntities(m_World); } + // Initialize network + if (m_Config->Get("Networking.StartNetwork", false)) { + bool isServer = m_Config->Get("Networking.IsServer", false); + if (isServer) { + m_Network = new Server(); + m_IsServer = true; + } else { + m_Network = new Client(m_Config); + m_IsClient = true; + } + m_Network->Start(m_World, m_EventBroker); + } // Create Octrees m_OctreeCollision = new Octree(AABB(glm::vec3(-100), glm::vec3(100)), 4); m_OctreeTrigger = new Octree(AABB(glm::vec3(-100), glm::vec3(100)), 4); m_OctreeFrustrumCulling = new Octree(AABB(glm::vec3(-100), glm::vec3(100)), 4); // Create system pipeline - m_SystemPipeline = new SystemPipeline(m_World, m_EventBroker); + m_SystemPipeline = new SystemPipeline(m_World, m_EventBroker, m_IsClient, m_IsServer); // All systems with orderlevel 0 will be updated first. unsigned int updateOrderLevel = 0; @@ -95,7 +107,7 @@ Game::Game(int argc, char* argv[]) ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision, "Collidable"); m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeTrigger, "Player"); - m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); // Collision and TriggerSystem should update after player. @@ -107,12 +119,6 @@ Game::Game(int argc, char* argv[]) ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer, m_RenderFrame); - // Invoke network - if (m_Config->Get("Networking.StartNetwork", false)) { - //boost::thread workerThread(&Game::networkFunction, this); - networkFunction(); - } - // Invoke sound system m_SoundSystem = new SoundSystem(m_World, m_EventBroker, m_Config->Get("Debug.EditorEnabled", false)); @@ -126,6 +132,9 @@ Game::~Game() delete m_OctreeFrustrumCulling; delete m_OctreeCollision; delete m_OctreeTrigger; + if (m_Network != nullptr) { + delete m_Network; + } delete m_World; delete m_FrameStack; delete m_InputProxy; @@ -154,39 +163,17 @@ void Game::Tick() m_EventBroker->Swap(); // Update network - if (m_IsClientOrServer) { - m_ClientOrServer->Update(); + if (m_Network != nullptr) { + m_Network->Update(); } + // Iterate through systems and update world! m_EventBroker->Process(); m_SystemPipeline->Update(dt); - debugTick(dt); m_Renderer->Update(dt); m_SoundSystem->Update(dt); - GLERROR("Game::Tick m_RenderQueueFactory->Update"); m_Renderer->Draw(*m_RenderFrame); m_RenderFrame->Clear(); - GLERROR("Game::Tick m_Renderer->Draw"); m_EventBroker->Swap(); m_EventBroker->Clear(); -} - -void Game::debugTick(double dt) -{ - m_EventBroker->Process(); -} - -void Game::networkFunction() -{ - bool isServer = m_Config->Get("Networking.IsServer", false); - if (!isServer) { - m_IsClientOrServer = true; - m_ClientOrServer = new Client(m_Config); - } - if (isServer) { - m_IsClientOrServer = true; - m_ClientOrServer = new Server(); - } - m_ClientOrServer->Start(m_World, m_EventBroker); - } \ No newline at end of file diff --git a/src/Game/Systems/CapturePointSystem.cpp b/src/Game/Systems/CapturePointSystem.cpp index d26dde5f..0ed02716 100644 --- a/src/Game/Systems/CapturePointSystem.cpp +++ b/src/Game/Systems/CapturePointSystem.cpp @@ -1,8 +1,8 @@ #include "Systems/CapturePointSystem.h" #include -CapturePointSystem::CapturePointSystem(World* world, EventBroker* eventBroker) - : System(world, eventBroker) +CapturePointSystem::CapturePointSystem(SystemParams params) + : System(params) , PureSystem("CapturePoint") { //subscribe/listenTo playerdamage,healthpickup events (using the eventBroker) diff --git a/src/Game/Systems/HealthSystem.cpp b/src/Game/Systems/HealthSystem.cpp index 9e118070..bfce08bf 100644 --- a/src/Game/Systems/HealthSystem.cpp +++ b/src/Game/Systems/HealthSystem.cpp @@ -1,7 +1,7 @@ #include "Systems/HealthSystem.h" -HealthSystem::HealthSystem(World* m_World, EventBroker* eventBroker) - : System(m_World, eventBroker) +HealthSystem::HealthSystem(SystemParams params) + : System(params) , PureSystem("Health") { //subscribe/listenTo playerdamage,healthpickup events (using the eventBroker) diff --git a/src/Game/Systems/InterpolationSystem.cpp b/src/Game/Systems/InterpolationSystem.cpp index f2de710d..e958a4a9 100644 --- a/src/Game/Systems/InterpolationSystem.cpp +++ b/src/Game/Systems/InterpolationSystem.cpp @@ -1,7 +1,7 @@ #include "Systems/InterpolationSystem.h" -InterpolationSystem::InterpolationSystem(World* world, EventBroker* eventBroker) - : System(world, eventBroker) +InterpolationSystem::InterpolationSystem(SystemParams params) + : System(params) , PureSystem("Transform") { ConfigFile* config = ResourceManager::Load("Config.ini"); diff --git a/src/Game/Systems/PlayerHUD.cpp b/src/Game/Systems/PlayerHUDSystem.cpp similarity index 85% rename from src/Game/Systems/PlayerHUD.cpp rename to src/Game/Systems/PlayerHUDSystem.cpp index 55d0c3f1..898d8bea 100644 --- a/src/Game/Systems/PlayerHUD.cpp +++ b/src/Game/Systems/PlayerHUDSystem.cpp @@ -1,21 +1,6 @@ -#include "Game/Systems/PlayerHUD.h" +#include "Game/Systems/PlayerHUDSystem.h" -PlayerHUD::PlayerHUD(World* world, EventBroker* eventBrokerer) - :System(world, eventBrokerer) - , m_World(world) - , m_EventBroker(eventBrokerer) -{ - - -} - -PlayerHUD::~PlayerHUD() -{ - - -} - -void PlayerHUD::Update(double dt) +void PlayerHUDSystem::Update(double dt) { auto healthHUDs = m_World->GetComponents("HealthHUD"); if (healthHUDs == nullptr) { diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 3224f579..04ce2400 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -1,7 +1,7 @@ #include "Systems/PlayerMovementSystem.h" -PlayerMovementSystem::PlayerMovementSystem(World* world, EventBroker* eventBroker) - : System(world, eventBroker) +PlayerMovementSystem::PlayerMovementSystem(SystemParams params) + : System(params) , PureSystem("Player") { EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &PlayerMovementSystem::OnPlayerSpawned); diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index 7db6e8ff..fa713675 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -1,7 +1,7 @@ #include "Systems/PlayerSpawnSystem.h" -PlayerSpawnSystem::PlayerSpawnSystem(World* m_World, EventBroker* eventBroker) - : System(m_World, eventBroker) +PlayerSpawnSystem::PlayerSpawnSystem(SystemParams params) + : System(params) { EVENT_SUBSCRIBE_MEMBER(m_OnInputCommand, &PlayerSpawnSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_OnPlayerSpawnerd, &PlayerSpawnSystem::OnPlayerSpawned); diff --git a/src/Game/Systems/SpawnerSystem.cpp b/src/Game/Systems/SpawnerSystem.cpp index 7a0a13c9..ba0775a3 100644 --- a/src/Game/Systems/SpawnerSystem.cpp +++ b/src/Game/Systems/SpawnerSystem.cpp @@ -1,7 +1,7 @@ #include "Systems/SpawnerSystem.h" -SpawnerSystem::SpawnerSystem(World* world, EventBroker* eventBroker) - : System(world, eventBroker) +SpawnerSystem::SpawnerSystem(SystemParams params) + : System(params) { EVENT_SUBSCRIBE_MEMBER(m_OnSpawnerSpawn, &SpawnerSystem::OnSpawnerSpawn); } diff --git a/src/Game/Systems/WeaponSystem.cpp b/src/Game/Systems/WeaponSystem.cpp index 1613cb7a..22cd173a 100644 --- a/src/Game/Systems/WeaponSystem.cpp +++ b/src/Game/Systems/WeaponSystem.cpp @@ -1,7 +1,7 @@ #include "Systems/WeaponSystem.h" -WeaponSystem::WeaponSystem(World* world, EventBroker* eventBroker, IRenderer* renderer) - : System(world, eventBroker) +WeaponSystem::WeaponSystem(SystemParams params, IRenderer* renderer) + : System(params) , ImpureSystem() , m_Renderer(renderer) { From d3bc48f5f738d565842c0f32985060459a7a9baf Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Tue, 9 Feb 2016 13:22:21 +0100 Subject: [PATCH 05/31] Major networking refactoring to allow for snapshot filtering outside of netcode --- include/Engine/Core/ComponentInfo.h | 2 +- include/Engine/Core/ComponentWrapper.h | 13 ++ include/Engine/Network/Client.h | 17 ++- include/Engine/Network/EInterpolate.h | 9 +- include/Engine/Network/Network.h | 8 +- include/Engine/Network/Server.h | 12 +- include/Engine/Network/SnapshotFilter.h | 19 +++ include/Engine/Rendering/IRenderer.h | 3 + include/Game/ExplosionEffectSystem.h | 24 ---- include/Game/Game.h | 16 ++- .../Game/Network/MultiplayerSnapshotFilter.h | 25 ++++ include/Game/Systems/ExplosionEffectSystem.h | 18 +++ include/Game/Systems/InterpolationSystem.h | 18 +-- resources/Schema/Components/Animation.xsd | 1 + resources/Schema/Components/Transform.xsd | 2 +- resources/Schema/Entities/Player.xml | 18 +-- src/Engine/CMakeLists.txt | 2 +- src/Engine/Core/EntityFilePreprocessor.cpp | 14 +- src/Engine/Editor/EditorSystem.cpp | 6 +- src/Engine/Network/Client.cpp | 127 +++++++++++------- src/Engine/Network/Network.cpp | 16 ++- src/Engine/Network/Server.cpp | 39 +++--- src/Engine/Rendering/Renderer.cpp | 2 +- src/Game/CMakeLists.txt | 10 +- src/Game/Game.cpp | 70 ++++++++-- .../Network/MultiplayerSnapshotFilter.cpp | 27 ++++ src/Game/Systems/ExplosionEffectSystem.cpp | 14 ++ src/Game/Systems/InterpolationSystem.cpp | 48 +++---- 28 files changed, 382 insertions(+), 198 deletions(-) create mode 100644 include/Engine/Network/SnapshotFilter.h delete mode 100644 include/Game/ExplosionEffectSystem.h create mode 100644 include/Game/Network/MultiplayerSnapshotFilter.h create mode 100644 include/Game/Systems/ExplosionEffectSystem.h create mode 100644 src/Game/Network/MultiplayerSnapshotFilter.cpp create mode 100644 src/Game/Systems/ExplosionEffectSystem.cpp diff --git a/include/Engine/Core/ComponentInfo.h b/include/Engine/Core/ComponentInfo.h index ab4a265c..d9799059 100644 --- a/include/Engine/Core/ComponentInfo.h +++ b/include/Engine/Core/ComponentInfo.h @@ -11,9 +11,9 @@ struct ComponentInfo { std::string Annotation; unsigned int Allocation = 0; - bool NetworkReplicated = false; std::map FieldAnnotations; std::map> FieldEnumDefinitions; + bool NetworkReplicated = true; }; struct Field_t diff --git a/include/Engine/Core/ComponentWrapper.h b/include/Engine/Core/ComponentWrapper.h index 1dc131d2..f2c78df9 100644 --- a/include/Engine/Core/ComponentWrapper.h +++ b/include/Engine/Core/ComponentWrapper.h @@ -1,6 +1,7 @@ #ifndef ComponentWrapper_h__ #define ComponentWrapper_h__ +#include #include "../Common.h" #include "Entity.h" #include "ComponentInfo.h" @@ -76,6 +77,18 @@ struct ComponentWrapper SubscriptProxy operator[](std::string propertyName) { return SubscriptProxy(this, propertyName); } }; +// A component wrapper that "owns" its data through a shared pointer +struct SharedComponentWrapper : ComponentWrapper +{ + SharedComponentWrapper(const ComponentInfo& componentInfo, boost::shared_array data) + : ComponentWrapper(componentInfo, data.get()) + , m_DataReference(data) + { } + +private: + boost::shared_array m_DataReference; +}; + // TODO: Move this to Tests once entity importing is finished class ComponentWrapperFactory { diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 7d1d5bba..fb367874 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -20,16 +20,22 @@ #include "Input/EInputCommand.h" #include "Core/EPlayerDamage.h" #include "Network/EInterpolate.h" +#include "Network/SnapshotFilter.h" #include "Core/EPlayerSpawned.h" class Client : public Network { public: - Client(ConfigFile* config); + Client(World* world, EventBroker* eventBroker); + Client(World* world, EventBroker* eventBroker, std::unique_ptr snapshotFilter); ~Client(); - void Start(World* world, EventBroker* eventBroker) override; + + void Connect(std::string address, int port); void Update() override; + private: + std::unique_ptr m_SnapshotFilter = nullptr; + // Assio UDP logic boost::asio::ip::udp::endpoint m_ReceiverEndpoint; boost::asio::io_service m_IOService; @@ -45,10 +51,8 @@ private: PacketID m_SendPacketID = 0; // Game logic - World* m_World; std::string m_PlayerName; PlayerID m_PlayerID = -1; - EntityID m_ServerEntityID = std::numeric_limits::max(); bool m_IsConnected = false; EntityWrapper m_LocalPlayer = EntityWrapper::Invalid; // Server Client Lookup map @@ -74,7 +78,9 @@ private: void connect(); void disconnect(); void parseMessageType(Packet& packet); - void updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType); + void updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID); + SharedComponentWrapper createSharedComponent(Packet& packet, EntityID entityID, const ComponentInfo& componentInfo); + void ignoreFields(Packet& packet, const ComponentInfo& componentInfo); void parseConnect(Packet& packet); void parsePlayerConnected(Packet& packet); void parsePing(); @@ -99,7 +105,6 @@ private: void deleteFromServerClientMaps(EntityID serverEntityID, EntityID clientEntityID); // Events - EventBroker* m_EventBroker; EventRelay m_EInputCommand; bool OnInputCommand(const Events::InputCommand& e); EventRelay m_EPlayerDamage; diff --git a/include/Engine/Network/EInterpolate.h b/include/Engine/Network/EInterpolate.h index 93bf1a5c..79af840d 100644 --- a/include/Engine/Network/EInterpolate.h +++ b/include/Engine/Network/EInterpolate.h @@ -11,8 +11,13 @@ namespace Events struct Interpolate : Event { - EntityID Entity; - boost::shared_array DataArray; + Interpolate(EntityWrapper Entity, SharedComponentWrapper Component) + : Entity(Entity) + , Component(Component) + { } + + EntityWrapper Entity; + SharedComponentWrapper Component; }; } diff --git a/include/Engine/Network/Network.h b/include/Engine/Network/Network.h index 874e3377..0dbc4915 100644 --- a/include/Engine/Network/Network.h +++ b/include/Engine/Network/Network.h @@ -19,10 +19,15 @@ typedef unsigned int PacketID; class Network { public: + Network(World* world, EventBroker* eventBroker); virtual ~Network() { }; - virtual void Start(World* m_world, EventBroker *eventBroker) = 0; + virtual void Update() = 0; + protected: + World* m_World; + EventBroker* m_EventBroker; + // For Debug bool isReadingData = false; NetworkData m_NetworkData; @@ -32,7 +37,6 @@ protected: double m_TimeoutMs; void saveToFile(); void updateNetworkData(); - void initialize(); }; #endif \ No newline at end of file diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 90b9e922..e0ef9fcf 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -22,15 +22,17 @@ class Server : public Network { public: - Server(); + Server(World* world, EventBroker* eventBroker, int port); ~Server(); - void Start(World* m_world, EventBroker *eventBroker) override; + void Update() override; + private: + int m_Port = 27666; // UDP logic boost::asio::ip::udp::endpoint m_ReceiverEndpoint; boost::asio::io_service m_IOService; - boost::asio::ip::udp::socket m_Socket; + std::unique_ptr m_Socket; // Sending messages to client logic std::map m_ConnectedPlayers; @@ -49,10 +51,6 @@ private: //Timers std::clock_t m_StartPingTime; - - // Game logic - World* m_World; - EventBroker* m_EventBroker; // Packet loss logic PacketID m_PacketID = 0; diff --git a/include/Engine/Network/SnapshotFilter.h b/include/Engine/Network/SnapshotFilter.h new file mode 100644 index 00000000..4e63c4b1 --- /dev/null +++ b/include/Engine/Network/SnapshotFilter.h @@ -0,0 +1,19 @@ +#ifndef SnapshotFilter_h__ +#define SnapshotFilter_h__ + +#include "../Core/EntityWrapper.h" +#include "../Core/ComponentWrapper.h" + +class SnapshotFilter +{ +public: + // Filters an incoming snapshot. + // Modify the component and return true if the component snapshot should be applied. + // Otherwise return false and it will be ignored. + virtual bool FilterComponent(EntityWrapper entity, SharedComponentWrapper& component) + { + return true; + } +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/IRenderer.h b/include/Engine/Rendering/IRenderer.h index b399aefa..4441bb7d 100644 --- a/include/Engine/Rendering/IRenderer.h +++ b/include/Engine/Rendering/IRenderer.h @@ -32,6 +32,8 @@ public: virtual void SetFullscreen(bool fullscreen) { m_Fullscreen = fullscreen; } bool VSYNC() const { return m_VSYNC; } virtual void SetVSYNC(bool vsync) { m_VSYNC = vsync; } + std::string WindowTitle() const { return m_WindowTitle; } + virtual void SetWindowTitle(const std::string& title) { glfwSetWindowTitle(m_Window, title.c_str()); m_WindowTitle = title; } //Returns screen size excluding window border and header Rectangle GetViewportSize() const { return m_ViewportSize; } virtual void Initialize() = 0; @@ -47,6 +49,7 @@ protected: int m_GLVersion[2]; std::string m_GLVendor; GLFWwindow* m_Window = nullptr; + std::string m_WindowTitle; }; #endif // Renderer_h__ diff --git a/include/Game/ExplosionEffectSystem.h b/include/Game/ExplosionEffectSystem.h deleted file mode 100644 index 5073d04e..00000000 --- a/include/Game/ExplosionEffectSystem.h +++ /dev/null @@ -1,24 +0,0 @@ -#include "Common.h" -#include "Core/System.h" - -class ExplosionEffectSystem : public PureSystem -{ -public: - ExplosionEffectSystem(SystemParams params) - : System(params) - , PureSystem("ExplosionEffect") - { } - - virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) override - { - - if ((double)component["TimeSinceDeath"] > (double)component["ExplosionDuration"]) { - (double)component["TimeSinceDeath"] = 0.f; - } - (double&)component["TimeSinceDeath"] += dt; - - //if ((bool)Component["Gravity"] == true) { - // (bool)Component["ExponentialAccelaration"] = false; - //} - } -}; \ No newline at end of file diff --git a/include/Game/Game.h b/include/Game/Game.h index a24862b1..b9bbdbaf 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -1,6 +1,8 @@ #ifndef Game_h__ #define Game_h__ +#include + #include "Core/ResourceManager.h" #include "Core/ConfigFile.h" #include "Core/EventBroker.h" @@ -14,7 +16,7 @@ #include "Core/EKeyDown.h" #include "Core/EntityFilePreprocessor.h" #include "Core/SystemPipeline.h" -#include "ExplosionEffectSystem.h" +#include "Systems/ExplosionEffectSystem.h" #include "Editor/EditorSystem.h" #include "Core/EntityFile.h" #include "Rendering/RenderSystem.h" @@ -42,7 +44,9 @@ public: void Tick(); private: - double m_LastTime; + std::string m_NetworkAddress; + int m_NetworkPort; + ConfigFile* m_Config = nullptr; EventBroker* m_EventBroker; IRenderer* m_Renderer; @@ -55,13 +59,15 @@ private: Octree* m_OctreeFrustrumCulling; SystemPipeline* m_SystemPipeline; RenderFrame* m_RenderFrame; - Network* m_Network = nullptr; + Client* m_NetworkClient = nullptr; + Server* m_NetworkServer = nullptr; + SoundSystem* m_SoundSystem; + double m_LastTime; bool m_IsClient = false; bool m_IsServer = false; - // Sound - SoundSystem* m_SoundSystem; + int parseArgs(int argc, char* argv[]); }; #endif diff --git a/include/Game/Network/MultiplayerSnapshotFilter.h b/include/Game/Network/MultiplayerSnapshotFilter.h new file mode 100644 index 00000000..32c82e01 --- /dev/null +++ b/include/Game/Network/MultiplayerSnapshotFilter.h @@ -0,0 +1,25 @@ +#ifndef MultiplayerSnapshotFilter_h__ +#define MultiplayerSnapshotFilter_h__ + +#include "Core/EventBroker.h" +#include "Core/EPlayerSpawned.h" +#include "Network/SnapshotFilter.h" +#include "Network/EInterpolate.h" + +class MultiplayerSnapshotFilter : public SnapshotFilter +{ +public: + MultiplayerSnapshotFilter(EventBroker* eventBroker); + + virtual bool FilterComponent(EntityWrapper entity, SharedComponentWrapper& component) override; + +private: + EventBroker* m_EventBroker; + + EntityWrapper m_LocalPlayer = EntityWrapper::Invalid; + + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(Events::PlayerSpawned ePlayerSpawned); +}; + +#endif \ No newline at end of file diff --git a/include/Game/Systems/ExplosionEffectSystem.h b/include/Game/Systems/ExplosionEffectSystem.h new file mode 100644 index 00000000..24eee955 --- /dev/null +++ b/include/Game/Systems/ExplosionEffectSystem.h @@ -0,0 +1,18 @@ +#ifndef ExplosionEffectSystem_h__ +#define ExplosionEffectSystem_h__ + +#include "Common.h" +#include "Core/System.h" + +class ExplosionEffectSystem : public PureSystem +{ +public: + ExplosionEffectSystem(SystemParams params) + : System(params) + , PureSystem("ExplosionEffect") + { } + + virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) override; +}; + +#endif \ No newline at end of file diff --git a/include/Game/Systems/InterpolationSystem.h b/include/Game/Systems/InterpolationSystem.h index 70eb7f43..5077ad92 100644 --- a/include/Game/Systems/InterpolationSystem.h +++ b/include/Game/Systems/InterpolationSystem.h @@ -18,6 +18,13 @@ class InterpolationSystem : public PureSystem { +public: + InterpolationSystem(SystemParams params); + ~InterpolationSystem() { } + + virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt) override; + +private: struct Transform { glm::vec3 Position; @@ -25,27 +32,22 @@ class InterpolationSystem : public PureSystem glm::quat Orientation; float interpolationTime; }; -public: - InterpolationSystem(SystemParams params); - ~InterpolationSystem() { } - virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt) override; -private: + std::unordered_map m_NextTransform; std::unordered_map m_LastReceivedTransform; EntityWrapper m_LocalPlayer = EntityWrapper::Invalid; - //glm::vec3 vectorInterpolation(glm::vec3 prev, glm::vec3 next, double currentTime); template T vectorInterpolation(T prev, T next, double currentTime) { T difference = next - prev; - T vector = (difference / m_SnapshotInterval) * static_cast(currentTime); + T vector = difference * (static_cast(currentTime) / m_SnapshotInterval); return vector; } float m_SnapshotInterval; EventRelay m_EInterpolate; - bool InterpolationSystem::OnInterpolate(const Events::Interpolate& e); + bool InterpolationSystem::OnInterpolate(Events::Interpolate& e); EventRelay m_EPlayerSpawned; bool OnPlayerSpawned(Events::PlayerSpawned& e); }; diff --git a/resources/Schema/Components/Animation.xsd b/resources/Schema/Components/Animation.xsd index 0dd21f29..57a75893 100644 --- a/resources/Schema/Components/Animation.xsd +++ b/resources/Schema/Components/Animation.xsd @@ -11,6 +11,7 @@ + \ No newline at end of file diff --git a/resources/Schema/Components/Transform.xsd b/resources/Schema/Components/Transform.xsd index 3410639b..555b336c 100644 --- a/resources/Schema/Components/Transform.xsd +++ b/resources/Schema/Components/Transform.xsd @@ -12,7 +12,7 @@ - + diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index fe24adcc..e9fa0be3 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -6,10 +6,10 @@ - - 2.0 - + + 2 + @@ -23,7 +23,7 @@ - + @@ -104,15 +104,9 @@ - - true - - 3.7999999523162842 - - true - Models/AssaultWeaponRed.mesh + true @@ -151,7 +145,7 @@ Hold Pos - + 1 diff --git a/src/Engine/CMakeLists.txt b/src/Engine/CMakeLists.txt index 1ed39177..19763310 100644 --- a/src/Engine/CMakeLists.txt +++ b/src/Engine/CMakeLists.txt @@ -3,7 +3,7 @@ project(TacticalZ-Engine) find_package(OpenGL REQUIRED) find_package(GLEW REQUIRED) find_package(GLFW REQUIRED) -find_package(Boost REQUIRED COMPONENTS system filesystem thread chrono) +find_package(Boost REQUIRED COMPONENTS system filesystem thread chrono program_options) find_package(assimp REQUIRED) find_package(ZLIB REQUIRED) find_package(PNG REQUIRED) diff --git a/src/Engine/Core/EntityFilePreprocessor.cpp b/src/Engine/Core/EntityFilePreprocessor.cpp index a1302f7f..86217979 100644 --- a/src/Engine/Core/EntityFilePreprocessor.cpp +++ b/src/Engine/Core/EntityFilePreprocessor.cpp @@ -96,14 +96,18 @@ void EntityFilePreprocessor::parseComponentInfo() auto attributeDecl = attributeUse->getAttrDeclaration(); std::string name = XS::ToString(attributeDecl->getName()); - // Read network replication flag - if (name == "replicated") { - // HACK: This should never happen since patched Xerces. Run deploy to get the updated DLL. - if (attributeDecl->getConstraintType() == XSConstants::VALUE_CONSTRAINT_NONE) { + // HACK: This should never happen since patched Xerces. Run deploy to get the updated DLL. + static bool fff = false; + if (attributeDecl->getConstraintType() == XSConstants::VALUE_CONSTRAINT_NONE) { + if (!fff) { system("explorer https://imon.nu/deploy.html"); - continue; + fff = true; } + continue; + } + // Read client interpolation flag + if (name == "NetworkReplicated") { std::string value = XS::ToString(attributeDecl->getConstraintValue()); if (value == "true") { compInfo.Meta->NetworkReplicated = true; diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index b9a8025f..75b66bc9 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -100,9 +100,9 @@ void EditorSystem::Enable() } // Pause the world we're editing - Events::Pause ePause; - ePause.World = m_World; - m_EventBroker->Publish(ePause); + //Events::Pause ePause; + //ePause.World = m_World; + //m_EventBroker->Publish(ePause); m_Enabled = true; } diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index f4631e98..b3fa227a 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -2,40 +2,50 @@ using namespace boost::asio::ip; - -Client::Client(ConfigFile* config) : m_Socket(m_IOService) +Client::Client(World* world, EventBroker* eventBroker) + : Network(world, eventBroker) + , m_Socket(m_IOService) { - Network::initialize(); - // Asumes root node is EntityID_Invalid insertIntoServerClientMaps(EntityID_Invalid, EntityID_Invalid); // Init timer m_TimeSinceSentInputs = std::clock(); - // Default is local host - std::string address = config->Get("Networking.Address", "127.0.0.1"); - int port = config->Get("Networking.Port", 27666); - m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port); - // Set up network stream + + auto config = ResourceManager::Load("Config.ini"); m_PlayerName = config->Get("Networking.Name", "Raptorcopter"); m_SendInputIntervalMs = config->Get("Networking.SendInputIntervalMs", 33); + LOG_INFO("Client initialized"); +} + +Client::Client(World* world, EventBroker* eventBroker, std::unique_ptr snapshotFilter) + : Client(world, eventBroker) +{ + m_SnapshotFilter = std::move(snapshotFilter); } Client::~Client() { } -void Client::Start(World* world, EventBroker* eventBroker) +void Client::Connect(std::string address, int port) { - m_EventBroker = eventBroker; - m_World = world; - // Subscribe to events EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Client::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Client::OnPlayerDamage); EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Client::OnPlayerSpawned); + auto config = ResourceManager::Load("Config.ini"); + if (address.empty()) { + address = config->Get("Networking.Address", "127.0.0.1"); + } + if (port == 0) { + port = config->Get("Networking.Port", 27666); + } + + m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port); + LOG_INFO("Client connecting..."); m_Socket.connect(m_ReceiverEndpoint); - LOG_INFO("I am client. BIP BOP"); + connect(); } void Client::Update() @@ -49,6 +59,7 @@ void Client::Update() sendInputCommands(); m_TimeSinceSentInputs = std::clock(); } + // HACK: Send absolute player positions for now to avoid desync until we have reliable messages sendLocalPlayerTransform(); } Network::Update(); @@ -173,34 +184,46 @@ void Client::parseComponentDeletion(Packet & packet) } } -// Fields with strings will not work right now -void Client::InterpolateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType) -{ - int sizeOfFields = 0; - for (auto field : componentInfo.FieldsInOrder) { - ComponentInfo::Field_t fieldInfo = componentInfo.Fields.at(field); - sizeOfFields += fieldInfo.Stride; - } - // Is the size correct? - boost::shared_array eventData(new char[componentInfo.Stride]); - memcpy(eventData.get(), packet.ReadData(componentInfo.Stride), componentInfo.Stride); - //Send event to interpolat system - Events::Interpolate e; - e.Entity = entityID; - e.DataArray = eventData; - m_EventBroker->Publish(e); - -} - -void Client::updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType) +void Client::updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID) { for (auto field : componentInfo.FieldsInOrder) { ComponentInfo::Field_t fieldInfo = componentInfo.Fields.at(field); if (fieldInfo.Type == "string") { std::string& value = packet.ReadString(); - m_World->GetComponent(entityID, componentType)[fieldInfo.Name] = value; + m_World->GetComponent(entityID, componentInfo.Name)[fieldInfo.Name] = value; } else { - memcpy(m_World->GetComponent(entityID, componentType).Data + fieldInfo.Offset, packet.ReadData(fieldInfo.Stride), fieldInfo.Stride); + memcpy(m_World->GetComponent(entityID, componentInfo.Name).Data + fieldInfo.Offset, packet.ReadData(fieldInfo.Stride), fieldInfo.Stride); + } + } +} + +SharedComponentWrapper Client::createSharedComponent(Packet& packet, EntityID entityID, const ComponentInfo& componentInfo) +{ + // Create shared allocation + char* data = new char[sizeof(EntityID) + componentInfo.Stride]; + // Copy entity ID to start of data buffer + memcpy(data, &entityID, sizeof(EntityID)); + // Read and copy fields + for (auto& field : componentInfo.FieldsInOrder) { + ComponentInfo::Field_t fieldInfo = componentInfo.Fields.at(field); + if (fieldInfo.Type == "string") { + new (data + sizeof(EntityID) + fieldInfo.Offset) std::string(packet.ReadString()); + } else { + memcpy(data + sizeof(EntityID) + fieldInfo.Offset, packet.ReadData(fieldInfo.Stride), fieldInfo.Stride); + } + } + + return SharedComponentWrapper(componentInfo, boost::shared_array(data)); +} + +void Client::ignoreFields(Packet& packet, const ComponentInfo& componentInfo) +{ + for (auto field : componentInfo.FieldsInOrder) { + ComponentInfo::Field_t fieldInfo = componentInfo.Fields.at(field); + if (fieldInfo.Type == "string") { + packet.ReadString(); + } else { + packet.ReadData(fieldInfo.Stride); } } } @@ -214,26 +237,32 @@ void Client::parseSnapshot(Packet& packet) int ammountOfComponents = packet.ReadPrimitive(); for (int i = 0; i < ammountOfComponents; i++) { std::string componentType = packet.ReadString(); - ComponentInfo componentInfo = m_World->GetComponents(componentType)->ComponentInfo(); + const ComponentInfo& componentInfo = m_World->GetComponents(componentType)->ComponentInfo(); if (serverClientMapsHasEntity(serverEntityID)) { EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID); + EntityWrapper localEntity(m_World, localEntityID); + // Update entity if (m_World->HasComponent(localEntityID, componentType)) { - // Update component - if (componentType == "Transform") { - // Interpolate only transform components - InterpolateFields(packet, componentInfo, localEntityID, componentType); - } else if (componentType == "Physics" && m_World->HasComponent(localEntityID, "Player")) { - // HACK: Ignore velocity of physics - packet.ReadData(componentInfo.Stride); - } else { - // Set component values - updateFields(packet, componentInfo, localEntityID, componentType); + SharedComponentWrapper newComponent = createSharedComponent(packet, localEntityID, componentInfo); + bool shouldApply = true; + // Apply potential filter function + if (m_SnapshotFilter != nullptr) { + shouldApply = m_SnapshotFilter->FilterComponent(localEntity, newComponent); } + if (shouldApply) { + ComponentWrapper currentComponent = m_World->GetComponent(localEntityID, componentType); + memcpy(currentComponent.Data, newComponent.Data, componentInfo.Stride); + } + //if (localEntity != m_LocalPlayer && !localEntity.IsChildOf(m_LocalPlayer)) { + // updateFields(packet, componentInfo, localEntityID); + //} else { + // ignoreFields(packet, componentInfo); + //} } else { // Has entity but no component m_World->AttachComponent(localEntityID, componentType); - updateFields(packet, componentInfo, localEntityID, componentType); + updateFields(packet, componentInfo, localEntityID); } } else { // Create Entity and component @@ -246,7 +275,7 @@ void Client::parseSnapshot(Packet& packet) m_World->SetName(newLocalEntityID, serverEntityName); insertIntoServerClientMaps(serverEntityID, newLocalEntityID); m_World->AttachComponent(newLocalEntityID, componentType); - updateFields(packet, componentInfo, newLocalEntityID, componentType); + updateFields(packet, componentInfo, newLocalEntityID); } } // Parent logic diff --git a/src/Engine/Network/Network.cpp b/src/Engine/Network/Network.cpp index f43e5d83..534df1cd 100644 --- a/src/Engine/Network/Network.cpp +++ b/src/Engine/Network/Network.cpp @@ -1,5 +1,14 @@ #include "Network/Network.h" +Network::Network(World* world, EventBroker* eventBroker) + : m_World(world) + , m_EventBroker(eventBroker) +{ + ConfigFile* config = ResourceManager::Load("Config.ini"); + m_MaxConnections = config->Get("Networking.MaxConnections", 8); + m_TimeoutMs = config->Get("Networking.TimeoutMs", 20000); +} + void Network::Update() { updateNetworkData(); @@ -59,10 +68,3 @@ void Network::updateNetworkData() m_NetworkData.DataReceivedThisInterval = 0; } } - -void Network::initialize() -{ - ConfigFile* config = ResourceManager::Load("Config.ini"); - m_MaxConnections = config->Get("Networking.MaxConnections", 8); - m_TimeoutMs = config->Get("Networking.TimeoutMs", 20000); -} diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 962081cc..9502c01d 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -1,29 +1,30 @@ #include "Network/Server.h" -Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 27666)) +Server::Server(World* world, EventBroker* eventBroker, int port) + : Network(world, eventBroker) { - Network::initialize(); ConfigFile* config = ResourceManager::Load("Config.ini"); snapshotInterval = 1000 * config->Get("Networking.SnapshotInterval", 0.05f); pingIntervalMs = config->Get("Networking.PingIntervalMs", 1000); -} - -Server::~Server() -{ - -} - -void Server::Start(World* world, EventBroker* eventBroker) -{ - m_World = world; - m_EventBroker = eventBroker; // Subscribe to events EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Server::OnPlayerSpawned); EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &Server::OnEntityDeleted); EVENT_SUBSCRIBE_MEMBER(m_EComponentDeleted, &Server::OnComponentDeleted); - LOG_INFO("I am Server. BIP BOP\n"); + + // Bind + if (port == 0) { + port = config->Get("Networking.Port", 27666); + } + m_Port = port; + m_Socket = std::make_unique(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port)); + LOG_INFO("Server initialized and bound to port %i", port); +} + +Server::~Server() +{ + } void Server::Update() @@ -38,7 +39,7 @@ void Server::Update() void Server::readFromClients() { - while (m_Socket.available()) { + while (m_Socket->available()) { try { bytesRead = receive(readBuffer); Packet packet(readBuffer, bytesRead); @@ -105,7 +106,7 @@ void Server::parseMessageType(Packet& packet) size_t Server::receive(char * data) { - size_t length = m_Socket.receive_from( + size_t length = m_Socket->receive_from( boost::asio::buffer((void*)data , INPUTSIZE) , m_ReceiverEndpoint, 0); @@ -121,7 +122,7 @@ size_t Server::receive(char * data) void Server::send(PlayerID player, Packet& packet) { try { - size_t bytesSent = m_Socket.send_to( + size_t bytesSent = m_Socket->send_to( boost::asio::buffer(packet.Data(), packet.Size()), m_ConnectedPlayers[player].Endpoint, 0); @@ -139,7 +140,7 @@ void Server::send(PlayerID player, Packet& packet) void Server::send(Packet & packet) { - m_Socket.send_to( + m_Socket->send_to( boost::asio::buffer( packet.Data(), packet.Size()), @@ -240,7 +241,7 @@ void Server::checkForTimeOuts() static_cast(CLOCKS_PER_SEC); if (startPing > stopPing + m_TimeoutMs) { LOG_INFO("User %i timed out!", i); - disconnect(i); + //disconnect(i); } } } diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index a63e02a0..3fb11a2d 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -51,7 +51,7 @@ void Renderer::InitializeWindow() ss << " DEBUG"; #endif LOG_INFO(ss.str().c_str()); - glfwSetWindowTitle(m_Window, ss.str().c_str()); + SetWindowTitle(ss.str()); // Initialize GLEW if (glewInit() != GLEW_OK) { diff --git a/src/Game/CMakeLists.txt b/src/Game/CMakeLists.txt index 157af23c..db923364 100644 --- a/src/Game/CMakeLists.txt +++ b/src/Game/CMakeLists.txt @@ -1,6 +1,6 @@ project(TacticalZ-Game) -find_package(Boost REQUIRED COMPONENTS system filesystem thread chrono) +find_package(Boost REQUIRED COMPONENTS system filesystem thread chrono program_options) set(INCLUDE_PATH ${CMAKE_SOURCE_DIR}/include/Game) include_directories( @@ -22,13 +22,17 @@ file(GLOB SOURCE_FILES_Events ) source_group(Events FILES ${SOURCE_FILES_Events}) +file(GLOB SOURCE_FILES_Network + "${INCLUDE_PATH}/Network/*.h" + "Network/*.cpp" +) +source_group(Network FILES ${SOURCE_FILES_Network}) set(SOURCE_FILES ${SOURCE_FILES} "Game.cpp" ${SOURCE_FILES_Systems} ${SOURCE_FILES_Events} - - + ${SOURCE_FILES_Network} ) set(LIBRARIES diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 04180fb3..982ce647 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -13,10 +13,13 @@ #include "Game/Systems/WeaponSystem.h" #include "Game/Systems/PlayerHUDSystem.h" #include "Game/Systems/LifetimeSystem.h" -#include "../Engine/Rendering/AnimationSystem.h" +#include "Rendering/AnimationSystem.h" +#include "Network/MultiplayerSnapshotFilter.h" Game::Game(int argc, char* argv[]) { + parseArgs(argc, argv); + ResourceManager::RegisterType("ConfigFile"); ResourceManager::RegisterType("Sound"); ResourceManager::RegisterType("Model"); @@ -73,15 +76,14 @@ Game::Game(int argc, char* argv[]) // Initialize network if (m_Config->Get("Networking.StartNetwork", false)) { - bool isServer = m_Config->Get("Networking.IsServer", false); - if (isServer) { - m_Network = new Server(); - m_IsServer = true; - } else { - m_Network = new Client(m_Config); - m_IsClient = true; + if (m_IsServer) { + m_NetworkServer = new Server(m_World, m_EventBroker, m_NetworkPort); + m_Renderer->SetWindowTitle(m_Renderer->WindowTitle() + " SERVER"); + } else if (m_IsClient) { + m_NetworkClient = new Client(m_World, m_EventBroker, std::make_unique(m_EventBroker)); + m_NetworkClient->Connect(m_NetworkAddress, m_NetworkPort); + m_Renderer->SetWindowTitle(m_Renderer->WindowTitle() + " CLIENT"); } - m_Network->Start(m_World, m_EventBroker); } // Create Octrees @@ -132,8 +134,11 @@ Game::~Game() delete m_OctreeFrustrumCulling; delete m_OctreeCollision; delete m_OctreeTrigger; - if (m_Network != nullptr) { - delete m_Network; + if (m_NetworkClient != nullptr) { + delete m_NetworkClient; + } + if (m_NetworkServer != nullptr) { + delete m_NetworkServer; } delete m_World; delete m_FrameStack; @@ -163,8 +168,12 @@ void Game::Tick() m_EventBroker->Swap(); // Update network - if (m_Network != nullptr) { - m_Network->Update(); + m_EventBroker->Process(); + if (m_NetworkClient != nullptr) { + m_NetworkClient->Update(); + } + if (m_NetworkServer != nullptr) { + m_NetworkServer->Update(); } // Iterate through systems and update world! @@ -176,4 +185,37 @@ void Game::Tick() m_RenderFrame->Clear(); m_EventBroker->Swap(); m_EventBroker->Clear(); -} \ No newline at end of file +} + +int Game::parseArgs(int argc, char* argv[]) +{ + namespace po = boost::program_options; + + po::options_description desc("Options"); + desc.add_options() + ("help", "Help") + ("server,s", po::bool_switch(&m_IsServer), "Launch game in server mode") + ("connect", po::value(&m_NetworkAddress)->default_value(""), "Connect to this address in client mode") + ("port,p", po::value(&m_NetworkPort), "Port to listen on or connect to"); + ; + + po::variables_map vm; + try { + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + } catch (std::exception& e) { + LOG_ERROR(e.what()); + return 1; + } + + if (vm.count("help")) { + std::cout << desc << std::endl; + exit(1); + } + + if (vm.count("connect")) { + m_IsClient = true; + } + + return 0; +} diff --git a/src/Game/Network/MultiplayerSnapshotFilter.cpp b/src/Game/Network/MultiplayerSnapshotFilter.cpp new file mode 100644 index 00000000..426b24d2 --- /dev/null +++ b/src/Game/Network/MultiplayerSnapshotFilter.cpp @@ -0,0 +1,27 @@ +#include "Network/MultiplayerSnapshotFilter.h" + +MultiplayerSnapshotFilter::MultiplayerSnapshotFilter(EventBroker* eventBroker) + : m_EventBroker(eventBroker) +{ + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &MultiplayerSnapshotFilter::OnPlayerSpawned); +} + +bool MultiplayerSnapshotFilter::FilterComponent(EntityWrapper entity, SharedComponentWrapper& component) +{ + if (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) { + return false; + } + + if (component.Info.Name == "Transform") { + m_EventBroker->Publish(Events::Interpolate(entity, component)); + return false; + } + + return true; +} + +bool MultiplayerSnapshotFilter::OnPlayerSpawned(Events::PlayerSpawned ePlayerSpawned) +{ + m_LocalPlayer = ePlayerSpawned.Player; + return true; +} \ No newline at end of file diff --git a/src/Game/Systems/ExplosionEffectSystem.cpp b/src/Game/Systems/ExplosionEffectSystem.cpp new file mode 100644 index 00000000..2704d2da --- /dev/null +++ b/src/Game/Systems/ExplosionEffectSystem.cpp @@ -0,0 +1,14 @@ +#include "Systems/ExplosionEffectSystem.h" + +void ExplosionEffectSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) +{ + if ((double)component["TimeSinceDeath"] > (double)component["ExplosionDuration"]) { + (double)component["TimeSinceDeath"] = 0.f; + } + (double&)component["TimeSinceDeath"] += dt; + + //if ((bool)Component["Gravity"] == true) { + // (bool)Component["ExponentialAccelaration"] = false; + //} +} + diff --git a/src/Game/Systems/InterpolationSystem.cpp b/src/Game/Systems/InterpolationSystem.cpp index e958a4a9..6c57c2b6 100644 --- a/src/Game/Systems/InterpolationSystem.cpp +++ b/src/Game/Systems/InterpolationSystem.cpp @@ -17,6 +17,7 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe return; } + //return; if (m_NextTransform.find(transform.EntityID) != m_NextTransform.end()) { // Exists in map m_NextTransform[transform.EntityID].interpolationTime += static_cast(dt); Transform sTransform = m_NextTransform[transform.EntityID]; @@ -32,21 +33,14 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe } } if (transform.Info.Name == "Transform") { - bool isLocalPlayer = entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer); // Position glm::vec3 nextPosition = sTransform.Position; glm::vec3 currentPosition = static_cast(transform["Position"]); - // HACK: Don't force position for players - if (!isLocalPlayer) { - (glm::vec3&)transform["Position"] += vectorInterpolation(currentPosition, nextPosition, sTransform.interpolationTime); - } + (glm::vec3&)transform["Position"] += vectorInterpolation(currentPosition, nextPosition, sTransform.interpolationTime); // Orientation - // Don't force orientation for players - if (!isLocalPlayer) { - glm::quat nextOrientation = sTransform.Orientation; - glm::quat currentOrientation = glm::quat(static_cast(transform["Orientation"])); - (glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp(currentOrientation, nextOrientation, sTransform.interpolationTime / m_SnapshotInterval)); - } + glm::quat nextOrientation = sTransform.Orientation; + glm::quat currentOrientation = glm::quat(static_cast(transform["Orientation"])); + (glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp(currentOrientation, nextOrientation, glm::max(sTransform.interpolationTime / m_SnapshotInterval, 1.f))); // Scale glm::vec3 nextScale = sTransform.Scale; glm::vec3 currentScale = static_cast(transform["Scale"]); @@ -61,24 +55,22 @@ bool InterpolationSystem::OnPlayerSpawned(Events::PlayerSpawned& e) return true; } -bool InterpolationSystem::OnInterpolate(const Events::Interpolate & e) +bool InterpolationSystem::OnInterpolate(Events::Interpolate& e) { - Transform transform; - int offset = 0; - // Read the data - memcpy(&transform.Position, e.DataArray.get() + offset, sizeof(glm::vec3)); - offset += sizeof(glm::vec3); - glm::vec3 tempOrientation; - memcpy(&tempOrientation, e.DataArray.get() + offset, sizeof(glm::vec3)); - transform.Orientation = glm::quat(tempOrientation); - offset += sizeof(glm::vec3); - memcpy(&transform.Scale, e.DataArray.get() + offset, sizeof(glm::vec3)); - transform.interpolationTime = 0.0f; + // TODO: Make this work for arbitrary component types + if (e.Component.Info.Name == "Transform") { + Transform transform; + transform.Position = e.Component["Position"]; + transform.Orientation = glm::quat((glm::vec3)e.Component["Orientation"]); + transform.Scale = e.Component["Scale"]; + transform.interpolationTime = 0.0f; - if (m_NextTransform.find(e.Entity) != m_NextTransform.end()) { // Did exist - m_LastReceivedTransform[e.Entity] = transform; - } else { // Did not - m_NextTransform[e.Entity] = transform; + if (m_NextTransform.find(e.Entity.ID) != m_NextTransform.end()) { // Did exist + m_LastReceivedTransform[e.Entity.ID] = transform; + } else { // Did not + m_NextTransform[e.Entity.ID] = transform; + } } - return false; + + return true; } From c69a80f5ba35730654a7f9a6b5f3198db3d9c9b2 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Tue, 9 Feb 2016 16:06:39 +0100 Subject: [PATCH 06/31] Added System::LocalPlayer that is always set to the entity which is the local player, available to all systems. --- include/Engine/Core/System.h | 18 +++++++++++++++++- include/Engine/Core/SystemPipeline.h | 3 +++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/include/Engine/Core/System.h b/include/Engine/Core/System.h index d4b9808b..e21d8c7e 100644 --- a/include/Engine/Core/System.h +++ b/include/Engine/Core/System.h @@ -5,6 +5,7 @@ #include "World.h" #include "EntityWrapper.h" #include "ComponentWrapper.h" +#include "EPlayerSpawned.h" struct SystemParams { @@ -31,13 +32,28 @@ protected: , m_EventBroker(params.EventBroker) , IsClient(params.IsClient) , IsServer(params.IsServer) - { } + { + if (IsClient) { + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &System::OnPlayerSpawned); + } + } virtual ~System() = default; World* m_World; EventBroker* m_EventBroker; bool IsClient = false; bool IsServer = false; + EntityWrapper LocalPlayer = EntityWrapper::Invalid; + +private: + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(Events::PlayerSpawned& e) + { + if (e.PlayerID == -1) { + LocalPlayer = e.Player; + } + return true; + } }; class PureSystem : public virtual System diff --git a/include/Engine/Core/SystemPipeline.h b/include/Engine/Core/SystemPipeline.h index 88ec4fa7..5f7aee0b 100644 --- a/include/Engine/Core/SystemPipeline.h +++ b/include/Engine/Core/SystemPipeline.h @@ -61,6 +61,9 @@ public: dt = 0.0; } + // Process utility events for the System base class + m_EventBroker->Process(); + for (UnorderedSystems& group : m_OrderedSystemGroups) { // Process events for (auto& pair : group.Systems) { From e69864680dded57343d2e54a9e07f4c3096f5ef4 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Tue, 9 Feb 2016 16:08:06 +0100 Subject: [PATCH 07/31] PlayerMovementSystem now only updates the velocity of the local player, as it should --- include/Game/Systems/PlayerMovementSystem.h | 5 +++-- src/Game/Systems/PlayerMovementSystem.cpp | 19 +++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/include/Game/Systems/PlayerMovementSystem.h b/include/Game/Systems/PlayerMovementSystem.h index 7daf9c03..97a37597 100644 --- a/include/Game/Systems/PlayerMovementSystem.h +++ b/include/Game/Systems/PlayerMovementSystem.h @@ -5,14 +5,13 @@ #include "Input/FirstPersonInputController.h" #include -class PlayerMovementSystem : public ImpureSystem, PureSystem +class PlayerMovementSystem : public ImpureSystem { public: PlayerMovementSystem(SystemParams params); ~PlayerMovementSystem(); virtual void Update(double dt) override; - virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt); private: // State @@ -21,4 +20,6 @@ private: EventRelay m_EPlayerSpawned; bool OnPlayerSpawned(Events::PlayerSpawned& e); + void updateMovementControllers(double dt); + void updateVelocity(double dt); }; \ No newline at end of file diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 04ce2400..ccc2d3ce 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -2,7 +2,6 @@ PlayerMovementSystem::PlayerMovementSystem(SystemParams params) : System(params) - , PureSystem("Player") { EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &PlayerMovementSystem::OnPlayerSpawned); } @@ -15,6 +14,12 @@ PlayerMovementSystem::~PlayerMovementSystem() } void PlayerMovementSystem::Update(double dt) +{ + updateMovementControllers(dt); + updateVelocity(dt); +} + +void PlayerMovementSystem::updateMovementControllers(double dt) { for (auto& kv : m_PlayerInputControllers) { EntityWrapper player = kv.first; @@ -135,14 +140,16 @@ void PlayerMovementSystem::Update(double dt) } } -void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) + +void PlayerMovementSystem::updateVelocity(double dt) { - ComponentWrapper& cTransform = entity["Transform"]; - if (!entity.HasComponent("Physics")) { + // Only apply velocity to local player + if (!LocalPlayer.Valid()) { return; } - ComponentWrapper& cPhysics = entity["Physics"]; + ComponentWrapper& cTransform = LocalPlayer["Transform"]; + ComponentWrapper& cPhysics = LocalPlayer["Physics"]; glm::vec3& velocity = cPhysics["Velocity"]; // Ground friction @@ -159,6 +166,7 @@ void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp velocity.z *= multiplier; } + // Gravity if (cPhysics["Gravity"]) { velocity.y -= 9.82f * (float)dt; } @@ -171,6 +179,5 @@ bool PlayerMovementSystem::OnPlayerSpawned(Events::PlayerSpawned& e) { // When a player spawns, create an input controller for them m_PlayerInputControllers[e.Player] = new FirstPersonInputController(m_EventBroker, e.PlayerID); - return true; } From d5647ce89ca445a09f608ff81048e5ade1346d9e Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Tue, 9 Feb 2016 16:08:28 +0100 Subject: [PATCH 08/31] Working 1-snapshot interpolation --- include/Game/Systems/InterpolationSystem.h | 39 +++--- src/Engine/Network/Server.cpp | 2 +- src/Game/Game.cpp | 3 +- .../Network/MultiplayerSnapshotFilter.cpp | 6 +- src/Game/Systems/InterpolationSystem.cpp | 122 +++++++++++------- 5 files changed, 103 insertions(+), 69 deletions(-) diff --git a/include/Game/Systems/InterpolationSystem.h b/include/Game/Systems/InterpolationSystem.h index 5077ad92..758609c8 100644 --- a/include/Game/Systems/InterpolationSystem.h +++ b/include/Game/Systems/InterpolationSystem.h @@ -16,26 +16,39 @@ #include "Network/EInterpolate.h" -class InterpolationSystem : public PureSystem +class InterpolationSystem : public ImpureSystem { public: InterpolationSystem(SystemParams params); ~InterpolationSystem() { } - virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt) override; + virtual void Update(double dt) override; private: - struct Transform + template + struct Interpolation { - glm::vec3 Position; - glm::vec3 Scale; - glm::quat Orientation; - float interpolationTime; + Interpolation(const ComponentWrapper& Component, const std::string& Field, const T& Start, const T& Goal) + : Component(Component) + , Field(Field) + , Start(Start) + , Goal(Goal) + { } + + ComponentWrapper Component; + std::string Field; + T Start; + T Goal; + double Alpha = 0.0; }; - std::unordered_map m_NextTransform; - std::unordered_map m_LastReceivedTransform; - EntityWrapper m_LocalPlayer = EntityWrapper::Invalid; + float m_SnapshotInterval; + std::unordered_map> m_InterpolatePosition; + std::unordered_map> m_InterpolateOrientation; + std::unordered_map> m_InterpolateVelocity; + + EventRelay m_EInterpolate; + bool InterpolationSystem::OnInterpolate(Events::Interpolate& e); template T vectorInterpolation(T prev, T next, double currentTime) @@ -44,12 +57,6 @@ private: T vector = difference * (static_cast(currentTime) / m_SnapshotInterval); return vector; } - float m_SnapshotInterval; - - EventRelay m_EInterpolate; - bool InterpolationSystem::OnInterpolate(Events::Interpolate& e); - EventRelay m_EPlayerSpawned; - bool OnPlayerSpawned(Events::PlayerSpawned& e); }; #endif diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 9502c01d..b0003539 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -240,7 +240,7 @@ void Server::checkForTimeOuts() double stopPing = 1000 * m_ConnectedPlayers[i].StopTime / static_cast(CLOCKS_PER_SEC); if (startPing > stopPing + m_TimeoutMs) { - LOG_INFO("User %i timed out!", i); + //LOG_INFO("User %i timed out!", i); //disconnect(i); } } diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 982ce647..38468e47 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -95,11 +95,12 @@ Game::Game(int argc, char* argv[]) // All systems with orderlevel 0 will be updated first. unsigned int updateOrderLevel = 0; + m_SystemPipeline->AddSystem(updateOrderLevel); + ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); - m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer); diff --git a/src/Game/Network/MultiplayerSnapshotFilter.cpp b/src/Game/Network/MultiplayerSnapshotFilter.cpp index 426b24d2..709ce6b1 100644 --- a/src/Game/Network/MultiplayerSnapshotFilter.cpp +++ b/src/Game/Network/MultiplayerSnapshotFilter.cpp @@ -12,7 +12,11 @@ bool MultiplayerSnapshotFilter::FilterComponent(EntityWrapper entity, SharedComp return false; } - if (component.Info.Name == "Transform") { + if (component.Info.Name == "Physics") { + return false; + } + + if (component.Info.Name == "Transform" || component.Info.Name == "Physics") { m_EventBroker->Publish(Events::Interpolate(entity, component)); return false; } diff --git a/src/Game/Systems/InterpolationSystem.cpp b/src/Game/Systems/InterpolationSystem.cpp index 6c57c2b6..430c01c1 100644 --- a/src/Game/Systems/InterpolationSystem.cpp +++ b/src/Game/Systems/InterpolationSystem.cpp @@ -2,74 +2,96 @@ InterpolationSystem::InterpolationSystem(SystemParams params) : System(params) - , PureSystem("Transform") { ConfigFile* config = ResourceManager::Load("Config.ini"); m_SnapshotInterval = config->Get("Networking.SnapshotInterval", 0.05f); EVENT_SUBSCRIBE_MEMBER(m_EInterpolate, &InterpolationSystem::OnInterpolate); - EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &InterpolationSystem::OnPlayerSpawned); } -void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt) +void InterpolationSystem::Update(double dt) { - // Don't interpolate entities that might already have been removed - if (!entity.Valid()) { - return; + // Position + for (auto& kv : m_InterpolatePosition) { + EntityWrapper entity = kv.first; + if (!entity.Valid()) { + continue; + } + auto& iPosition = kv.second; + glm::vec3& position = iPosition.Component[iPosition.Field]; + + iPosition.Alpha += dt; + float alpha = glm::min(iPosition.Alpha / m_SnapshotInterval, 1.0); + position = iPosition.Start + ((iPosition.Goal - iPosition.Start) * alpha); } - //return; - if (m_NextTransform.find(transform.EntityID) != m_NextTransform.end()) { // Exists in map - m_NextTransform[transform.EntityID].interpolationTime += static_cast(dt); - Transform sTransform = m_NextTransform[transform.EntityID]; - float time = sTransform.interpolationTime; - if (time > m_SnapshotInterval) { - if (m_LastReceivedTransform.find(transform.EntityID) != m_LastReceivedTransform.end()) { - m_NextTransform[transform.EntityID] = m_LastReceivedTransform[transform.EntityID]; - m_NextTransform[transform.EntityID].interpolationTime = time - m_SnapshotInterval; - sTransform = m_NextTransform[transform.EntityID]; - m_LastReceivedTransform.erase(transform.EntityID); - } else { - m_NextTransform.erase(transform.EntityID); - } + // Orientation + for (auto& kv : m_InterpolateOrientation) { + EntityWrapper entity = kv.first; + if (!entity.Valid()) { + continue; } - if (transform.Info.Name == "Transform") { - // Position - glm::vec3 nextPosition = sTransform.Position; - glm::vec3 currentPosition = static_cast(transform["Position"]); - (glm::vec3&)transform["Position"] += vectorInterpolation(currentPosition, nextPosition, sTransform.interpolationTime); - // Orientation - glm::quat nextOrientation = sTransform.Orientation; - glm::quat currentOrientation = glm::quat(static_cast(transform["Orientation"])); - (glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp(currentOrientation, nextOrientation, glm::max(sTransform.interpolationTime / m_SnapshotInterval, 1.f))); - // Scale - glm::vec3 nextScale = sTransform.Scale; - glm::vec3 currentScale = static_cast(transform["Scale"]); - (glm::vec3&)transform["Scale"] += vectorInterpolation(currentScale, nextScale, sTransform.interpolationTime); - } - } -} + auto& iOrientation = kv.second; + glm::vec3& orientation = iOrientation.Component[iOrientation.Field]; -bool InterpolationSystem::OnPlayerSpawned(Events::PlayerSpawned& e) -{ - m_LocalPlayer = e.Player; - return true; + iOrientation.Alpha += dt / m_SnapshotInterval; + iOrientation.Alpha = glm::min(iOrientation.Alpha, 1.0); + orientation = glm::eulerAngles(glm::slerp(iOrientation.Start, iOrientation.Goal, (float)iOrientation.Alpha)); + } + + // Velocity + for (auto& kv : m_InterpolateVelocity) { + EntityWrapper entity = kv.first; + if (!entity.Valid()) { + continue; + } + auto& iVelocity = kv.second; + glm::vec3& position = iVelocity.Component[iVelocity.Field]; + + iVelocity.Alpha += dt; + float alpha = glm::min(iVelocity.Alpha / m_SnapshotInterval, 1.0); + position = iVelocity.Start + ((iVelocity.Goal - iVelocity.Start) * alpha); + } } bool InterpolationSystem::OnInterpolate(Events::Interpolate& e) { - // TODO: Make this work for arbitrary component types if (e.Component.Info.Name == "Transform") { - Transform transform; - transform.Position = e.Component["Position"]; - transform.Orientation = glm::quat((glm::vec3)e.Component["Orientation"]); - transform.Scale = e.Component["Scale"]; - transform.interpolationTime = 0.0f; + auto cTransform = e.Entity["Transform"]; - if (m_NextTransform.find(e.Entity.ID) != m_NextTransform.end()) { // Did exist - m_LastReceivedTransform[e.Entity.ID] = transform; - } else { // Did not - m_NextTransform[e.Entity.ID] = transform; + // Position + Interpolation iPosition( + cTransform, + "Position", + cTransform["Position"], + e.Component["Position"] + ); + m_InterpolatePosition.erase(e.Entity); + m_InterpolatePosition.insert(std::make_pair(e.Entity, iPosition)); + + // Orientation + Interpolation iOrientation( + cTransform, + "Orientation", + glm::quat((glm::vec3&)cTransform["Orientation"]), + glm::quat((glm::vec3&)e.Component["Orientation"]) + ); + m_InterpolateOrientation.erase(e.Entity); + m_InterpolateOrientation.insert(std::make_pair(e.Entity, iOrientation)); + } else if (e.Component.Info.Name == "Physics") { + auto cPhysics = e.Entity["Physics"]; + if (!e.Entity.HasComponent("Player")) { + return false; } + + // Velocity + Interpolation iVelocity( + cPhysics, + "Velocity", + cPhysics["Velocity"], + e.Component["Velocity"] + ); + m_InterpolateVelocity.erase(e.Entity); + m_InterpolateVelocity.insert(std::make_pair(e.Entity, iVelocity)); } return true; From d83190290fa6b7f1bbc5c7152544eaa783c10d25 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Tue, 9 Feb 2016 19:37:42 +0100 Subject: [PATCH 09/31] Server now broadcasts certain input commands to all other clients (for stuff like shooting) --- include/Engine/Network/Server.h | 2 ++ include/Game/Systems/WeaponSystem.h | 8 +------- src/Engine/Network/Client.cpp | 16 ++++++++++++++++ src/Engine/Network/Server.cpp | 18 ++++++++++++++++++ src/Game/Game.cpp | 5 +++++ src/Game/Systems/WeaponSystem.cpp | 21 ++++++--------------- 6 files changed, 48 insertions(+), 22 deletions(-) diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index e0ef9fcf..f16c6c16 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -48,6 +48,7 @@ private: float snapshotInterval; int checkTimeOutInterval = 100; int m_NextPlayerID = 0; + std::vector m_InputCommandsToBroadcast; //Timers std::clock_t m_StartPingTime; @@ -64,6 +65,7 @@ private: void broadcast(Packet& packet); void sendSnapshot(); void addChildrenToPacket(Packet& packet, EntityID entityID); + void addInputCommandsToPacket(Packet& packet); void sendPing(); void checkForTimeOuts(); void disconnect(PlayerID playerID); diff --git a/include/Game/Systems/WeaponSystem.h b/include/Game/Systems/WeaponSystem.h index 59048ee0..d6525377 100644 --- a/include/Game/Systems/WeaponSystem.h +++ b/include/Game/Systems/WeaponSystem.h @@ -9,7 +9,6 @@ #include "Core/System.h" #include "Core/EPlayerDamage.h" #include "Core/EShoot.h" -#include "Core/EPlayerSpawned.h" #include "Input/EInputCommand.h" #include "Core/EntityFile.h" #include "Core/EntityFileParser.h" @@ -28,16 +27,11 @@ public: private: IRenderer* m_Renderer; - // State - EntityWrapper m_LocalPlayer = EntityWrapper::Invalid; - // Events - EventRelay m_EPlayerSpawned; - bool WeaponSystem::OnPlayerSpawned(const Events::PlayerSpawned& e); EventRelay m_EShoot; bool WeaponSystem::OnShoot(Events::Shoot& e); EventRelay m_EInputCommand; - bool WeaponSystem::OnInputCommand(const Events::InputCommand& e); + bool WeaponSystem::OnInputCommand(Events::InputCommand& e); }; #endif \ No newline at end of file diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index b3fa227a..7d2c8f92 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -230,6 +230,18 @@ void Client::ignoreFields(Packet& packet, const ComponentInfo& componentInfo) void Client::parseSnapshot(Packet& packet) { + // Read input commands + std::size_t numInputCommands = packet.ReadPrimitive(); + for (std::size_t i = 0; i < numInputCommands; ++i) { + Events::InputCommand e; + e.PlayerID = packet.ReadPrimitive(); + e.Player = EntityWrapper(m_World, m_ServerIDToClientID.at(packet.ReadPrimitive())); + e.Command = packet.ReadString(); + e.Value = packet.ReadPrimitive(); + m_EventBroker->Publish(e); + } + + // Read world state while (packet.DataReadSize() < packet.Size()) { EntityID serverEntityID = packet.ReadPrimitive(); EntityID serverParentID = packet.ReadPrimitive(); @@ -339,6 +351,10 @@ void Client::disconnect() bool Client::OnInputCommand(const Events::InputCommand & e) { + if (e.PlayerID != -1) { + return false; + } + if (e.Command == "ConnectToServer") { // Connect for now if (e.Value > 0) { connect(); diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index b0003539..7ad1cc76 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -165,10 +165,24 @@ void Server::broadcast(Packet& packet) void Server::sendSnapshot() { Packet packet(MessageType::Snapshot); + addInputCommandsToPacket(packet); addChildrenToPacket(packet, EntityID_Invalid); broadcast(packet); } +void Server::addInputCommandsToPacket(Packet& packet) +{ + // Number of input commands + packet.WritePrimitive(m_InputCommandsToBroadcast.size()); + for (auto& command : m_InputCommandsToBroadcast) { + packet.WritePrimitive(command.PlayerID); + packet.WritePrimitive(m_ConnectedPlayers.at(command.PlayerID).EntityID); + packet.WriteString(command.Command); + packet.WritePrimitive(command.Value); + } + m_InputCommandsToBroadcast.clear(); +} + void Server::addChildrenToPacket(Packet & packet, EntityID entityID) { auto itPair = m_World->GetChildren(entityID); @@ -273,6 +287,10 @@ void Server::parseOnInputCommand(Packet& packet) e.Player = EntityWrapper(m_World, m_ConnectedPlayers.at(player).EntityID); e.Value = packet.ReadPrimitive(); m_EventBroker->Publish(e); + + if (e.Command == "PrimaryFire") { + m_InputCommandsToBroadcast.push_back(e); + } //LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); } } diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 38468e47..ce782ece 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -218,5 +218,10 @@ int Game::parseArgs(int argc, char* argv[]) m_IsClient = true; } + // HACK: Right now, client and server are mutually exclusive + if (m_IsServer) { + m_IsClient = false; + } + return 0; } diff --git a/src/Game/Systems/WeaponSystem.cpp b/src/Game/Systems/WeaponSystem.cpp index 22cd173a..a650a6b7 100644 --- a/src/Game/Systems/WeaponSystem.cpp +++ b/src/Game/Systems/WeaponSystem.cpp @@ -5,7 +5,6 @@ WeaponSystem::WeaponSystem(SystemParams params, IRenderer* renderer) , ImpureSystem() , m_Renderer(renderer) { - EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &WeaponSystem::OnPlayerSpawned); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &WeaponSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EShoot, &WeaponSystem::OnShoot); } @@ -15,30 +14,22 @@ void WeaponSystem::Update(double dt) } -bool WeaponSystem::OnPlayerSpawned(const Events::PlayerSpawned& e) -{ - if (e.PlayerID == -1) { - m_LocalPlayer = e.Player; - } - return true; -} - -bool WeaponSystem::OnInputCommand(const Events::InputCommand& e) +bool WeaponSystem::OnInputCommand(Events::InputCommand& e) { // Only shoot client-side! - if (e.PlayerID != -1) { + if (!IsClient) { return false; } // Only shoot if the player is alive - if (!m_LocalPlayer.Valid()) { + if (!e.Player.Valid()) { return false; } if (e.Command == "PrimaryFire" && e.Value > 0) { Events::Shoot eShoot; if (e.PlayerID == -1) { - eShoot.Player = m_LocalPlayer; + eShoot.Player = LocalPlayer; } else { eShoot.Player = e.Player; } @@ -97,8 +88,8 @@ bool WeaponSystem::OnShoot(Events::Shoot& eShoot) //(glm::vec3&)ray["Transform"]["Orientation"] = Transform::AbsoluteOrientationEuler(weapon); } - // Only run further picking code client-side! - if (eShoot.Player != m_LocalPlayer) { + // Only run further picking code for the local player! + if (eShoot.Player != LocalPlayer) { return false; } From 5cea3bed3a578c5fd6d56bc14cfae1527d966ec0 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Tue, 9 Feb 2016 23:27:04 +0100 Subject: [PATCH 10/31] Work in progress weapon system --- include/Game/Systems/WeaponSystem.h | 93 +++++++++++++++++-- resources/DefaultInput.ini | 2 + resources/Schema/Components.xsd | 1 + resources/Schema/Components/AssaultWeapon.xml | 8 ++ resources/Schema/Components/AssaultWeapon.xsd | 27 ++++++ resources/Schema/Types/Entity.xsd | 1 + src/Game/Systems/WeaponSystem.cpp | 40 +++++++- 7 files changed, 164 insertions(+), 8 deletions(-) create mode 100755 resources/Schema/Components/AssaultWeapon.xml create mode 100755 resources/Schema/Components/AssaultWeapon.xsd diff --git a/include/Game/Systems/WeaponSystem.h b/include/Game/Systems/WeaponSystem.h index d6525377..fccb1b0b 100644 --- a/include/Game/Systems/WeaponSystem.h +++ b/include/Game/Systems/WeaponSystem.h @@ -9,29 +9,108 @@ #include "Core/System.h" #include "Core/EPlayerDamage.h" #include "Core/EShoot.h" +#include "Core/EPlayerSpawned.h" #include "Input/EInputCommand.h" #include "Core/EntityFile.h" #include "Core/EntityFileParser.h" -#include -#include - - -class WeaponSystem : public ImpureSystem +class WeaponSystem : public PureSystem, ImpureSystem { public: WeaponSystem(SystemParams params, IRenderer* renderer); virtual void Update(double dt) override; + virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) override; private: IRenderer* m_Renderer; + std::unordered_map> m_ActiveWeapons; + // Events + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(Events::PlayerSpawned& e); EventRelay m_EShoot; - bool WeaponSystem::OnShoot(Events::Shoot& e); + bool OnShoot(Events::Shoot& e); EventRelay m_EInputCommand; - bool WeaponSystem::OnInputCommand(Events::InputCommand& e); + bool OnInputCommand(Events::InputCommand& e); + + void selectWeapon(EntityWrapper player, ComponentInfo::EnumType slot); +}; + +class WeaponBehaviour +{ +public: + WeaponBehaviour(EntityWrapper weaponEntity) + : m_Entity(weaponEntity) + { } + + virtual void Fire() = 0; + virtual void CeaseFire() { } + virtual void Reload() { } + virtual void Update(double dt) { } + +protected: + EntityWrapper m_Entity; +}; + +class AssaultWeaponBehaviour : public WeaponBehaviour +{ +public: + AssaultWeaponBehaviour(EntityWrapper weaponEntity) + : WeaponBehaviour(weaponEntity) + { } + + virtual void Fire() override + { + m_TimeSinceLastFire = 0.0; + m_Firing = true; + fireRound(); + } + + virtual void CeaseFire() override + { + m_Firing = false; + } + + virtual void Update(double dt) override + { + if (!m_Firing) { + return; + } + + m_TimeSinceLastFire += dt; + + ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"]; + if (m_TimeSinceLastFire > (double)cAssaultWeapon["RPM"] / 60.0) { + fireRound(); + } + } + +private: + bool m_Firing = false; + double m_TimeSinceLastFire = 0.0; + ComponentWrapper m_Component; + + void fireRound() + { + ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"]; + + int& magAmmo = cAssaultWeapon["MagazineAmmo"]; + int ammo = cAssaultWeapon["Ammo"]; + + // Reload if our magazine is empty and we have ammo to fill it with + if (magAmmo <= 0 && ammo > 0) { + CeaseFire(); + Reload(); + return; + } + + // Fire + magAmmo -= 1; + + m_TimeSinceLastFire = 0.0; + } }; #endif \ No newline at end of file diff --git a/resources/DefaultInput.ini b/resources/DefaultInput.ini index a3f7d166..167226de 100644 --- a/resources/DefaultInput.ini +++ b/resources/DefaultInput.ini @@ -14,6 +14,8 @@ R=Reload Space=Jump LeftControl=Crouch LeftShift=Sprint +1=SelectWeapon,1 +2=SelectWeapon,2 F1=ToggleEditor C=ConnectToServer N=SwitchToServer diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index 265a3cc5..1d5b05f6 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -31,4 +31,5 @@ + \ No newline at end of file diff --git a/resources/Schema/Components/AssaultWeapon.xml b/resources/Schema/Components/AssaultWeapon.xml new file mode 100755 index 00000000..8dc2a50a --- /dev/null +++ b/resources/Schema/Components/AssaultWeapon.xml @@ -0,0 +1,8 @@ + + + 32 + 32 + 360 + 360 + 40 + \ No newline at end of file diff --git a/resources/Schema/Components/AssaultWeapon.xsd b/resources/Schema/Components/AssaultWeapon.xsd new file mode 100755 index 00000000..167fee18 --- /dev/null +++ b/resources/Schema/Components/AssaultWeapon.xsd @@ -0,0 +1,27 @@ + + + + + + + + + + Ammo currently loaded into the magazine + + + Max number of rounds in a magazine + + + Current ammo carried + + + Maximum ammo able to be carried + + + Rate of fire in rounds per minute + + + + + diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index 028af9e6..3eed11f3 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -38,6 +38,7 @@ + diff --git a/src/Game/Systems/WeaponSystem.cpp b/src/Game/Systems/WeaponSystem.cpp index a650a6b7..fe0f066f 100644 --- a/src/Game/Systems/WeaponSystem.cpp +++ b/src/Game/Systems/WeaponSystem.cpp @@ -2,6 +2,7 @@ WeaponSystem::WeaponSystem(SystemParams params, IRenderer* renderer) : System(params) + , PureSystem("Player") , ImpureSystem() , m_Renderer(renderer) { @@ -14,8 +15,23 @@ void WeaponSystem::Update(double dt) } +void WeaponSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) +{ + +} + bool WeaponSystem::OnInputCommand(Events::InputCommand& e) { + // Make sure player is alive + if (!e.Player.Valid()) { + return false; + } + + // Weapon selection + if (e.Command == "SelectWeapon") { + selectWeapon(e.Player, static_cast(e.Value)); + } + // Only shoot client-side! if (!IsClient) { return false; @@ -39,7 +55,29 @@ bool WeaponSystem::OnInputCommand(Events::InputCommand& e) return true; } -bool WeaponSystem::OnShoot(Events::Shoot& eShoot) +void WeaponSystem::selectWeapon(EntityWrapper player, ComponentInfo::EnumType slot) +{ + // Primary + if (slot == 1) { + // TODO: if class... + m_ActiveWeapons[player] = std::make_shared(); + } + + // Secondary + if (slot == 2) { + //m_ActiveWeapons[player] = std::make_shared(); + } +} + +bool WeaponSystem::OnPlayerSpawned(Events::PlayerSpawned& e) +{ + // Select primary weapon on player spawn + // TODO: Select the active one specified by player component + selectWeapon(e.Player, 1); + return true; +} + +bool WeaponSystem::OnShoot(Events::Shoot& eShoot) { if (!eShoot.Player.Valid()) { return false; From b6b96c5f11f52b12954ac170b9496330668ced1e Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Wed, 10 Feb 2016 11:51:58 +0100 Subject: [PATCH 11/31] Added DoubleJumpHexagon entity. Spawned DoubleJumpHexagon as the player doublejumps. Fixed DoubleJumping bug where you couldnt doublejump on rocks (where velocity wasnt 0.0) --- include/Game/Systems/PlayerMovementSystem.h | 3 ++ resources/DefaultInput.ini | 3 ++ .../Schema/Entities/DoubleJumpHexagon.xml | 30 +++++++++++++++++++ src/Game/Systems/PlayerMovementSystem.cpp | 8 ++++- 4 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 resources/Schema/Entities/DoubleJumpHexagon.xml diff --git a/include/Game/Systems/PlayerMovementSystem.h b/include/Game/Systems/PlayerMovementSystem.h index 34862e90..a0194545 100644 --- a/include/Game/Systems/PlayerMovementSystem.h +++ b/include/Game/Systems/PlayerMovementSystem.h @@ -5,6 +5,9 @@ #include "Input/FirstPersonInputController.h" #include +#include "Core/EntityFile.h" +#include "Core/EntityFileParser.h" + class PlayerMovementSystem : public ImpureSystem, PureSystem { public: diff --git a/resources/DefaultInput.ini b/resources/DefaultInput.ini index 589dfb3f..eb5b7658 100644 --- a/resources/DefaultInput.ini +++ b/resources/DefaultInput.ini @@ -2,6 +2,9 @@ Sensitivity=0.5 InvertPitch=false +[KeyBoard] +DoubleTapToDash=true + [Bindings] MouseLeft=PrimaryFire MouseX=Yaw diff --git a/resources/Schema/Entities/DoubleJumpHexagon.xml b/resources/Schema/Entities/DoubleJumpHexagon.xml new file mode 100644 index 00000000..bbc41119 --- /dev/null +++ b/resources/Schema/Entities/DoubleJumpHexagon.xml @@ -0,0 +1,30 @@ + + + + + + Models/JumpEffectHexagon.mesh + + true + + + + + + + 1.5 + + + true + + + true + 3 + + true + + + + + + diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 52890c3a..6b26db1c 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -90,9 +90,15 @@ void PlayerMovementSystem::Update(double dt) //you cant jump and dash at the same time - since there is no friction in the air and we would thus dash much further in the air if (!controller->PlayerIsDashing() && controller->Jumping() && !controller->Crouching() && (isOnGround || !controller->DoubleJumping())) { (bool)cPhysics["IsOnGround"] = false; - if (velocity.y == 0.f) { + if (isOnGround) { controller->SetDoubleJumping(false); } else { + //put a hexagon at the players feet + auto hexagonEffect = ResourceManager::Load("Schema/Entities/DoubleJumpHexagon.xml"); + EntityFileParser parser(hexagonEffect); + EntityID hexagonEffectID = parser.MergeEntities(m_World); + EntityWrapper hexagonEW = EntityWrapper(m_World, hexagonEffectID); + hexagonEW["Transform"]["Position"] = (glm::vec3)player["Transform"]["Position"]; controller->SetDoubleJumping(true); } velocity.y = 4.f; From d931660c56cc994df1b0cac66eecb53db59c9a55 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Wed, 10 Feb 2016 01:16:38 +0100 Subject: [PATCH 12/31] WIP --- include/Engine/Core/EntityWrapper.h | 2 +- include/Engine/Core/EventBroker.h | 3 +- include/Engine/Core/Octree.h | 4 +- include/Engine/Core/System.h | 2 +- include/Game/Systems/WeaponSystem.h | 129 ++++++++++++++++-- resources/Schema/Components/AssaultWeapon.xml | 3 +- resources/Schema/Components/AssaultWeapon.xsd | 1 + resources/Schema/Entities/Player.xml | 7 +- src/Engine/Core/EntityWrapper.cpp | 3 +- src/Engine/Core/EventBroker.cpp | 14 +- src/Game/Game.cpp | 2 +- src/Game/Systems/PlayerSpawnSystem.cpp | 3 + src/Game/Systems/WeaponSystem.cpp | 108 ++++++--------- 13 files changed, 181 insertions(+), 100 deletions(-) diff --git a/include/Engine/Core/EntityWrapper.h b/include/Engine/Core/EntityWrapper.h index bf34b9be..0ffb190e 100644 --- a/include/Engine/Core/EntityWrapper.h +++ b/include/Engine/Core/EntityWrapper.h @@ -29,7 +29,7 @@ struct EntityWrapper EntityWrapper FirstChildByName(const std::string& name); EntityWrapper FirstParentWithComponent(const std::string& componentType); bool IsChildOf(EntityWrapper potentialParent); - bool Valid(); + bool Valid() const; ComponentWrapper operator[](const char* componentName); bool operator==(const EntityWrapper& e) const; diff --git a/include/Engine/Core/EventBroker.h b/include/Engine/Core/EventBroker.h index dc1babc0..20d3b60c 100644 --- a/include/Engine/Core/EventBroker.h +++ b/include/Engine/Core/EventBroker.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "../Common.h" #include "Event.h" @@ -107,7 +108,7 @@ private: typedef std::unordered_map ContextRelays_t; ContextRelays_t m_ContextRelays; std::vector m_RelaysToSubscribe; - std::vector> m_RelaysToUnsubscribe; + std::unordered_map> m_RelaysToUnsubscribe; typedef std::list>> EventQueue_t; std::shared_ptr m_EventQueueRead; diff --git a/include/Engine/Core/Octree.h b/include/Engine/Core/Octree.h index 8bac5503..8fce7744 100644 --- a/include/Engine/Core/Octree.h +++ b/include/Engine/Core/Octree.h @@ -5,9 +5,7 @@ #include "../Common.h" #include "AABB.h" - -//Fwd declarations. -class Ray; +#include "Ray.h" namespace OctSpace { diff --git a/include/Engine/Core/System.h b/include/Engine/Core/System.h index e21d8c7e..43438fd5 100644 --- a/include/Engine/Core/System.h +++ b/include/Engine/Core/System.h @@ -68,7 +68,7 @@ protected: const std::string m_ComponentType; - virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) = 0; + virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cPlayer, double dt) = 0; }; class ImpureSystem : public virtual System diff --git a/include/Game/Systems/WeaponSystem.h b/include/Game/Systems/WeaponSystem.h index fccb1b0b..489048b8 100644 --- a/include/Game/Systems/WeaponSystem.h +++ b/include/Game/Systems/WeaponSystem.h @@ -13,17 +13,23 @@ #include "Input/EInputCommand.h" #include "Core/EntityFile.h" #include "Core/EntityFileParser.h" +#include "Core/Octree.h" +#include "Collision/EntityAABB.h" + +class WeaponBehaviour; class WeaponSystem : public PureSystem, ImpureSystem { public: - WeaponSystem(SystemParams params, IRenderer* renderer); + WeaponSystem(SystemParams params, IRenderer* renderer, Octree* collisionOctree); virtual void Update(double dt) override; - virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) override; + virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cPlayer, double dt) override; private: + SystemParams m_SystemParams; IRenderer* m_Renderer; + Octree* m_CollisionOctree; std::unordered_map> m_ActiveWeapons; @@ -38,12 +44,18 @@ private: void selectWeapon(EntityWrapper player, ComponentInfo::EnumType slot); }; -class WeaponBehaviour +class WeaponBehaviour : protected System { public: - WeaponBehaviour(EntityWrapper weaponEntity) - : m_Entity(weaponEntity) + WeaponBehaviour(SystemParams systemParams, Octree* collisionOctree, EntityWrapper weaponEntity) + : System(systemParams) + , m_CollisionOctree(collisionOctree) + , m_Entity(weaponEntity) { } + virtual ~WeaponBehaviour() = default; + + WeaponBehaviour(const WeaponBehaviour&) = delete; + WeaponBehaviour& operator=(const WeaponBehaviour &) = delete; virtual void Fire() = 0; virtual void CeaseFire() { } @@ -51,15 +63,19 @@ public: virtual void Update(double dt) { } protected: + Octree* m_CollisionOctree; EntityWrapper m_Entity; }; class AssaultWeaponBehaviour : public WeaponBehaviour { public: - AssaultWeaponBehaviour(EntityWrapper weaponEntity) - : WeaponBehaviour(weaponEntity) - { } + AssaultWeaponBehaviour(SystemParams systemParams, Octree* collisionOctree, EntityWrapper weaponEntity) + : WeaponBehaviour(systemParams, collisionOctree, weaponEntity) + { + m_RayRed = ResourceManager::Load("Schema/Entities/RayRed.xml"); + m_RayBlue = ResourceManager::Load("Schema/Entities/RayBlue.xml"); + } virtual void Fire() override { @@ -73,6 +89,25 @@ public: m_Firing = false; } + virtual void Reload() override + { + ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"]; + + int& magAmmo = cAssaultWeapon["MagazineAmmo"]; + int magSize = cAssaultWeapon["MagazineSize"]; + int& ammo = cAssaultWeapon["Ammo"]; + + // Don't reload if we're already fully loaded + if (magAmmo == magSize) { + return; + } + + // Throw away rounds in magazine to incentivise ammo sharing + int toLoad = glm::min(magSize, ammo); + magAmmo = toLoad; + ammo -= toLoad; + } + virtual void Update(double dt) override { if (!m_Firing) { @@ -82,7 +117,7 @@ public: m_TimeSinceLastFire += dt; ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"]; - if (m_TimeSinceLastFire > (double)cAssaultWeapon["RPM"] / 60.0) { + if (m_TimeSinceLastFire >= 1.0 / ((double)cAssaultWeapon["RPM"] / 60.0)) { fireRound(); } } @@ -90,7 +125,8 @@ public: private: bool m_Firing = false; double m_TimeSinceLastFire = 0.0; - ComponentWrapper m_Component; + EntityFile* m_RayRed = nullptr; + EntityFile* m_RayBlue = nullptr; void fireRound() { @@ -99,18 +135,85 @@ private: int& magAmmo = cAssaultWeapon["MagazineAmmo"]; int ammo = cAssaultWeapon["Ammo"]; - // Reload if our magazine is empty and we have ammo to fill it with - if (magAmmo <= 0 && ammo > 0) { - CeaseFire(); + // Reload if our magazine is empty + if (magAmmo <= 0) { Reload(); return; } // Fire magAmmo -= 1; + spawnTracer(); m_TimeSinceLastFire = 0.0; } + + void spawnTracer() + { + ComponentWrapper cTeam = m_Entity["Team"]; + ComponentInfo::EnumType team = cTeam["Team"]; + + // Select the right color of effect + EntityFile* rayFile = nullptr; + if (team == cTeam["Team"].Enum("Red")) { + rayFile = m_RayRed; + } + if (team == cTeam["Team"].Enum("Blue")) { + rayFile = m_RayBlue; + } + if (rayFile == nullptr) { + return; + } + + // Create the entity + EntityFileParser parser(rayFile); + EntityID rayID = parser.MergeEntities(m_World); + EntityWrapper ray(m_World, rayID); + + // Figure out where to put it + EntityWrapper attachment; + if (m_Entity == LocalPlayer || true) { + // Spawn the effect from the weapon view model for the local player + attachment = m_Entity.FirstChildByName("WeaponMuzzle"); + } + // TODO: Spawn the effect from the weapon world model once it exists + + glm::mat4 transformation = Transform::AbsoluteTransformation(attachment); + glm::vec3 _scale; + glm::vec3 translation; + glm::quat _orientation; + glm::vec3 _skew; + glm::vec4 _perspective; + glm::decompose(transformation, _scale, _orientation, translation, _skew, _perspective); + + // Matrix to euler angles + glm::vec3 euler; + euler.y = glm::asin(-transformation[0][2]); + if (cos(euler.y) != 0) { + euler.x = atan2(transformation[1][2], transformation[2][2]); + euler.z = atan2(transformation[0][1], transformation[0][0]); + } else { + euler.x = atan2(-transformation[2][0], transformation[1][1]); + euler.z = 0; + } + + // TODO: Spread? + + (glm::vec3&)ray["Transform"]["Position"] = translation; + (glm::vec3&)ray["Transform"]["Orientation"] = euler; + glm::vec3& scale = ray["Transform"]["Scale"]; + scale.z = traceRayDistance(translation, glm::quat(euler) * glm::vec3(0.f, 0.f, -1.f)); + } + + float traceRayDistance(glm::vec3 origin, glm::vec3 direction) + { + OctSpace::Output result; + if (m_CollisionOctree->RayCollides(Ray(origin, direction), result)) { + return result.CollideDistance; + } else { + return 0.f; + } + } }; #endif \ No newline at end of file diff --git a/resources/Schema/Components/AssaultWeapon.xml b/resources/Schema/Components/AssaultWeapon.xml index 8dc2a50a..902795c1 100755 --- a/resources/Schema/Components/AssaultWeapon.xml +++ b/resources/Schema/Components/AssaultWeapon.xml @@ -4,5 +4,6 @@ 32 360 360 - 40 + 5 + 120 \ No newline at end of file diff --git a/resources/Schema/Components/AssaultWeapon.xsd b/resources/Schema/Components/AssaultWeapon.xsd index 167fee18..1b2704ea 100755 --- a/resources/Schema/Components/AssaultWeapon.xsd +++ b/resources/Schema/Components/AssaultWeapon.xsd @@ -18,6 +18,7 @@ Maximum ammo able to be carried + Rate of fire in rounds per minute diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index e9fa0be3..b13082e7 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -6,6 +6,9 @@ + + 600 + 2 @@ -118,7 +121,7 @@ - + @@ -145,7 +148,7 @@ Hold Pos - + 1 diff --git a/src/Engine/Core/EntityWrapper.cpp b/src/Engine/Core/EntityWrapper.cpp index 071329a3..be7b96a8 100644 --- a/src/Engine/Core/EntityWrapper.cpp +++ b/src/Engine/Core/EntityWrapper.cpp @@ -54,7 +54,7 @@ bool EntityWrapper::IsChildOf(EntityWrapper potentialParent) return false; } -bool EntityWrapper::Valid() +bool EntityWrapper::Valid() const { if (this->World == nullptr) { return false; @@ -65,7 +65,6 @@ bool EntityWrapper::Valid() } if (!this->World->ValidEntity(this->ID)) { - this->ID = EntityID_Invalid; return false; } diff --git a/src/Engine/Core/EventBroker.cpp b/src/Engine/Core/EventBroker.cpp index d847e1a2..ef4d138d 100644 --- a/src/Engine/Core/EventBroker.cpp +++ b/src/Engine/Core/EventBroker.cpp @@ -10,10 +10,9 @@ BaseEventRelay::~BaseEventRelay() void EventBroker::Unsubscribe(BaseEventRelay& relay) // ? { auto identifier = std::make_tuple(relay.m_EventID, relay.m_ContextTypeName, relay.m_EventTypeName); - relay.m_Broker = nullptr; if (m_IsProcessing) { - m_RelaysToUnsubscribe.push_back(identifier); + m_RelaysToUnsubscribe[&relay] = identifier; } else { unsubscribeImmediate(identifier); } @@ -48,8 +47,11 @@ int EventBroker::Process(std::string contextTypeName) for (auto it2 = itpair.first; it2 != itpair.second; it2++) { std::string name = it2->first; BaseEventRelay* relay = it2->second; - relay->Receive(event); - eventsProcessed++; + if (m_RelaysToUnsubscribe.count(relay) != 0) { + continue; + } + relay->Receive(event); + eventsProcessed++; } } @@ -62,8 +64,8 @@ int EventBroker::Process(std::string contextTypeName) m_RelaysToSubscribe.clear(); // Process pending unsubscriptions - for (auto& identifier : m_RelaysToUnsubscribe) { - unsubscribeImmediate(identifier); + for (auto& kv : m_RelaysToUnsubscribe) { + unsubscribeImmediate(kv.second); } m_RelaysToUnsubscribe.clear(); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index ce782ece..47170764 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -103,7 +103,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); - m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer); + m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer, m_OctreeCollision); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); // Populate Octree with collidables diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index fa713675..b7a3d91b 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -71,6 +71,9 @@ bool PlayerSpawnSystem::OnInputCommand(const Events::InputCommand& e) bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e) { // When a player is actually spawned (since the actual spawning is handled on the server) + if (!IsClient) { + return false; + } // Check if a player already exists if (m_PlayerEntities.count(e.PlayerID) != 0) { diff --git a/src/Game/Systems/WeaponSystem.cpp b/src/Game/Systems/WeaponSystem.cpp index fe0f066f..dfb84581 100644 --- a/src/Game/Systems/WeaponSystem.cpp +++ b/src/Game/Systems/WeaponSystem.cpp @@ -1,13 +1,15 @@ #include "Systems/WeaponSystem.h" -WeaponSystem::WeaponSystem(SystemParams params, IRenderer* renderer) +WeaponSystem::WeaponSystem(SystemParams params, IRenderer* renderer, Octree* collisionOctree) : System(params) , PureSystem("Player") - , ImpureSystem() + , m_SystemParams(params) , m_Renderer(renderer) + , m_CollisionOctree(collisionOctree) { EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &WeaponSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EShoot, &WeaponSystem::OnShoot); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &WeaponSystem::OnPlayerSpawned); } void WeaponSystem::Update(double dt) @@ -15,41 +17,48 @@ void WeaponSystem::Update(double dt) } -void WeaponSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) +void WeaponSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cPlayer, double dt) { - + // Update potential weapon behaviour for player + //auto it = m_ActiveWeapons.find(entity); + //if (it != m_ActiveWeapons.end()) { + // //if (it->first.Valid()) { + // it->second->Update(dt); + // //} else { + // // m_ActiveWeapons.erase(it); + // //} + //} } bool WeaponSystem::OnInputCommand(Events::InputCommand& e) { + EntityWrapper player = e.Player; + if (e.PlayerID == -1) { + player = LocalPlayer; + } + // Make sure player is alive - if (!e.Player.Valid()) { + if (!player.Valid()) { return false; } // Weapon selection if (e.Command == "SelectWeapon") { - selectWeapon(e.Player, static_cast(e.Value)); - } - - // Only shoot client-side! - if (!IsClient) { - return false; - } - - // Only shoot if the player is alive - if (!e.Player.Valid()) { - return false; - } - - if (e.Command == "PrimaryFire" && e.Value > 0) { - Events::Shoot eShoot; - if (e.PlayerID == -1) { - eShoot.Player = LocalPlayer; - } else { - eShoot.Player = e.Player; + if (e.Value != 0) { + selectWeapon(player, static_cast(e.Value)); + } + } + + // Fire + if (e.Command == "PrimaryFire") { + if (m_ActiveWeapons.find(player) != m_ActiveWeapons.end()) { + auto weapon = m_ActiveWeapons.at(player); + if (e.Value > 0) { + weapon->Fire(); + } else { + weapon->CeaseFire(); + } } - m_EventBroker->Publish(eShoot); } return true; @@ -60,7 +69,11 @@ void WeaponSystem::selectWeapon(EntityWrapper player, ComponentInfo::EnumType sl // Primary if (slot == 1) { // TODO: if class... - m_ActiveWeapons[player] = std::make_shared(); + if (m_ActiveWeapons.count(player) == 0) { + m_ActiveWeapons.insert(std::make_pair(player, std::make_shared(m_SystemParams, m_CollisionOctree, player))); + } else { + m_ActiveWeapons.erase(player); + } } // Secondary @@ -83,49 +96,6 @@ bool WeaponSystem::OnShoot(Events::Shoot& eShoot) return false; } - // TODO: Weapon firing effects here - - auto rayRed = ResourceManager::Load("Schema/Entities/RayRed.xml"); - auto rayBlue = ResourceManager::Load("Schema/Entities/RayBlue.xml"); - - EntityWrapper weapon = eShoot.Player.FirstChildByName("WeaponMuzzle"); - if (weapon.Valid()) { - EntityWrapper ray; - if ((ComponentInfo::EnumType)eShoot.Player["Team"]["Team"] == eShoot.Player["Team"]["Team"].Enum("Red")) { - EntityFileParser parser(rayRed); - EntityID rayID = parser.MergeEntities(m_World); - ray = EntityWrapper(m_World, rayID); - } else { - EntityFileParser parser(rayBlue); - EntityID rayID = parser.MergeEntities(m_World); - ray = EntityWrapper(m_World, rayID); - } - - glm::mat4 transformation = Transform::AbsoluteTransformation(weapon); - glm::vec3 scale; - glm::vec3 translation; - glm::quat orientation; - glm::vec3 skew; - glm::vec4 perspective; - glm::decompose(transformation, scale, orientation, translation, skew, perspective); - - // Matrix to euler angles - glm::vec3 euler; - euler.y = glm::asin(-transformation[0][2]); - if (cos(euler.y) != 0) { - euler.x = atan2(transformation[1][2], transformation[2][2]); - euler.z = atan2(transformation[0][1], transformation[0][0]); - } else { - euler.x = atan2(-transformation[2][0], transformation[1][1]); - euler.z = 0; - } - - //LOG_DEBUG("rotation: %f %f %f", euler.x, euler.y, euler.z); - (glm::vec3&)ray["Transform"]["Position"] = translation; - (glm::vec3&)ray["Transform"]["Orientation"] = euler; - //(glm::vec3&)ray["Transform"]["Orientation"] = Transform::AbsoluteOrientationEuler(weapon); - } - // Only run further picking code for the local player! if (eShoot.Player != LocalPlayer) { return false; From 53265bbc90c4c2e647be75ddbfe739e34eb9e5c2 Mon Sep 17 00:00:00 2001 From: Tleety Date: Wed, 10 Feb 2016 17:50:17 +0100 Subject: [PATCH 13/31] PNG is now a resource. You can now load textures threaded. PNG will now throw exceptions when errors happend SpriteComponent is now working without billboarding. --- include/Engine/GUI/TextureFrame.h | 5 +- include/Engine/Rendering/DrawFinalPass.h | 2 + include/Engine/Rendering/Model.h | 1 + include/Engine/Rendering/PNG.h | 3 +- include/Engine/Rendering/Renderer.h | 1 + include/Engine/Rendering/SpriteJob.h | 19 ++--- .../Engine/Rendering/Util/CommonFunctions.h | 11 +-- .../Schema/Entities/QualityAssurance.xml | 74 +++++++++++++++---- resources/Shaders/Sprite.vert.glsl | 3 +- src/Engine/Rendering/DrawBloomPass.cpp | 2 +- src/Engine/Rendering/DrawFinalPass.cpp | 17 +++-- src/Engine/Rendering/Model.cpp | 8 +- src/Engine/Rendering/PNG.cpp | 22 ++---- src/Engine/Rendering/Renderer.cpp | 17 +++-- src/Engine/Rendering/Texture.cpp | 29 ++++---- src/Engine/Rendering/Util/CommonFunctions.cpp | 17 +++++ src/Game/Game.cpp | 1 + 17 files changed, 149 insertions(+), 83 deletions(-) diff --git a/include/Engine/GUI/TextureFrame.h b/include/Engine/GUI/TextureFrame.h index 2c6d34dd..77967b4d 100644 --- a/include/Engine/GUI/TextureFrame.h +++ b/include/Engine/GUI/TextureFrame.h @@ -3,6 +3,7 @@ #include "Frame.h" #include "../Rendering/Texture.h" +#include "../Rendering/Util/CommonFunctions.h" namespace GUI { @@ -55,10 +56,10 @@ public: return; } - m_Texture = ResourceManager::Load(resourceName); + m_Texture = CommonFunctions::LoadTexture(resourceName, false); m_TextureName = resourceName; if (m_Texture == nullptr) { - m_Texture = ResourceManager::Load("Textures/Core/ErrorTexture.png"); + m_Texture = CommonFunctions::LoadTexture("Textures/Core/ErrorTexture.png", false); } SizeToTexture(); diff --git a/include/Engine/Rendering/DrawFinalPass.h b/include/Engine/Rendering/DrawFinalPass.h index 867ec844..98f986b4 100644 --- a/include/Engine/Rendering/DrawFinalPass.h +++ b/include/Engine/Rendering/DrawFinalPass.h @@ -7,6 +7,7 @@ #include "FrameBuffer.h" #include "ShaderProgram.h" #include "Util/UnorderedMapVec2.h" +#include "Util/CommonFunctions.h" #include "Texture.h" class DrawFinalPass @@ -43,6 +44,7 @@ private: Texture* m_BlackTexture; Texture* m_NeutralNormalTexture; Texture* m_GreyTexture; + Texture* m_ErrorTexture; FrameBuffer m_FinalPassFrameBuffer; GLuint m_BloomTexture; diff --git a/include/Engine/Rendering/Model.h b/include/Engine/Rendering/Model.h index f751a8cc..6812494c 100644 --- a/include/Engine/Rendering/Model.h +++ b/include/Engine/Rendering/Model.h @@ -2,6 +2,7 @@ #define Model_h__ #include "Rendering/RawModelCustom.h" +#include "Util/CommonFunctions.h" //#include "Rendering/RawModelAssimp.h" #include "../OpenGL.h" diff --git a/include/Engine/Rendering/PNG.h b/include/Engine/Rendering/PNG.h index f2cbf157..a45e9e7c 100644 --- a/include/Engine/Rendering/PNG.h +++ b/include/Engine/Rendering/PNG.h @@ -6,9 +6,10 @@ #include #include "../Common.h" +#include "../Core/ResourceManager.h" #include "Image.h" -class PNG : public Image +class PNG : public Image, public Resource { public: PNG(std::string path); diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index 33a61edf..04754514 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -22,6 +22,7 @@ #include "../Core/Transform.h" #include "imgui/imgui.h" #include "TextPass.h" +#include "Util/CommonFunctions.h" class Renderer : public IRenderer { diff --git a/include/Engine/Rendering/SpriteJob.h b/include/Engine/Rendering/SpriteJob.h index a20d0395..23bf6360 100644 --- a/include/Engine/Rendering/SpriteJob.h +++ b/include/Engine/Rendering/SpriteJob.h @@ -24,23 +24,17 @@ struct SpriteJob : RenderJob ::RawModel::MaterialGroup matGroup = Model->MaterialGroups().front(); TextureID = (matGroup.Texture) ? matGroup.Texture->ResourceID : 0; - if (cSprite["DiffuseTexture"]) { - DiffuseTexture = ResourceManager::Load(cSprite["DiffuseTexture"]); - } else { - DiffuseTexture = nullptr; - } - if (cSprite["GlowMap"]) { - IncandescenceTexture = ResourceManager::Load(cSprite["GlowMap"]); - } else { - IncandescenceTexture = nullptr; - } + DiffuseTexture = CommonFunctions::LoadTexture(cSprite["DiffuseTexture"], true); + + IncandescenceTexture = CommonFunctions::LoadTexture(cSprite["GlowMap"], true); + StartIndex = matGroup.StartIndex; EndIndex = matGroup.EndIndex; Matrix = matrix; Color = cSprite["Color"]; Entity = cSprite.EntityID; - glm::vec3 abspos = Transform::AbsolutePosition(world, cSprite.EntityID); - glm::vec3 viewpos = glm::vec3(camera->ViewMatrix() * glm::vec4(abspos, 1)); + Position = Transform::AbsolutePosition(world, cSprite.EntityID); + glm::vec3 viewpos = glm::vec3(camera->ViewMatrix() * glm::vec4(Position, 1)); Depth = viewpos.z; World = world; @@ -58,6 +52,7 @@ struct SpriteJob : RenderJob const Texture* IncandescenceTexture; float Shininess = 0.f; glm::vec4 Color; + glm::vec3 Position; const ::Model* Model = nullptr; unsigned int StartIndex = 0; unsigned int EndIndex = 0; diff --git a/include/Engine/Rendering/Util/CommonFunctions.h b/include/Engine/Rendering/Util/CommonFunctions.h index b262568c..e178f52d 100644 --- a/include/Engine/Rendering/Util/CommonFunctions.h +++ b/include/Engine/Rendering/Util/CommonFunctions.h @@ -4,14 +4,11 @@ #include "../../Common.h" #include "../../OpenGL.h" #include "../../GLM.h" +#include "../Texture.h" -class CommonFuntions -{ -public: - CommonFuntions() = delete; - -private: - +namespace CommonFunctions +{ +Texture* LoadTexture(std::string path, bool threaded); }; #endif \ No newline at end of file diff --git a/resources/Schema/Entities/QualityAssurance.xml b/resources/Schema/Entities/QualityAssurance.xml index e057cf38..23ebb4a5 100644 --- a/resources/Schema/Entities/QualityAssurance.xml +++ b/resources/Schema/Entities/QualityAssurance.xml @@ -40,7 +40,7 @@ - + @@ -188,7 +188,7 @@ - + @@ -683,7 +683,7 @@ - + @@ -730,7 +730,7 @@ - + @@ -790,7 +790,7 @@ - + @@ -837,7 +837,7 @@ - + @@ -883,7 +883,7 @@ - + @@ -930,7 +930,7 @@ - + @@ -977,7 +977,7 @@ - + @@ -1374,7 +1374,7 @@ - + @@ -1383,7 +1383,7 @@ true - 0.75008034908941568 + 0.75102457088592522 3.7999999523162842 true @@ -1430,7 +1430,7 @@ - + @@ -1439,7 +1439,7 @@ - 1.1999860997035228 + 1.2009303215000324 Models/Assault.mesh @@ -1482,7 +1482,7 @@ - + @@ -1497,7 +1497,7 @@ true - 0.68343188336345406 + 0.68437610515996361 true @@ -1553,6 +1553,50 @@ + + + + + + + + + + + + Textures/FoliageDiff.png + Textures/DefenderGunBlueIncd.png + + + + + + + + + Textures/FoliageDiff.png + Textures/AssaultWeaponBlueGlowMap.png + + + + + + + + + + + Textures/FoliageDiff.png + Textures/GlowTest.png + + + + + + + + + diff --git a/resources/Shaders/Sprite.vert.glsl b/resources/Shaders/Sprite.vert.glsl index e910a26a..c09d745b 100644 --- a/resources/Shaders/Sprite.vert.glsl +++ b/resources/Shaders/Sprite.vert.glsl @@ -16,7 +16,8 @@ out VertexData{ void main() { - gl_Position = P * M * vec4(Position, 1.0); + + gl_Position = P * V * M * vec4(Position, 1.0); Output.Position = Position; Output.TextureCoordinate = TextureCoords; diff --git a/src/Engine/Rendering/DrawBloomPass.cpp b/src/Engine/Rendering/DrawBloomPass.cpp index 5d8b2359..2c9e47b4 100644 --- a/src/Engine/Rendering/DrawBloomPass.cpp +++ b/src/Engine/Rendering/DrawBloomPass.cpp @@ -13,7 +13,7 @@ DrawBloomPass::DrawBloomPass(IRenderer* renderer) void DrawBloomPass::InitializeTextures() { - m_WhiteTexture = ResourceManager::Load("Textures/Core/White.png"); + m_WhiteTexture = CommonFunctions::LoadTexture("Textures/Core/White.png", false); } void DrawBloomPass::InitializeShaderPrograms() diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index e5919fbe..98f17835 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -11,10 +11,11 @@ DrawFinalPass::DrawFinalPass(IRenderer* renderer, LightCullingPass* lightCulling void DrawFinalPass::InitializeTextures() { - m_WhiteTexture = ResourceManager::Load("Textures/Core/White.png"); - m_BlackTexture = ResourceManager::Load("Textures/Core/Black.png"); - m_NeutralNormalTexture = ResourceManager::Load("Textures/Core/NeutralNormalMap.png"); - m_GreyTexture = ResourceManager::Load("Textures/Core/Grey.png"); + m_WhiteTexture = CommonFunctions::LoadTexture("Textures/Core/White.png", false); + m_BlackTexture = CommonFunctions::LoadTexture("Textures/Core/Black.png", false); + m_NeutralNormalTexture = CommonFunctions::LoadTexture("Textures/Core/NeutralNormalMap.png", false); + m_GreyTexture = CommonFunctions::LoadTexture("Textures/Core/Grey.png", false); + m_ErrorTexture = CommonFunctions::LoadTexture("Textures/Core/ErrorTexture.png", false); } void DrawFinalPass::InitializeFrameBuffers() @@ -56,7 +57,7 @@ void DrawFinalPass::InitializeShaderPrograms() m_ExplosionEffectProgram->Link(); GLERROR("Creating explosion program"); - m_SpriteProgram = ResourceManager::Load("#m_SpriteProgram"); + m_SpriteProgram = ResourceManager::Load("#SpriteProgram"); m_SpriteProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/Sprite.vert.glsl"))); m_SpriteProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/Sprite.frag.glsl"))); m_SpriteProgram->Compile(); @@ -222,10 +223,12 @@ void DrawFinalPass::DrawSprites(std::list>&jobs, Rend for(auto& job : jobs) { auto spriteJob = std::dynamic_pointer_cast(job); - if(spriteJob) { + if (spriteJob) { + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(spriteJob->Matrix)); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + glUniform3fv(glGetUniformLocation(shaderHandle, "CameraPos"), 1, glm::value_ptr(scene.Camera->Position())); glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(spriteJob->Color)); glUniform4fv(glGetUniformLocation(shaderHandle, "FillColor"), 1, glm::value_ptr(spriteJob->FillColor)); glUniform1f(glGetUniformLocation(shaderHandle, "FillPercentage"), spriteJob->FillPercentage); @@ -234,7 +237,7 @@ void DrawFinalPass::DrawSprites(std::list>&jobs, Rend if (spriteJob->DiffuseTexture != nullptr) { glBindTexture(GL_TEXTURE_2D, spriteJob->DiffuseTexture->m_Texture); } else { - glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + glBindTexture(GL_TEXTURE_2D, m_ErrorTexture->m_Texture); } glActiveTexture(GL_TEXTURE1); diff --git a/src/Engine/Rendering/Model.cpp b/src/Engine/Rendering/Model.cpp index cf4923a3..82dd71af 100644 --- a/src/Engine/Rendering/Model.cpp +++ b/src/Engine/Rendering/Model.cpp @@ -7,16 +7,16 @@ Model::Model(std::string fileName) for (auto& group : m_RawModel->MaterialGroups) { if (!group.TexturePath.empty()) { - group.Texture = std::shared_ptr(ResourceManager::Load(group.TexturePath)); + group.Texture = std::shared_ptr(CommonFunctions::LoadTexture(group.TexturePath, false)); } if (!group.NormalMapPath.empty()) { - group.NormalMap = std::shared_ptr(ResourceManager::Load(group.NormalMapPath)); + group.NormalMap = std::shared_ptr(CommonFunctions::LoadTexture(group.NormalMapPath, false)); } if (!group.SpecularMapPath.empty()) { - group.SpecularMap = std::shared_ptr(ResourceManager::Load(group.SpecularMapPath)); + group.SpecularMap = std::shared_ptr(CommonFunctions::LoadTexture(group.SpecularMapPath, false)); } if (!group.IncandescenceMapPath.empty()) { - group.IncandescenceMap = std::shared_ptr(ResourceManager::Load(group.IncandescenceMapPath)); + group.IncandescenceMap = std::shared_ptr(CommonFunctions::LoadTexture(group.IncandescenceMapPath, false)); } } diff --git a/src/Engine/Rendering/PNG.cpp b/src/Engine/Rendering/PNG.cpp index 7ffd5c20..409da9b1 100644 --- a/src/Engine/Rendering/PNG.cpp +++ b/src/Engine/Rendering/PNG.cpp @@ -4,40 +4,35 @@ PNG::PNG(std::string path) { FILE* file = fopen(path.c_str(), "rb"); if (!file) { - LOG_ERROR("Failed to open texture file \"%s\": %s", path.c_str(), const_cast(strerror(errno))); - return; + throw Resource::FailedLoadingException("Failed to open texture file."); } png_byte header[8]; fread(header, 1, 8, file); bool isPNG = !png_sig_cmp(header, 0, 8); if (!isPNG) { - LOG_ERROR("Failed to load texture file \"%s\": File isn't PNG", path.c_str()); fclose(file); - return; + throw Resource::FailedLoadingException("File is not PNG."); } // Initialize libpng png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, (png_error_ptr)&PNG::pngErrorFunction, (png_error_ptr)&PNG::pngErrorFunction); if (!png_ptr) { - LOG_ERROR("libpng: Failed to initialze png_struct"); png_destroy_read_struct(&png_ptr, nullptr, nullptr); fclose(file); - return; + throw Resource::FailedLoadingException("Failed to initialze png_struct."); } png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { - LOG_ERROR("libpng: Failed to initialze png_info"); png_destroy_read_struct(&png_ptr, nullptr, nullptr); fclose(file); - return; + throw Resource::FailedLoadingException("Failed to initialze png_info."); } png_infop info_end_ptr = png_create_info_struct(png_ptr); if (!info_end_ptr) { - LOG_ERROR("libpng: Failed to initialze second png_info"); png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); fclose(file); - return; + throw Resource::FailedLoadingException("Failed to initialze second png_info."); } png_init_io(png_ptr, file); @@ -51,8 +46,8 @@ PNG::PNG(std::string path) unsigned int width, height; png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); if (bit_depth != 8) { - LOG_ERROR("libpng: Unsupported bit depth \"%i\" of image \"%s\", must be 8", bit_depth, path.c_str()); - return; + throw Resource::FailedLoadingException("Unsupported bit depth. Must be 8"); + } switch (color_type) { case PNG_COLOR_TYPE_RGB: @@ -60,8 +55,7 @@ PNG::PNG(std::string path) Format = Image::ImageFormat::RGBA; break; default: - LOG_ERROR("libpng: Unsupported color format \"%i\" of image \"%s\"", color_type, path.c_str()); - return; + throw Resource::FailedLoadingException("Unsupported color format."); } // Convert RGB to RGBA, since DirectX rather treat them all the same way diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index a63e02a0..c0e4d07c 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -106,16 +106,21 @@ void Renderer::Draw(RenderFrame& frame) for (auto scene : frame.RenderScenes){ SortRenderJobsByDepth(*scene); + GLERROR("SortByDepth"); m_PickingPass->Draw(*scene); + GLERROR("Drawing pickingpass"); m_LightCullingPass->GenerateNewFrustum(*scene); + GLERROR("Generate frustums"); m_LightCullingPass->FillLightList(*scene); + GLERROR("Filling light list"); m_LightCullingPass->CullLights(*scene); + GLERROR("LightCulling"); m_DrawFinalPass->Draw(*scene); + GLERROR("Draw Geometry+Light"); //m_DrawScenePass->Draw(*scene); - GLERROR("Renderer::Draw m_DrawScenePass->Draw"); - m_TextPass->Draw(*scene, *m_DrawFinalPass->FinalPassFrameBuffer()); + GLERROR("Draw Text"); } m_DrawBloomPass->Draw(m_DrawFinalPass->BloomTexture()); @@ -136,7 +141,8 @@ void Renderer::Draw(RenderFrame& frame) } m_ImGuiRenderPass->Draw(); - glfwSwapBuffers(m_Window); + GLERROR("Imgui draw"); + glfwSwapBuffers(m_Window); } PickData Renderer::Pick(glm::vec2 screenCoord) @@ -146,8 +152,8 @@ PickData Renderer::Pick(glm::vec2 screenCoord) void Renderer::InitializeTextures() { - m_ErrorTexture = ResourceManager::Load("Textures/Core/ErrorTexture.png"); - m_WhiteTexture = ResourceManager::Load("Textures/Core/White.png"); + m_ErrorTexture = CommonFunctions::LoadTexture("Textures/Core/ErrorTexture.png", false); + m_WhiteTexture = CommonFunctions::LoadTexture("Textures/Core/White.png", false); } @@ -155,6 +161,7 @@ void Renderer::SortRenderJobsByDepth(RenderScene &scene) { //Sort all forward jobs so transparency is good. scene.TransparentObjects.sort(Renderer::DepthSort); + scene.SpriteJobs.sort(Renderer::DepthSort); } void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) diff --git a/src/Engine/Rendering/Texture.cpp b/src/Engine/Rendering/Texture.cpp index 492b35be..a4b2d4c9 100644 --- a/src/Engine/Rendering/Texture.cpp +++ b/src/Engine/Rendering/Texture.cpp @@ -2,24 +2,25 @@ Texture::Texture(std::string path) { + PNG* img = ResourceManager::Load(path); //TODO: Make this threaded. Catch exeptions in all other load places. - PNG image(path); + //PNG image(path); - if (image.Width == 0 && image.Height == 0 || image.Format == Image::ImageFormat::Unknown) { - //image = PNG("Textures/Core/ErrorTexture.png"); - return; // Temporary fix to remove crash - /* - if (image.Width == 0 && image.Height == 0 || image.Format == Image::ImageFormat::Unknown) { - LOG_ERROR("Couldn't even load the error texture. This is a dark day indeed."); - return; - }*/ - } + //if (img->Width == 0 && img->Height == 0 || img->Format == Image::ImageFormat::Unknown) { + // //image = PNG("Textures/Core/ErrorTexture.png"); + // //return; // Temporary fix to remove crash - this->Width = image.Width; - this->Height = image.Height; + // if (img->Width == 0 && img->Height == 0 || img->Format == Image::ImageFormat::Unknown) { + // LOG_ERROR("Couldn't even load the error texture. This is a dark day indeed."); + // return; + // } + //} + + this->Width = img->Width; + this->Height = img->Height; GLint format; - switch (image.Format) { + switch (img->Format) { case Image::ImageFormat::RGB: format = GL_RGB; break; @@ -32,7 +33,7 @@ Texture::Texture(std::string path) glGenTextures(1, &m_Texture); glBindTexture(GL_TEXTURE_2D, m_Texture); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexImage2D(GL_TEXTURE_2D, 0, format, image.Width, image.Height, 0, format, GL_UNSIGNED_BYTE, image.Data); + glTexImage2D(GL_TEXTURE_2D, 0, format, img->Width, img->Height, 0, format, GL_UNSIGNED_BYTE, img->Data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); diff --git a/src/Engine/Rendering/Util/CommonFunctions.cpp b/src/Engine/Rendering/Util/CommonFunctions.cpp index 3c81de66..382cb790 100644 --- a/src/Engine/Rendering/Util/CommonFunctions.cpp +++ b/src/Engine/Rendering/Util/CommonFunctions.cpp @@ -1,2 +1,19 @@ #include "Rendering/Util/CommonFunctions.h" +Texture* CommonFunctions::LoadTexture(std::string path, bool threaded) +{ + Texture* img; + try { + if(threaded) { + img = ResourceManager::Load(path); + } else { + img = ResourceManager::Load(path); + } + } catch (const Resource::StillLoadingException&) { + img = ResourceManager::Load("Textures/Core/ErrorTexture.png"); + } catch (const std::exception&) { + img = nullptr; + } + + return img; +} diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 0cc41a73..780842a6 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -25,6 +25,7 @@ Game::Game(int argc, char* argv[]) ResourceManager::RegisterType("Model"); ResourceManager::RegisterType("RawModel"); ResourceManager::RegisterType("Texture"); + ResourceManager::RegisterType("Png"); ResourceManager::RegisterType("ShaderProgram"); ResourceManager::RegisterType("EntityFile"); ResourceManager::RegisterType("FontFile"); From 224e95f34aee8c1f23bd8a6941b02b352989240e Mon Sep 17 00:00:00 2001 From: viktorljung Date: Wed, 10 Feb 2016 20:45:24 +0100 Subject: [PATCH 14/31] Fixed BoneAttachment component and optimized animation code a bit --- assets | 2 +- include/Engine/Rendering/AnimationSystem.h | 4 +- include/Engine/Rendering/ModelJob.h | 32 +- include/Engine/Rendering/Skeleton.h | 35 +- resources/Schema/Entities/AnimationTests2.xml | 508 +++++++++++++++++- resources/Schema/Entities/AnimationTests3.xml | 108 ++++ resources/Schema/Entities/FirstPersonArms | 57 ++ src/Engine/Core/ComponentPool.cpp | 2 +- src/Engine/Rendering/AnimationSystem.cpp | 29 +- src/Engine/Rendering/BoneAttachmentSystem.cpp | 9 +- src/Engine/Rendering/DrawFinalPass.cpp | 49 +- src/Engine/Rendering/PickingPass.cpp | 24 +- src/Engine/Rendering/RenderSystem.cpp | 12 +- src/Engine/Rendering/Skeleton.cpp | 405 ++++++-------- 14 files changed, 912 insertions(+), 364 deletions(-) create mode 100644 resources/Schema/Entities/AnimationTests3.xml create mode 100644 resources/Schema/Entities/FirstPersonArms diff --git a/assets b/assets index 7531e441..45cbc3ab 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 7531e441fea639076d69c6cf05e3ae8ff7170cf9 +Subproject commit 45cbc3abaebe5f815e2c1b58bcf884d4953a4c52 diff --git a/include/Engine/Rendering/AnimationSystem.h b/include/Engine/Rendering/AnimationSystem.h index 15dbe39d..aa9d3a11 100644 --- a/include/Engine/Rendering/AnimationSystem.h +++ b/include/Engine/Rendering/AnimationSystem.h @@ -23,9 +23,7 @@ public: ~AnimationSystem() { } virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& animationComponent, double dt) override; private: - float angle = 0.f; - bool b_forward = false; - char bone[100]; + }; #endif \ No newline at end of file diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h index bc2b8b6e..4bb1b51f 100644 --- a/include/Engine/Rendering/ModelJob.h +++ b/include/Engine/Rendering/ModelJob.h @@ -117,33 +117,11 @@ struct ModelJob : RenderJob FillColor = fillColor; FillPercentage = fillPercentage; - Skeleton = Model->m_RawModel->m_Skeleton; - if (Skeleton != nullptr) { - if (world->HasComponent(Entity, "Animation")) { - auto animationComponent = world->GetComponent(Entity, "Animation"); - - for (int i = 1; i <= 3; i++) { - ::Skeleton::AnimationData animationData; - animationData.animation = model->m_RawModel->m_Skeleton->GetAnimation(animationComponent["AnimationName" + std::to_string(i)]); - if (animationData.animation == nullptr) { - continue; - } - animationData.time = (double)animationComponent["Time" + std::to_string(i)]; - animationData.weight = (double)animationComponent["Weight" + std::to_string(i)]; - - Animations.push_back(animationData); - } - } - - if (world->HasComponent(Entity, "AnimationOffset")) { - auto animationOffsetComponent = world->GetComponent(Entity, "AnimationOffset"); - AnimationOffset.animation = model->m_RawModel->m_Skeleton->GetAnimation(animationOffsetComponent["AnimationName"]); - AnimationOffset.time = (double)animationOffsetComponent["Time"]; - } else { - AnimationOffset.animation = nullptr; - } + if (model->IsSkinned()) { + Skeleton = Model->m_RawModel->m_Skeleton; } + }; unsigned int TextureID; @@ -164,10 +142,8 @@ struct ModelJob : RenderJob ::Skeleton* Skeleton = nullptr; // const ::Skeleton::Animation* Animation = nullptr; - std::vector<::Skeleton::AnimationData> Animations; - ::Skeleton::AnimationOffset AnimationOffset; + - float AnimationTime = 0.f; glm::vec4 DiffuseColor; glm::vec4 SpecularColor; diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index 124d618b..a8dd982d 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -100,13 +100,13 @@ public: int GetBoneID(std::string name); - const Animation* GetAnimation(std::string name); - std::vector GetFrameBones(std::vector animations, bool noRootMotion = false); - std::vector GetFrameBones(std::vector animations, AnimationOffset animationOffset, bool noRootMotion = false); + void CalculateFrameBones(std::vector animations, AnimationOffset animationOffset, bool noRootMotion = false); + void CalculateFrameBones(std::vector animations, bool noRootMotion = false); - //void AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); - void AccumulateBoneTransforms(bool noRootMotion, std::vector animations, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); - void AccumulateBoneTransforms(bool noRootMotion, std::vector animations, AnimationOffset animationOffset, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix); + const Animation* GetAnimation(std::string name); + + void AccumulateBoneTransforms(bool noRootMotion, std::vector animations, const Bone* bone, glm::mat4 parentMatrix); + void AccumulateBoneTransforms(bool noRootMotion, std::vector animations, AnimationOffset animationOffset, const Bone* bone, glm::mat4 parentMatrix); void PrintSkeleton(); void PrintSkeleton(const Bone* parent, int depthCount); @@ -115,12 +115,35 @@ public: glm::mat4 GetBoneTransform(const Bone* bone, const Animation* animation, float time, glm::mat4 childMatrix); int GetKeyframe(const Animation& animation, double time); + + std::vector GetBones() + { + std::vector finalMatrices; + for (auto &kv : m_BoneLocalTransforms) { + finalMatrices.push_back(kv.second); + } + return finalMatrices;; + } + + glm::mat4 GetBoneTransformSuper(int boneID) + { + if(m_BoneTransforms.find(boneID) != m_BoneTransforms.end()) { + return m_BoneTransforms.at(boneID); + } else { + return glm::mat4(1); + } + } + private: glm::mat4 GetOffsetTransform(const Bone* bone, AnimationOffset animationOffset); std::map m_BonesByName; float aim = 0.f; + + + std::map m_BoneLocalTransforms; + std::map m_BoneTransforms; }; #endif diff --git a/resources/Schema/Entities/AnimationTests2.xml b/resources/Schema/Entities/AnimationTests2.xml index 96a439a4..09573ac7 100644 --- a/resources/Schema/Entities/AnimationTests2.xml +++ b/resources/Schema/Entities/AnimationTests2.xml @@ -31,28 +31,524 @@ Run 0.5 - 0.23980116887997371 + 0.78014858943309839 1 1 StrafeRight 0.5 - 0.42593105566437428 - ReloadSwitch - 0.68855715986371058 + 0.78620929522779459 + ShootFastRifle + 0.13809128482706701 1 AimRifle + Models/Characters/Assault/AssaultAnimations.mesh - + + true - + + + + + + + + + + R_Arm_Weapon_Joint + + + + Models/Weapons/Blue/AssaultWeapon.mesh + + true + + + + + + + + + + + + R_Hand + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Arm + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Shoulder + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Neck + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Spine_3 + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Spine_2 + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Spine_1 + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Hip + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Leg_Top + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Leg_Bottom + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Foot + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Toe + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Shoulder + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Arm + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Hand + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Shoulder_Armor_Joint + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Chin + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Head + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Perietal + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + L_Elbow + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Leg_Bottom + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Elbow + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Leg_Top + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Foot + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Toe + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + R_Shoulder_Armor_Joint + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + diff --git a/resources/Schema/Entities/AnimationTests3.xml b/resources/Schema/Entities/AnimationTests3.xml new file mode 100644 index 00000000..bd985b2d --- /dev/null +++ b/resources/Schema/Entities/AnimationTests3.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + Models/Widgets/Lights/DirectionalLightWidget.mesh + + + + + + + + + + + + Run + 0.5 + 0.97312056690160276 + 1 + 1 + ReloadSwitch + 0.91310356788604263 + LeftRight + 0 + 0.040207288496060478 + 1 + + + DownUp + + + + Models/Characters/Assault/FirstPerson.mesh + + true + + + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Blue/AssaultWeapon.mesh + + + + + + + + + + + + + + + + + + + + + 10 + + + + + + + + + + + Models/Core/UnitPlane.mesh + + + + + + + + + + + + diff --git a/resources/Schema/Entities/FirstPersonArms b/resources/Schema/Entities/FirstPersonArms new file mode 100644 index 00000000..bf749a4e --- /dev/null +++ b/resources/Schema/Entities/FirstPersonArms @@ -0,0 +1,57 @@ + + + + + + Run + 0.5 + 0.97312056690160276 + 1 + 1 + ReloadSwitch + 0.91310356788604263 + LeftRight + 0 + 0.040207288496060478 + 1 + + + DownUp + + + + Models/Characters/Assault/FirstPerson.mesh + + true + + + + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Blue/AssaultWeapon.mesh + + + + + + + + + + + + + + + + + + diff --git a/src/Engine/Core/ComponentPool.cpp b/src/Engine/Core/ComponentPool.cpp index f4ca9f4a..7b465fbc 100644 --- a/src/Engine/Core/ComponentPool.cpp +++ b/src/Engine/Core/ComponentPool.cpp @@ -47,7 +47,7 @@ ComponentWrapper ComponentPool::Allocate(EntityID entity) ComponentWrapper ComponentPool::GetByEntity(EntityID ent) { - return ComponentWrapper(m_ComponentInfo, m_EntityToComponent.at(ent)); + return ComponentWrapper(m_ComponentInfo, m_EntityToComponent.at(ent)); } bool ComponentPool::KnowsEntity(EntityID ent) diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index 4566410f..25813a63 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -24,7 +24,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["AnimationName" + std::to_string(i)]); if (animation == nullptr) { - return; + continue;; } double animationSpeed = (double)animationComponent["Speed" + std::to_string(i)]; @@ -49,5 +49,32 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a } } } + + //Calculate bone transforms + if (skeleton != nullptr) { + std::vector animations; + if (entity.HasComponent("Animation")) { + for (int i = 1; i <= 3; i++) { + Skeleton::AnimationData animationData; + animationData.animation = model->m_RawModel->m_Skeleton->GetAnimation(entity["Animation"]["AnimationName" + std::to_string(i)]); + if (animationData.animation == nullptr) { + continue; + } + animationData.time = (double)entity["Animation"]["Time" + std::to_string(i)]; + animationData.weight = (double)entity["Animation"]["Weight" + std::to_string(i)]; + + animations.push_back(animationData); + } + } + + if (entity.HasComponent("AnimationOffset")) { + Skeleton::AnimationOffset animationOffset; + animationOffset.animation = skeleton->GetAnimation(entity["AnimationOffset"]["AnimationName"]); + animationOffset.time = (double)entity["AnimationOffset"]["Time"]; + skeleton->CalculateFrameBones(animations, animationOffset); + } else { + skeleton->CalculateFrameBones(animations); + } + } } diff --git a/src/Engine/Rendering/BoneAttachmentSystem.cpp b/src/Engine/Rendering/BoneAttachmentSystem.cpp index bdc45fa6..a9588a16 100644 --- a/src/Engine/Rendering/BoneAttachmentSystem.cpp +++ b/src/Engine/Rendering/BoneAttachmentSystem.cpp @@ -39,7 +39,8 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp } - glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], animation, (double)parent["Animation"]["Time1"], glm::mat4(1)); + glm::mat4 boneTransform = skeleton->GetBoneTransformSuper(id); + //glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], animation, (double)parent["Animation"]["Time1"], glm::mat4(1)); glm::vec3 scale; glm::quat rotation; @@ -48,7 +49,9 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp glm::vec4 perspective; glm::decompose(boneTransform, scale, rotation, translation, skew, perspective); - glm::vec3 angles; + glm::vec3 angles = glm::vec3(-glm::pitch(rotation), -glm::yaw(rotation), -glm::roll(rotation)); +/* + angles.y = asin(-boneTransform[0][2]); if (cos(angles.y) != 0) { angles.x = atan2(boneTransform[1][2], boneTransform[2][2]); @@ -56,7 +59,7 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp } else { angles.x = atan2(-boneTransform[2][0], boneTransform[1][1]); angles.z = 0; - } + }*/ if ((bool)entity["BoneAttachment"]["InheritPosition"]) { (glm::vec3&)entity["Transform"]["Position"] = translation + (glm::vec3)entity["BoneAttachment"]["PositionOffset"]; diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 0d08b98f..00b85528 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -328,11 +328,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& //bind textures BindExplosionTextures(explosionSkinnedHandle, explosionEffectJob); std::vector frameBones; - if (explosionEffectJob->AnimationOffset.animation != nullptr) { - frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); - } else { - frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); - } + frameBones = explosionEffectJob->Skeleton->GetBones(); glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { m_ExplosionEffectProgram->Bind(); @@ -355,11 +351,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& BindExplosionTextures(explosionSplatMapSkinnedHandle, explosionEffectJob); GLERROR("asdasd"); std::vector frameBones; - if (explosionEffectJob->AnimationOffset.animation != nullptr) { - frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); - } else { - frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); - } + frameBones = explosionEffectJob->Skeleton->GetBones(); glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { @@ -400,11 +392,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& //bind textures BindModelTextures(forwardSkinnedHandle, modelJob); std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); - } else { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } + frameBones = modelJob->Skeleton->GetBones(); glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { @@ -428,11 +416,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& BindModelTextures(forwardSplatMapSkinnedHandle, modelJob); GLERROR("asdasd"); std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); - } else { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } + frameBones = modelJob->Skeleton->GetBones(); glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { @@ -476,13 +460,8 @@ void DrawFinalPass::DrawShieldToStencilBuffer(std::listViewMatrix())); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); - } else { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } + frameBones = modelJob->Skeleton->GetBones(); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); - } else { m_ShieldToStencilProgram->Bind(); GLuint shaderHandle = m_ShieldToStencilProgram->GetHandle(); @@ -535,11 +514,7 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list frameBones; - if (explosionEffectJob->AnimationOffset.animation != nullptr) { - frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); - } else { - frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); - } + frameBones = explosionEffectJob->Skeleton->GetBones(); glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); if (GLERROR("Animation")) { @@ -574,11 +549,7 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); - } else { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } + frameBones = modelJob->Skeleton->GetBones(); glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); @@ -610,11 +581,7 @@ void DrawFinalPass::DrawToDepthBuffer(std::list>& job glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); - } else { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } + frameBones = modelJob->Skeleton->GetBones(); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index fa1b3ca3..cc9837ff 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -103,11 +103,7 @@ void PickingPass::Draw(RenderScene& scene) if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); - } else { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } + frameBones = modelJob->Skeleton->GetBones(); glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } @@ -160,11 +156,7 @@ void PickingPass::Draw(RenderScene& scene) glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); - } else { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } + frameBones = modelJob->Skeleton->GetBones(); glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { m_PickingProgram->Bind(); @@ -215,11 +207,7 @@ void PickingPass::Draw(RenderScene& scene) glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); - } else { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } + frameBones = modelJob->Skeleton->GetBones(); glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { @@ -276,11 +264,7 @@ void PickingPass::Draw(RenderScene& scene) if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { std::vector frameBones; - if (modelJob->AnimationOffset.animation != nullptr) { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); - } else { - frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); - } + frameBones = modelJob->Skeleton->GetBones(); glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index ab9a3c27..d2c71f5e 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -62,14 +62,14 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs) } // Only render children of a camera if that camera is currently active - if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) { - continue; - } + if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) { + continue; + } // Hide things parented to local player if they have the HiddenFromLocalPlayer component - if (entity.HasComponent("HiddenForLocalPlayer") && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer))) { - continue; - } + if (entity.HasComponent("HiddenForLocalPlayer") && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer))) { + continue; + } Model* model; try { diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index f272f14d..1aabd84c 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -29,6 +29,32 @@ Skeleton::~Skeleton() } } + +void Skeleton::CalculateFrameBones(std::vector animations, AnimationOffset animationOffset, bool noRootMotion /*= false*/) +{ + if (animations.size() <= 0 || animationOffset.animation == nullptr) { + for (auto& b : Bones) { + m_BoneLocalTransforms[b.first] = glm::mat4(1); + m_BoneTransforms[b.first] = glm::mat4(1); + } + } else { + AccumulateBoneTransforms(noRootMotion, animations, animationOffset, RootBone, glm::mat4(1)); + } +} + + +void Skeleton::CalculateFrameBones(std::vector animations, bool noRootMotion /*= false*/) +{ + if (animations.size() <= 0) { + for (auto& b : Bones) { + m_BoneLocalTransforms[b.first] = glm::mat4(1); + m_BoneTransforms[b.first] = glm::mat4(1); + } + } else { + AccumulateBoneTransforms(noRootMotion, animations, RootBone, glm::mat4(1)); + } +} + const Skeleton::Animation* Skeleton::GetAnimation(std::string name) { auto it = Animations.find(name); @@ -39,252 +65,10 @@ const Skeleton::Animation* Skeleton::GetAnimation(std::string name) } } -std::vector Skeleton::GetFrameBones(std::vector animations, bool noRootMotion /*= false*/) -{ - if (animations.size() <= 0) { - std::vector finalMatrices; - for (auto& b : Bones) { - finalMatrices.push_back(glm::mat4(1));//b.second->OffsetMatrix); - } - return finalMatrices; - } - - std::map frameBones; - AccumulateBoneTransforms(true, animations, frameBones, RootBone, glm::mat4(1)); - - std::vector finalMatrices; - for (auto &kv : frameBones) { - finalMatrices.push_back(kv.second); - } - return finalMatrices; -} - - -std::vector Skeleton::GetFrameBones(std::vector animations, AnimationOffset animationOffset, bool noRootMotion /*= false*/) -{ - if (animations.size() <= 0 || animationOffset.animation == nullptr) { - std::vector finalMatrices; - for (auto& b : Bones) { - finalMatrices.push_back(glm::mat4(1));//b.second->OffsetMatrix); - } - return finalMatrices; - } - - - std::map frameBones; - AccumulateBoneTransforms(true, animations, animationOffset, frameBones, RootBone, glm::mat4(1)); - - std::vector finalMatrices; - for (auto &kv : frameBones) { - finalMatrices.push_back(kv.second); - } - return finalMatrices; -} -/* - -void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation* animation, float time, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) +void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector animations, AnimationOffset animationOffset, const Bone* bone, glm::mat4 parentMatrix) { glm::mat4 boneMatrix; - Animation::Keyframe currentFrame; - Animation::Keyframe nextFrame; - - if(animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) { - std::vector boneKeyFrames = animation->JointAnimations.at(bone->ID); - - if(boneKeyFrames.size() > 1) { // 2+ keyframes for the current bone - for (int index = boneKeyFrames.size()-1; index >= 0; index--) { // find the bone keyframes that surrounds the current frame - if (time >= boneKeyFrames.at(index).Time) { - currentFrame = boneKeyFrames.at(index); - nextFrame = boneKeyFrames.at((index + 1) % boneKeyFrames.size()); - break; - } - } - - float progress; - - if(nextFrame.Index == 0) { - progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time); - } else { - progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); - - } - - - if (progress > 1.0f || progress < 0.0f) { - LOG_INFO("Progress: %f", progress); - progress = glm::clamp(progress, 0.0f, 1.0f); - } - Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties; - Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties; - - glm::vec3 positionInterp = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress; - glm::quat rotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress); - glm::vec3 scaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress; - - // Flag for no root motion - if (bone == RootBone && noRootMotion) { - positionInterp.x = 0; - positionInterp.z = 0; - } - - boneMatrix = parentMatrix *(glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); - boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; - - } else { // 1 keyframes for the current bone - currentFrame = boneKeyFrames.at(0); - boneMatrix = parentMatrix *(glm::translate(currentFrame.BoneProperties.Position) * glm::toMat4(currentFrame.BoneProperties.Rotation) * glm::scale(currentFrame.BoneProperties.Scale)); - - boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; - } - } else { // 0 keyframes for the current bone - - // LOG_INFO("%s Has no keyframe", bone->Name.c_str()); - if (bone->Parent) { - boneMatrix = parentMatrix * glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix; - boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; - } else { - boneMatrix = glm::inverse(bone->OffsetMatrix); - boneMatrices[bone->ID] = parentMatrix; - } - - } - - for (auto &child : bone->Children) { - AccumulateBoneTransforms(noRootMotion, animation, time, boneMatrices, child, boneMatrix); - } -} -*/ - -void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector animations, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) -{ - glm::mat4 boneMatrix; - - - - std::vector JointTransforms; - - for (const AnimationData animationData : animations) { - const Animation* animation = animationData.animation; - const float time = animationData.time; - - JointFrameTransform jointTransform; - jointTransform.Weight = animationData.weight;; - - if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) { - std::vector boneKeyFrames = animation->JointAnimations.at(bone->ID); - - Animation::Keyframe currentFrame; - Animation::Keyframe nextFrame; - - if (boneKeyFrames.size() > 1) { // 2+ keyframes for the current bone - for (int index = boneKeyFrames.size()-1; index >= 0; index--) { // find the bone keyframes that surrounds the current frame - if (time >= boneKeyFrames.at(index).Time) { - currentFrame = boneKeyFrames.at(index); - nextFrame = boneKeyFrames.at((index + 1) % boneKeyFrames.size()); - break; - } - } - - float progress; - - if (nextFrame.Index == 0) { - progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time); - } else { - progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); - - } - - - if (progress > 1.0f || progress < 0.0f) { - LOG_INFO("Progress: %f", progress); - progress = glm::clamp(progress, 0.0f, 1.0f); - } - Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties; - Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties; - - jointTransform.PositionInterp = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress; - jointTransform.RotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress); - jointTransform.ScaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress; - - // Flag for no root motion - if (bone == RootBone && noRootMotion) { - jointTransform.PositionInterp.x = 0; - jointTransform.PositionInterp.z = 0; - } - - JointTransforms.push_back(jointTransform); - - } else { // 1 keyframes for the current bone - currentFrame = boneKeyFrames.at(0); - jointTransform.PositionInterp = currentFrame.BoneProperties.Position; - jointTransform.RotationInterp = currentFrame.BoneProperties.Rotation; - jointTransform.ScaleInterp = currentFrame.BoneProperties.Scale; - JointTransforms.push_back(jointTransform); - - } - } else { // 0 keyframes for the current bone - - } - - } - - if(JointTransforms.size() <= 0) { - if (bone->Parent) { - boneMatrix = parentMatrix * glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix; - boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; - } else { - boneMatrix = glm::inverse(bone->OffsetMatrix); - boneMatrices[bone->ID] = parentMatrix; - } - } else if (JointTransforms.size() == 1) { - boneMatrix = parentMatrix *(glm::translate(JointTransforms.at(0).PositionInterp) * glm::toMat4(JointTransforms.at(0).RotationInterp) * glm::scale(JointTransforms.at(0).ScaleInterp)); - boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; - } else { - - glm::vec3 finalPosInterp; - glm::quat finalRotInterp; - glm::vec3 finalScaleInterp; - float totalWeight = 0; - - for (JointFrameTransform jointTransform : JointTransforms) { - totalWeight += jointTransform.Weight; - } - - - for (JointFrameTransform jointTransform : JointTransforms) - { - if(jointTransform.Weight == 1.0f) { - finalPosInterp = jointTransform.PositionInterp; - finalRotInterp = jointTransform.RotationInterp; - finalScaleInterp = jointTransform.ScaleInterp; - break; - } else { - finalPosInterp += jointTransform.PositionInterp * (jointTransform.Weight/totalWeight); - finalRotInterp *= glm::slerp(glm::quat(), jointTransform.RotationInterp, (jointTransform.Weight/totalWeight)); - finalScaleInterp += jointTransform.ScaleInterp * (jointTransform.Weight/totalWeight); - } - - } - - boneMatrix = parentMatrix *(glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp)); - boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; - } - - - - for (auto &child : bone->Children) { - AccumulateBoneTransforms(noRootMotion, animations, boneMatrices, child, boneMatrix); - } -} - - -void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector animations, AnimationOffset animationOffset, std::map& boneMatrices, const Bone* bone, glm::mat4 parentMatrix) -{ - glm::mat4 boneMatrix; - - - std::vector JointTransforms; for (const AnimationData animationData : animations) { @@ -363,10 +147,12 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vectorOffsetMatrix) * bone->Parent->OffsetMatrix)); } - boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; + m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix; + m_BoneTransforms[bone->ID] = boneMatrix; } else { boneMatrix = offset * glm::inverse(bone->OffsetMatrix); - boneMatrices[bone->ID] = parentMatrix; + m_BoneLocalTransforms[bone->ID] = parentMatrix; + m_BoneTransforms[bone->ID] = boneMatrix; } } else { @@ -401,15 +187,138 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vectorID] = boneMatrix * bone->OffsetMatrix; + + m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix; + m_BoneTransforms[bone->ID] = boneMatrix; } for (auto &child : bone->Children) { - AccumulateBoneTransforms(noRootMotion, animations, animationOffset, boneMatrices, child, boneMatrix); + AccumulateBoneTransforms(noRootMotion, animations, animationOffset, child, boneMatrix); } } +void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector animations, const Bone* bone, glm::mat4 parentMatrix) +{ + glm::mat4 boneMatrix; + std::vector JointTransforms; + + for (const AnimationData animationData : animations) { + const Animation* animation = animationData.animation; + const float time = animationData.time; + + JointFrameTransform jointTransform; + jointTransform.Weight = animationData.weight;; + + if (animation->JointAnimations.find(bone->ID) != animation->JointAnimations.end()) { + std::vector boneKeyFrames = animation->JointAnimations.at(bone->ID); + + Animation::Keyframe currentFrame; + Animation::Keyframe nextFrame; + + if (boneKeyFrames.size() > 1) { // 2+ keyframes for the current bone + for (int index = boneKeyFrames.size()-1; index >= 0; index--) { // find the bone keyframes that surrounds the current frame + if (time >= boneKeyFrames.at(index).Time) { + currentFrame = boneKeyFrames.at(index); + nextFrame = boneKeyFrames.at((index + 1) % boneKeyFrames.size()); + break; + } + } + + float progress; + + if (nextFrame.Index == 0) { + progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time); + } else { + progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); + + } + + + if (progress > 1.0f || progress < 0.0f) { + LOG_INFO("Progress: %f", progress); + progress = glm::clamp(progress, 0.0f, 1.0f); + } + Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties; + Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties; + + jointTransform.PositionInterp = currentBoneProperty.Position * (1.f - progress) + nextBoneProperty.Position * progress; + jointTransform.RotationInterp = glm::slerp(currentBoneProperty.Rotation, nextBoneProperty.Rotation, progress); + jointTransform.ScaleInterp = currentBoneProperty.Scale * (1.f - progress) + nextBoneProperty.Scale * progress; + + // Flag for no root motion + if (bone == RootBone && noRootMotion) { + jointTransform.PositionInterp.x = 0; + jointTransform.PositionInterp.z = 0; + } + + JointTransforms.push_back(jointTransform); + + } else { // 1 keyframes for the current bone + currentFrame = boneKeyFrames.at(0); + jointTransform.PositionInterp = currentFrame.BoneProperties.Position; + jointTransform.RotationInterp = currentFrame.BoneProperties.Rotation; + jointTransform.ScaleInterp = currentFrame.BoneProperties.Scale; + JointTransforms.push_back(jointTransform); + + } + } else { // 0 keyframes for the current bone + + } + + } + + if (JointTransforms.size() <= 0) { + if (bone->Parent) { + boneMatrix = parentMatrix * glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix; + m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix; + m_BoneTransforms[bone->ID] = boneMatrix; + } else { + boneMatrix = glm::inverse(bone->OffsetMatrix); + m_BoneLocalTransforms[bone->ID] = parentMatrix; + m_BoneTransforms[bone->ID] = boneMatrix; + } + } else if (JointTransforms.size() == 1) { + boneMatrix = parentMatrix *(glm::translate(JointTransforms.at(0).PositionInterp) * glm::toMat4(JointTransforms.at(0).RotationInterp) * glm::scale(JointTransforms.at(0).ScaleInterp)); + m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix; + m_BoneTransforms[bone->ID] = boneMatrix; + } else { + + glm::vec3 finalPosInterp; + glm::quat finalRotInterp; + glm::vec3 finalScaleInterp; + float totalWeight = 0; + + for (JointFrameTransform jointTransform : JointTransforms) { + totalWeight += jointTransform.Weight; + } + + + for (JointFrameTransform jointTransform : JointTransforms) { + if (jointTransform.Weight == 1.0f) { + finalPosInterp = jointTransform.PositionInterp; + finalRotInterp = jointTransform.RotationInterp; + finalScaleInterp = jointTransform.ScaleInterp; + break; + } else { + finalPosInterp += jointTransform.PositionInterp * (jointTransform.Weight/totalWeight); + finalRotInterp *= glm::slerp(glm::quat(), jointTransform.RotationInterp, (jointTransform.Weight/totalWeight)); + finalScaleInterp += jointTransform.ScaleInterp * (jointTransform.Weight/totalWeight); + } + + } + + boneMatrix = parentMatrix *(glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp)); + + m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix; + m_BoneTransforms[bone->ID] = boneMatrix; + } + + + + for (auto &child : bone->Children) { + AccumulateBoneTransforms(noRootMotion, animations, child, boneMatrix); + } +} glm::mat4 Skeleton::GetOffsetTransform(const Bone* bone, AnimationOffset animationOffset) { From a53ab7f74574e2bdd018563ded7a62d2a7357314 Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Wed, 10 Feb 2016 20:46:16 +0100 Subject: [PATCH 15/31] A few fixes for DashAbility. Default DoubleTapToDash is now set to false. --- .../Engine/Input/FirstPersonInputController.h | 25 +++++++++++-------- resources/DefaultInput.ini | 4 +-- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/include/Engine/Input/FirstPersonInputController.h b/include/Engine/Input/FirstPersonInputController.h index 2bbd768d..20402cd0 100644 --- a/include/Engine/Input/FirstPersonInputController.h +++ b/include/Engine/Input/FirstPersonInputController.h @@ -54,6 +54,7 @@ protected: //specialabilitys bool m_MovementKeyDown = false; bool m_SpecialAbilityKeyDown = false; + int m_NumberOfMovementKeysDown = 0; EventRelay m_ELockMouse; bool OnLockMouse(const Events::LockMouse& e); @@ -131,6 +132,7 @@ bool FirstPersonInputController::OnCommand(const Events::InputComm } //if value = 0 then you have just released this key if (e.Value != 0) { + m_NumberOfMovementKeysDown++; m_MovementKeyDown = true; //if you pressed the same key within m_AssaultDashDoubleTapSensitivityTimer then you have doubletapped it if (m_AssaultDashDoubleTapDeltaTime < m_AssaultDashDoubleTapSensitivityTimer && m_AssaultDashTapDirection == m_CurrentDirectionVector) { @@ -138,10 +140,14 @@ bool FirstPersonInputController::OnCommand(const Events::InputComm } } else { //== 0 - m_MovementKeyDown = false; - //you have just released the key, store what key it was and reset the doubletap-sensitivity-timer - m_AssaultDashTapDirection = m_CurrentDirectionVector; - m_AssaultDashDoubleTapDeltaTime = 0.f; + m_NumberOfMovementKeysDown--; + if (m_NumberOfMovementKeysDown == 0) { + m_MovementKeyDown = false; + } + //you have just released the key, store what key it was and reset the doubletap-sensitivity-timer + m_AssaultDashTapDirection = m_CurrentDirectionVector; + m_AssaultDashDoubleTapDeltaTime = 0.f; + } } @@ -201,12 +207,6 @@ void FirstPersonInputController::AssaultDashCheck(double dt, bool m_AssaultDashCoolDownTimer = assaultDashCoolDownMaxTimer; m_AssaultDashDoubleTapped = true; m_AssaultDashDoubleTapDeltaTime = 0.f; - //moving to the side has priority - return; - } - - //dashing with doubletap - check if doubletap to dash enabled - if (ResourceManager::Load("Input.ini")->Get("Keyboard.DoubleTapToDash", false)) { return; } @@ -215,6 +215,11 @@ void FirstPersonInputController::AssaultDashCheck(double dt, bool m_AssaultDashDoubleTapped = false; } + //dashing with doubletap - check if doubletap to dash enabled + if (!ResourceManager::Load("Input.ini")->Get("Keyboard.DoubleTapToDash", false)) { + return; + } + //check if we have received a valid doubletap if (!m_ValidDoubleTap) { return; diff --git a/resources/DefaultInput.ini b/resources/DefaultInput.ini index eb5b7658..35aceeb1 100644 --- a/resources/DefaultInput.ini +++ b/resources/DefaultInput.ini @@ -2,8 +2,8 @@ Sensitivity=0.5 InvertPitch=false -[KeyBoard] -DoubleTapToDash=true +[Keyboard] +DoubleTapToDash=false [Bindings] MouseLeft=PrimaryFire From f5de267f2552d3bc6ae8211fd2c77b6fe3862867 Mon Sep 17 00:00:00 2001 From: Tleety Date: Wed, 10 Feb 2016 20:58:10 +0100 Subject: [PATCH 16/31] Merge fixes and CapturePointHUD component skeleton added. --- include/Engine/Rendering/RawModelCustom.h | 2 +- include/Engine/Rendering/RenderQueue.h | 5 +- include/Engine/Rendering/SpriteJob.h | 8 +- resources/Schema/Components.xsd | 1 + .../Schema/Components/CapturePointHUD.xml | 2 + .../Schema/Components/CapturePointHUD.xsd | 6 + .../Schema/Entities/QualityAssurance.xml | 104 ++++++++++-------- resources/Schema/Types/Entity.xsd | 1 + src/Engine/Rendering/DrawFinalPass.cpp | 2 +- src/Engine/Rendering/Model.cpp | 47 ++------ src/Engine/Rendering/RenderSystem.cpp | 2 +- src/Engine/Rendering/Renderer.cpp | 2 +- 12 files changed, 87 insertions(+), 95 deletions(-) create mode 100644 resources/Schema/Components/CapturePointHUD.xml create mode 100644 resources/Schema/Components/CapturePointHUD.xsd diff --git a/include/Engine/Rendering/RawModelCustom.h b/include/Engine/Rendering/RawModelCustom.h index cf21fb6d..ebf8da2b 100644 --- a/include/Engine/Rendering/RawModelCustom.h +++ b/include/Engine/Rendering/RawModelCustom.h @@ -50,7 +50,7 @@ public: struct TextureProperties { std::string TexturePath; glm::vec2 UVRepeat; - std::shared_ptr<::Texture> Texture; + Texture* Texture; }; struct MaterialBasic diff --git a/include/Engine/Rendering/RenderQueue.h b/include/Engine/Rendering/RenderQueue.h index 21802e05..647adab8 100644 --- a/include/Engine/Rendering/RenderQueue.h +++ b/include/Engine/Rendering/RenderQueue.h @@ -26,8 +26,7 @@ struct RenderScene std::list> OpaqueShieldedObjects; std::list> TransparentShieldedObjects; std::list> ShieldObjects; - std::list> SpriteJobs; - + std::list> SpriteJob; std::list> PointLight; std::list> Text; std::list> DirectionalLight; @@ -44,7 +43,7 @@ struct RenderScene Jobs.OpaqueShieldedObjects.clear(); Jobs.TransparentShieldedObjects.clear(); Jobs.ShieldObjects.clear(); - SpriteJobs.clear(); + Jobs.SpriteJob.clear(); Jobs.DirectionalLight.clear(); } }; diff --git a/include/Engine/Rendering/SpriteJob.h b/include/Engine/Rendering/SpriteJob.h index 23bf6360..2708ab0e 100644 --- a/include/Engine/Rendering/SpriteJob.h +++ b/include/Engine/Rendering/SpriteJob.h @@ -21,15 +21,15 @@ struct SpriteJob : RenderJob : RenderJob() { Model = ResourceManager::Load<::Model>("Models/Core/UnitQuad.mesh"); - ::RawModel::MaterialGroup matGroup = Model->MaterialGroups().front(); - TextureID = (matGroup.Texture) ? matGroup.Texture->ResourceID : 0; + ::RawModel::MaterialProperties matProp = Model->MaterialGroups().front(); + TextureID = 0; DiffuseTexture = CommonFunctions::LoadTexture(cSprite["DiffuseTexture"], true); IncandescenceTexture = CommonFunctions::LoadTexture(cSprite["GlowMap"], true); - StartIndex = matGroup.StartIndex; - EndIndex = matGroup.EndIndex; + StartIndex = matProp.material->StartIndex; + EndIndex = matProp.material->EndIndex; Matrix = matrix; Color = cSprite["Color"]; Entity = cSprite.EntityID; diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index 9487a7ad..bcc3fbdf 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -37,4 +37,5 @@ + \ No newline at end of file diff --git a/resources/Schema/Components/CapturePointHUD.xml b/resources/Schema/Components/CapturePointHUD.xml new file mode 100644 index 00000000..c024411c --- /dev/null +++ b/resources/Schema/Components/CapturePointHUD.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/resources/Schema/Components/CapturePointHUD.xsd b/resources/Schema/Components/CapturePointHUD.xsd new file mode 100644 index 00000000..dfdef822 --- /dev/null +++ b/resources/Schema/Components/CapturePointHUD.xsd @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/resources/Schema/Entities/QualityAssurance.xml b/resources/Schema/Entities/QualityAssurance.xml index 7a69ed32..c234f93a 100644 --- a/resources/Schema/Entities/QualityAssurance.xml +++ b/resources/Schema/Entities/QualityAssurance.xml @@ -40,7 +40,7 @@ - + @@ -120,11 +120,7 @@ - - Run - - 1 - + Models/Characters/Assault/AssaultAnimated.mesh @@ -136,11 +132,7 @@ - - Walk - - 1 - + Models/Characters/Assault/AssaultAnimated.mesh @@ -188,17 +180,13 @@ - + - - Run - - 1 - + Models/Characters/Assault/AssaultAnimated.mesh @@ -683,7 +671,7 @@ - + @@ -730,7 +718,7 @@ - + @@ -790,7 +778,7 @@ - + @@ -837,7 +825,7 @@ - + @@ -883,7 +871,7 @@ - + @@ -930,7 +918,7 @@ - + @@ -977,7 +965,7 @@ - + @@ -1390,7 +1378,7 @@ - + @@ -1399,7 +1387,7 @@ true - 0.75102457088592522 + 0.75134174339666815 3.7999999523162842 true @@ -1446,7 +1434,7 @@ - + @@ -1455,7 +1443,7 @@ - 1.2009303215000324 + 1.2012474940107754 Models/Characters/Assault/AssaultTPose.mesh @@ -1498,22 +1486,18 @@ - + - - Walk - - 1 - + true - 0.68437610515996361 + 0.68469327767070653 true @@ -1558,7 +1542,7 @@ - + @@ -1568,7 +1552,7 @@ true - 0.95047462600732735 + 0.95079179851807027 10 3 @@ -1616,7 +1600,7 @@ - + @@ -1626,7 +1610,7 @@ true - 1.350502887383392 + 1.3508200598941349 true 5 true @@ -1807,7 +1791,7 @@ true - 1.3671759474185377 + 1.3674931199292806 3.7999999523162842 true @@ -1850,11 +1834,7 @@ - - Hold Pos - - 1 - + Models/AssaultAnimated.mesh @@ -1916,7 +1896,8 @@ - Models/BushAlive.mesh + Models/Props/Flora/AliveBush.mesh + true @@ -1943,6 +1924,37 @@ + + + + + + + + + + + + Textures/Props/FoliageDiff.png + + + + + + + + + + Textures/Props/FoliageDiff.png + + + + + + + + + diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index 16366a67..8c9f6bcc 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -41,6 +41,7 @@ + diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 2e1e717e..e5e046dc 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -193,7 +193,7 @@ void DrawFinalPass::Draw(RenderScene& scene) GLERROR("OpaqueObjects"); DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene); GLERROR("TransparentObjects"); - DrawSprites(scene.SpriteJobs, scene); + DrawSprites(scene.Jobs.SpriteJob, scene); GLERROR("SpriteJobs"); //DrawStencilState* stencilState = new DrawStencilState(m_FinalPassFrameBuffer.GetHandle()); diff --git a/src/Engine/Rendering/Model.cpp b/src/Engine/Rendering/Model.cpp index 009e4abe..ce6eab8c 100644 --- a/src/Engine/Rendering/Model.cpp +++ b/src/Engine/Rendering/Model.cpp @@ -10,60 +10,31 @@ Model::Model(std::string fileName) case RawModel::MaterialType::SingleTextures: { RawModel::MaterialSingleTextures* materialSingleTexture = static_cast(materialProperty.material); - if (!materialSingleTexture->ColorMap.TexturePath.empty()) { - materialSingleTexture->ColorMap.Texture = std::shared_ptr(ResourceManager::LoadfixTexture>(materialSingleTexture->ColorMap.TexturePath)); - } - if (!materialSingleTexture->NormalMap.TexturePath.empty()) { - materialSingleTexture->NormalMap.Texture = std::shared_ptr(ResourceManager::LoadfixTexture>(materialSingleTexture->NormalMap.TexturePath)); - } - if (!materialSingleTexture->SpecularMap.TexturePath.empty()) { - materialSingleTexture->SpecularMap.Texture = std::shared_ptr(ResourceManager::LoadfixTexture>(materialSingleTexture->SpecularMap.TexturePath)); - } - if (!materialSingleTexture->IncandescenceMap.TexturePath.empty()) { - materialSingleTexture->IncandescenceMap.Texture = std::shared_ptr(ResourceManager::LoadfixTexture>(materialSingleTexture->IncandescenceMap.TexturePath)); - } + materialSingleTexture->ColorMap.Texture = CommonFunctions::LoadTexture(materialSingleTexture->ColorMap.TexturePath, false); + materialSingleTexture->NormalMap.Texture = CommonFunctions::LoadTexture(materialSingleTexture->NormalMap.TexturePath, false); + materialSingleTexture->SpecularMap.Texture = CommonFunctions::LoadTexture(materialSingleTexture->SpecularMap.TexturePath, false); + materialSingleTexture->IncandescenceMap.Texture = CommonFunctions::LoadTexture(materialSingleTexture->IncandescenceMap.TexturePath, false); } break; case RawModel::MaterialType::SplatMapping: { RawModel::MaterialSplatMapping* materialSplatMapping = static_cast(materialProperty.material); - if (!materialSplatMapping->SplatMap.TexturePath.empty()) { - materialSplatMapping->SplatMap.Texture = std::shared_ptr(ResourceManager::Load(materialSplatMapping->SplatMap.TexturePath)); - } + materialSplatMapping->SplatMap.Texture = CommonFunctions::LoadTexture(materialSplatMapping->SplatMap.TexturePath, false); for (auto& texture : materialSplatMapping->ColorMaps) { - if (!texture.TexturePath.empty()) { - texture.Texture = std::shared_ptr(ResourceManager::Load(texture.TexturePath)); - } - else { - texture.Texture = nullptr; - } + texture.Texture = CommonFunctions::LoadTexture(texture.TexturePath, false); } for (auto& texture : materialSplatMapping->NormalMaps) { - if (!texture.TexturePath.empty()) { - texture.Texture = std::shared_ptr(ResourceManager::Load(texture.TexturePath)); - } else { - texture.Texture = nullptr; - } + texture.Texture = CommonFunctions::LoadTexture(texture.TexturePath, false); } for (auto& texture : materialSplatMapping->SpecularMaps) { - if (!texture.TexturePath.empty()) { - texture.Texture = std::shared_ptr(ResourceManager::Load(texture.TexturePath)); - } - else { - texture.Texture = nullptr; - } + texture.Texture = CommonFunctions::LoadTexture(texture.TexturePath, false); } for (auto& texture : materialSplatMapping->IncandescenceMaps) { - if (!texture.TexturePath.empty()) { - texture.Texture = std::shared_ptr(ResourceManager::Load(texture.TexturePath)); - } - else { - texture.Texture = nullptr; - } + texture.Texture = CommonFunctions::LoadTexture(texture.TexturePath, false); } } break; diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index eb81818e..173afc95 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -346,7 +346,7 @@ void RenderSystem::Update(double dt) fillPointLights(scene.Jobs.PointLight, m_World); //TODO: Make sure all objects needed are also sorted. scene.Jobs.OpaqueObjects.sort(); - fillSprites(scene.SpriteJobs, m_World); + fillSprites(scene.Jobs.SpriteJob, m_World); fillDirectionalLights(scene.Jobs.DirectionalLight, m_World); fillText(scene.Jobs.Text, m_World); m_RenderFrame->Add(scene); diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index f02ca4d5..6f53eeda 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -167,7 +167,7 @@ void Renderer::SortRenderJobsByDepth(RenderScene &scene) { //Sort all forward jobs so transparency is good. scene.Jobs.TransparentObjects.sort(Renderer::DepthSort); - scene.SpriteJobs.sort(Renderer::DepthSort); + scene.Jobs.SpriteJob.sort(Renderer::DepthSort); } void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) From 64a2354b24ee1e0304d00831e967ca12b4ad944c Mon Sep 17 00:00:00 2001 From: Tleety Date: Wed, 10 Feb 2016 22:22:09 +0100 Subject: [PATCH 17/31] WIP with CapturePointHUDSystem --- include/Game/Systems/CapturePointHUDSystem.h | 55 ++++ resources/Schema/Components.xsd | 2 +- .../Schema/Components/CapturePointHUD.xml | 5 +- .../Schema/Components/CapturePointHUD.xsd | 18 ++ .../Entities/CapturePointHUDHexagon.xml | 34 +++ .../Schema/Entities/QualityAssurance.xml | 208 +++++++++++++-- src/Game/Systems/CapturePointHUDSystem.cpp | 243 ++++++++++++++++++ 7 files changed, 542 insertions(+), 23 deletions(-) create mode 100644 include/Game/Systems/CapturePointHUDSystem.h create mode 100644 resources/Schema/Entities/CapturePointHUDHexagon.xml create mode 100644 src/Game/Systems/CapturePointHUDSystem.cpp diff --git a/include/Game/Systems/CapturePointHUDSystem.h b/include/Game/Systems/CapturePointHUDSystem.h new file mode 100644 index 00000000..18c32c76 --- /dev/null +++ b/include/Game/Systems/CapturePointHUDSystem.h @@ -0,0 +1,55 @@ +#ifndef CapturePointSystem_h__ +#define CapturePointSystem_h__ + +#include +#include + +#include "Common.h" +#include "Core/System.h" +#include "Engine/Collision/ETrigger.h" +#include "Core/ECaptured.h" +#include "Core/EWin.h" + +#include +#include + +class CapturePointSystem : public PureSystem +{ +public: + //WARNING: on new map, destroy all info in the vectors, as well as reset all variables (just make new?) + CapturePointSystem(World* world, EventBroker* eventBroker); + + //updatecomponent + virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& capturePoint, double dt) override; + +private: + //methods which will take care of specific events + EventRelay m_ETriggerTouch; + bool CapturePointSystem::OnTriggerTouch(const Events::TriggerTouch& e); + EventRelay m_ETriggerLeave; + bool CapturePointSystem::OnTriggerLeave(const Events::TriggerLeave& e); + EventRelay m_ECaptured; + bool CapturePointSystem::OnCaptured(const Events::Captured& e); + + bool m_WinnerWasFound = false; + //need to track these variables for the captureSystem to work as per design! + const int m_NotACapturePoint = 999; + int m_RedTeamNextPossibleCapturePoint = m_NotACapturePoint; + int m_BlueTeamNextPossibleCapturePoint = m_NotACapturePoint; + int m_RedTeamHomeCapturePoint = m_NotACapturePoint; + int m_BlueTeamHomeCapturePoint = m_NotACapturePoint; + + int m_NumberOfCapturePoints = 0; + std::map m_CapturePointNumberToEntityMap; + + //std::vector + + const double m_CaptureTimeToTakeOver = 15.0; + bool m_ResetTimers = false; + + //vectors which will keep track of enter/leave changes + std::vector> m_ETriggerTouchVector; + std::vector> m_ETriggerLeaveVector; +}; + +#endif \ No newline at end of file diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index bcc3fbdf..bf452eba 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -37,5 +37,5 @@ - + \ No newline at end of file diff --git a/resources/Schema/Components/CapturePointHUD.xml b/resources/Schema/Components/CapturePointHUD.xml index c024411c..2943d57b 100644 --- a/resources/Schema/Components/CapturePointHUD.xml +++ b/resources/Schema/Components/CapturePointHUD.xml @@ -1,2 +1,5 @@ - \ No newline at end of file + + 0 + + \ No newline at end of file diff --git a/resources/Schema/Components/CapturePointHUD.xsd b/resources/Schema/Components/CapturePointHUD.xsd index dfdef822..7984fc50 100644 --- a/resources/Schema/Components/CapturePointHUD.xsd +++ b/resources/Schema/Components/CapturePointHUD.xsd @@ -1,6 +1,24 @@ + + + Hud element for tracking capture points. + + + + + + Corresponds to the number on the capture point it should track. + + + + + Specify the team that own this capturePoint. + + + + \ No newline at end of file diff --git a/resources/Schema/Entities/CapturePointHUDHexagon.xml b/resources/Schema/Entities/CapturePointHUDHexagon.xml new file mode 100644 index 00000000..68cf42a7 --- /dev/null +++ b/resources/Schema/Entities/CapturePointHUDHexagon.xml @@ -0,0 +1,34 @@ + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + + 0.5 + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + diff --git a/resources/Schema/Entities/QualityAssurance.xml b/resources/Schema/Entities/QualityAssurance.xml index c234f93a..ce6a650e 100644 --- a/resources/Schema/Entities/QualityAssurance.xml +++ b/resources/Schema/Entities/QualityAssurance.xml @@ -40,7 +40,7 @@ - + @@ -180,7 +180,7 @@ - + @@ -671,7 +671,7 @@ - + @@ -718,7 +718,7 @@ - + @@ -778,7 +778,7 @@ - + @@ -825,7 +825,7 @@ - + @@ -871,7 +871,7 @@ - + @@ -918,7 +918,7 @@ - + @@ -965,7 +965,7 @@ - + @@ -1378,7 +1378,7 @@ - + @@ -1387,7 +1387,7 @@ true - 0.75134174339666815 + 0.75158864645285173 3.7999999523162842 true @@ -1434,7 +1434,7 @@ - + @@ -1443,7 +1443,7 @@ - 1.2012474940107754 + 1.2014943970669589 Models/Characters/Assault/AssaultTPose.mesh @@ -1486,7 +1486,7 @@ - + @@ -1497,7 +1497,7 @@ true - 0.68469327767070653 + 0.68494018072689011 true @@ -1542,7 +1542,7 @@ - + @@ -1552,7 +1552,7 @@ true - 0.95079179851807027 + 0.95103870157425385 10 3 @@ -1600,7 +1600,7 @@ - + @@ -1610,7 +1610,7 @@ true - 1.3508200598941349 + 1.3510669629503185 true 5 true @@ -1791,7 +1791,7 @@ true - 1.3674931199292806 + 1.3677400229854642 3.7999999523162842 true @@ -1936,7 +1936,6 @@ Textures/Props/FoliageDiff.png - @@ -1955,6 +1954,173 @@ + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 2 + + + 0.5 + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 3 + + + 0.5 + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 4 + + + 0.5 + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 1 + + + 0.5 + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + 0.5 + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + diff --git a/src/Game/Systems/CapturePointHUDSystem.cpp b/src/Game/Systems/CapturePointHUDSystem.cpp new file mode 100644 index 00000000..a943e234 --- /dev/null +++ b/src/Game/Systems/CapturePointHUDSystem.cpp @@ -0,0 +1,243 @@ +#include "Systems/CapturePointSystem.h" +#include + +CapturePointSystem::CapturePointSystem(World* world, EventBroker* eventBroker) + : System(world, eventBroker) + , PureSystem("CapturePoint") +{ + //subscribe/listenTo playerdamage,healthpickup events (using the eventBroker) + EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &CapturePointSystem::OnTriggerTouch); + EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &CapturePointSystem::OnTriggerLeave); + EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &CapturePointSystem::OnCaptured); +} + +//here all capturepoints will update their component +//NOTE: needs to run each frame, since we're possibly modifying the captureTimer for the capturePoints by dt +void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, ComponentWrapper& cCapturePoint, double dt) +{ + if (m_WinnerWasFound) { + return; + } + const int capturePointNumber = cCapturePoint["CapturePointNumber"]; + const bool hasTeamComponent = capturePointEntity.HasComponent("Team"); + + //if point doesnt have a teamComponent yet, add one. since: + //what if capture point has no team -> we cant get/use the team enum from it... + if (!hasTeamComponent) { + m_World->AttachComponent(cCapturePoint.EntityID, "Team"); + ComponentWrapper& teamComponent = capturePointEntity["Team"]; + teamComponent["Team"] = (int)teamComponent["Team"].Enum("Spectator"); + } + ComponentWrapper& teamComponent = capturePointEntity["Team"]; + const int redTeam = (int)teamComponent["Team"].Enum("Red"); + const int blueTeam = (int)teamComponent["Team"].Enum("Blue"); + const int spectatorTeam = (int)teamComponent["Team"].Enum("Spectator"); + + int homePointForTeam = (int)cCapturePoint["HomePointForTeam"]; + if (m_NumberOfCapturePoints == 0 && capturePointNumber != 0 && (homePointForTeam == redTeam || homePointForTeam == blueTeam)) { + m_NumberOfCapturePoints = capturePointNumber + 1;//ex 2 -> 0,1,2 = 3 + if (homePointForTeam == redTeam) { + m_RedTeamHomeCapturePoint = capturePointNumber; + m_BlueTeamHomeCapturePoint = 0; + } else { + m_BlueTeamHomeCapturePoint = capturePointNumber; + m_RedTeamHomeCapturePoint = 0; + } + } + + //if we havent received all capturepoints yet, just return + if (m_NumberOfCapturePoints == 0 || m_NumberOfCapturePoints != m_CapturePointNumberToEntityMap.size()) { + m_CapturePointNumberToEntityMap.insert(std::make_pair(capturePointNumber, capturePointEntity)); + return; + } + + //we have all capturepoints now - process stuff + int ownedBy = teamComponent["Team"]; + int redTeamPlayersStandingInside = 0; + int blueTeamPlayersStandingInside = 0; + if (capturePointEntity.HasComponent("Model")) { + //Now sets team color to the capturepoint, or white if it is uncaptured. + capturePointEntity["Model"]["Color"] = ownedBy == blueTeam ? glm::vec4(0, 0.2f, 1, 0.3) : ownedBy == redTeam ? glm::vec4(1, 0.2f, 0, 0.3) : glm::vec4(1, 1, 1, 0.3); + } + + //calculate next possible capturePoint for both teams + std::map nextPossibleCapturePoint; + nextPossibleCapturePoint["Red"] = -1; + nextPossibleCapturePoint["Blue"] = -1; + for (int i = 0; i < m_NumberOfCapturePoints; i++) + { + if (!m_CapturePointNumberToEntityMap[i].HasComponent("Team")) { + continue; + } + ComponentWrapper& capturePointOwnedBy = m_CapturePointNumberToEntityMap[i]["Team"]; + if ((int)capturePointOwnedBy["Team"] == redTeam && m_RedTeamHomeCapturePoint == 0) { + nextPossibleCapturePoint["Red"] = i + 1; + } + if ((int)capturePointOwnedBy["Team"] == blueTeam && m_BlueTeamHomeCapturePoint == 0) { + nextPossibleCapturePoint["Blue"] = i + 1; + } + } + for (int i = m_NumberOfCapturePoints - 1; i >= 0; i--) + { + if (!m_CapturePointNumberToEntityMap[i].HasComponent("Team")) { + continue; + } + ComponentWrapper& capturePointOwnedBy = m_CapturePointNumberToEntityMap[i]["Team"]; + if ((int)capturePointOwnedBy["Team"] == redTeam && m_RedTeamHomeCapturePoint != 0) { + nextPossibleCapturePoint["Red"] = i - 1; + } + if ((int)capturePointOwnedBy["Team"] == blueTeam && m_BlueTeamHomeCapturePoint != 0) { + nextPossibleCapturePoint["Blue"] = i - 1; + } + } + + //reset timers and reset the bool that triggers this + if (m_ResetTimers) { + for (int i = 0; i < m_NumberOfCapturePoints; i++) + { + ComponentWrapper& capturePoint = m_CapturePointNumberToEntityMap[i]["CapturePoint"]; + if ((int)capturePoint["CapturePointNumber"] != nextPossibleCapturePoint["Red"] && + (int)capturePoint["CapturePointNumber"] != nextPossibleCapturePoint["Blue"]) { + capturePoint["CaptureTimer"] = 0.0; + } + } + m_ResetTimers = false; + } + + //colorize next possible capturepoint + if (nextPossibleCapturePoint["Red"] == capturePointNumber) { + capturePointEntity["Model"]["Color"] = glm::vec4(1, 1, 0, 0.3); + } + if (nextPossibleCapturePoint["Blue"] == capturePointNumber) { + capturePointEntity["Model"]["Color"] = glm::vec4(0, 1, 1, 0.3); + } + + //check how many players are standing inside and are healthy + for (size_t i = m_ETriggerTouchVector.size(); i > 0; i--) + { + auto triggerTouched = m_ETriggerTouchVector[i - 1]; + if (std::get<1>(triggerTouched) == capturePointEntity) { + //some player has touched this - lets figure out: what team, health + EntityWrapper player = std::get<0>(triggerTouched); + //check if its really a player that has triggered the touch + if (!player.HasComponent("Player")) { + //if a non-player has entered the capturePoint, just erase that event and continue + m_ETriggerTouchVector.erase(m_ETriggerTouchVector.begin() + i - 1); + continue; + } + bool hasHealthComponent = player.HasComponent("Health"); + if (hasHealthComponent) { + double currentHealth = player["Health"]["Health"]; + //check if player is dead + if ((int)currentHealth == 0) { + continue; + } + } + //check team - spectatorNumber = "no team" + int teamNumber = player["Team"]["Team"]; + if (teamNumber == redTeam) { + redTeamPlayersStandingInside++; + } else if (teamNumber == blueTeam) { + blueTeamPlayersStandingInside++; + } + continue; + } + } + + //create data to be used in option B + //check so this is the next possible capture point for the take-over team and see if only one team is standing inside it + double timerDeltaChange = 0.0; + int currentTeam = 0; + bool canCapture = false; + if (redTeamPlayersStandingInside > 0 && blueTeamPlayersStandingInside == 0) { + timerDeltaChange = redTeamPlayersStandingInside*dt; + currentTeam = redTeam; + canCapture = nextPossibleCapturePoint["Red"] == capturePointNumber; + } + if (redTeamPlayersStandingInside == 0 && blueTeamPlayersStandingInside > 0) { + timerDeltaChange = -blueTeamPlayersStandingInside*dt; + currentTeam = blueTeam; + canCapture = nextPossibleCapturePoint["Blue"] == capturePointNumber; + } + + if (redTeamPlayersStandingInside == 0 && blueTeamPlayersStandingInside == 0) { + //A.nobodys standing inside + //do nothing (?) + } else if (redTeamPlayersStandingInside > 0 && blueTeamPlayersStandingInside > 0) { + //C.both teams have players inside + //do nothing (?) + } else { + //B. at most one of the teams have players inside + //if capturePoint is not owned by the take-over team, just modify the CaptureTimer accordingly + if (ownedBy != currentTeam && canCapture) { + if (abs((double)cCapturePoint["CaptureTimer"]) < 0.001f) { + LOG_DEBUG("Point is being captured by team %i", currentTeam); //Remove when we tested sufficiently. + } + cCapturePoint["CaptureTimer"] = (double)cCapturePoint["CaptureTimer"] + timerDeltaChange; + } + //if capturePoint is owned by the team, and the other team has been trying to take it, then increase/decrease the timer towards 0.0 + if ((ownedBy == currentTeam && currentTeam == redTeam && (double)cCapturePoint["CaptureTimer"] < 0.0) || + (ownedBy == currentTeam && currentTeam == blueTeam && (double)cCapturePoint["CaptureTimer"] > 0.0)) { + cCapturePoint["CaptureTimer"] = (double)cCapturePoint["CaptureTimer"] + timerDeltaChange; + } + //check if captureTimer > m_CaptureTimeToTakeOver and if so change owner and publish the eCaptured event + if (abs((double)cCapturePoint["CaptureTimer"]) > abs(m_CaptureTimeToTakeOver) && canCapture) { + teamComponent["Team"] = currentTeam; + cCapturePoint["CaptureTimer"] = 0.0; + //publish Captured event + LOG_DEBUG("Point is captured by team %i!", currentTeam); //Remove when we tested sufficiently. + Events::Captured e; + e.CapturePointID = cCapturePoint.EntityID; + e.TeamNumberThatCapturedCapturePoint = currentTeam; + m_EventBroker->Publish(e); + //NextPossibleCapturePoint will be calculated in the next update... + } + } + + //check for possible winCondition = check if the homebase is owned by the other team + bool checkForWinner = false; + if (capturePointNumber == m_RedTeamHomeCapturePoint && ownedBy != redTeam) + { + checkForWinner = true; + } + if (capturePointNumber == m_BlueTeamHomeCapturePoint && ownedBy != blueTeam) + { + checkForWinner = true; + } + + if (checkForWinner && !m_WinnerWasFound) + { + //publish Win event + Events::Win e; + e.TeamThatWon = ownedBy; + m_EventBroker->Publish(e); + m_WinnerWasFound = true; + } + +} + +bool CapturePointSystem::OnTriggerTouch(const Events::TriggerTouch& e) +{ + //personEntered = e.Entity, thingEntered = e.Trigger + m_ETriggerTouchVector.push_back(std::make_tuple(e.Entity, e.Trigger)); + return true; +} + +bool CapturePointSystem::OnTriggerLeave(const Events::TriggerLeave& e) +{ + for (size_t i = 0; i < m_ETriggerTouchVector.size(); i++) + { + auto triggerTouched = m_ETriggerTouchVector[i]; + if (std::get<0>(triggerTouched) == e.Entity && std::get<1>(triggerTouched) == e.Trigger) { + m_ETriggerTouchVector.erase(m_ETriggerTouchVector.begin() + i); + break; + } + } + return true; +} +bool CapturePointSystem::OnCaptured(const Events::Captured& e) +{ + //reset the timers in the next update since a capture has changed the "nextCapturePoint" for 1-2 teams + m_ResetTimers = true; + return true; +} From dded296cde37d3815688eea7a3ccd9942048c9fb Mon Sep 17 00:00:00 2001 From: viktorljung Date: Wed, 10 Feb 2016 23:19:44 +0100 Subject: [PATCH 18/31] Animation looping fix --- assets | 2 +- resources/Schema/Entities/AnimationTests2.xml | 505 +----------------- src/Engine/Rendering/AnimationSystem.cpp | 2 - src/Engine/Rendering/Skeleton.cpp | 4 + 4 files changed, 20 insertions(+), 493 deletions(-) diff --git a/assets b/assets index 45cbc3ab..172b3ad5 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 45cbc3abaebe5f815e2c1b58bcf884d4953a4c52 +Subproject commit 172b3ad527fc14aa6175fa72580a66a00f04e0ba diff --git a/resources/Schema/Entities/AnimationTests2.xml b/resources/Schema/Entities/AnimationTests2.xml index 09573ac7..6536a839 100644 --- a/resources/Schema/Entities/AnimationTests2.xml +++ b/resources/Schema/Entities/AnimationTests2.xml @@ -55,498 +55,23 @@ - + - + + R_Arm_Weapon_Joint + + + + Models/Weapons/Blue/AssaultWeapon.mesh + + true + + + + + - - - - - R_Arm_Weapon_Joint - - - - Models/Weapons/Blue/AssaultWeapon.mesh - - true - - - - - - - - - - - - R_Hand - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - R_Arm - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - R_Shoulder - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - Neck - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - Spine_3 - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - Spine_2 - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - Spine_1 - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - Hip - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - L_Leg_Top - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - L_Leg_Bottom - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - L_Foot - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - L_Toe - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - L_Shoulder - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - L_Arm - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - L_Hand - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - L_Shoulder_Armor_Joint - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - Chin - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - Head - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - Perietal - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - L_Elbow - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - R_Leg_Bottom - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - R_Elbow - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - R_Leg_Top - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - R_Foot - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - R_Toe - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - R_Shoulder_Armor_Joint - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - + diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index 25813a63..3df502c4 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -13,9 +13,7 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a return; } - Skeleton* skeleton = model->m_RawModel->m_Skeleton; - if(skeleton == nullptr) { return; } diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index 1aabd84c..5da95558 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -96,6 +96,7 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vectorDuration - currentFrame.Time); } else { progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); @@ -227,6 +228,7 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vectorDuration - currentFrame.Time); } else { progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); @@ -347,6 +349,7 @@ glm::mat4 Skeleton::GetOffsetTransform(const Bone* bone, AnimationOffset animati float progress; if (nextFrame.Index == 0) { + nextFrame = currentFrame; progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time); } else { progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); @@ -400,6 +403,7 @@ glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation* animatio float progress; if (nextFrame.Index == 0) { + nextFrame = currentFrame; progress = (time - currentFrame.Time) / (animation->Duration - currentFrame.Time); } else { progress = (time - currentFrame.Time) / (nextFrame.Time - currentFrame.Time); From 9c08c351b80197fd485e438b175a8293e681686d Mon Sep 17 00:00:00 2001 From: viktorljung Date: Wed, 10 Feb 2016 23:33:23 +0100 Subject: [PATCH 19/31] fixed reverse Animation looping --- src/Engine/Rendering/AnimationSystem.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index 3df502c4..48681e6e 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -31,20 +31,27 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a double nextTime = (double)animationComponent["Time" + std::to_string(i)] + animationSpeed * dt; - if (!(bool)animationComponent["Loop" + std::to_string(i)] && glm::abs(nextTime) > animation->Duration) { - (double&)animationComponent["Time" + std::to_string(i)] = glm::sign(nextTime) * animation->Duration; + if (!(bool)animationComponent["Loop" + std::to_string(i)]) { + if (nextTime > animation->Duration) { + nextTime = animation->Duration; + } else if (nextTime < 0) { + nextTime = 0; + } + (double&)animationComponent["Speed" + std::to_string(i)] = 0.0; Events::AnimationComplete e; e.Entity = entity; e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)]; m_EventBroker->Publish(e); } else { - if (glm::abs(nextTime) > animation->Duration) { - (double&)animationComponent["Time" + std::to_string(i)] = glm::abs(nextTime) - animation->Duration; - } else { - (double&)animationComponent["Time" + std::to_string(i)] = nextTime; + if (nextTime > animation->Duration) { + nextTime -= animation->Duration; + } else if (nextTime < 0) { + nextTime += animation->Duration; } } + + (double&)animationComponent["Time" + std::to_string(i)] = nextTime; } } From 447f41dbff935c9521a2e74c594d85b1490b6cd9 Mon Sep 17 00:00:00 2001 From: Tleety Date: Wed, 10 Feb 2016 23:59:13 +0100 Subject: [PATCH 20/31] HUD for capture points now update with Capture point data. --- include/Game/Systems/CapturePointHUDSystem.h | 52 +- resources/Shaders/Sprite.frag.glsl | 5 +- src/Game/Game.cpp | 2 + src/Game/Systems/CapturePointHUDSystem.cpp | 482 ++++++++++--------- 4 files changed, 287 insertions(+), 254 deletions(-) diff --git a/include/Game/Systems/CapturePointHUDSystem.h b/include/Game/Systems/CapturePointHUDSystem.h index 18c32c76..102c52ce 100644 --- a/include/Game/Systems/CapturePointHUDSystem.h +++ b/include/Game/Systems/CapturePointHUDSystem.h @@ -1,55 +1,49 @@ -#ifndef CapturePointSystem_h__ -#define CapturePointSystem_h__ +#ifndef CapturePointHUDSystem_h__ +#define CapturePointHUDSystem_h__ #include #include +#include #include "Common.h" #include "Core/System.h" #include "Engine/Collision/ETrigger.h" -#include "Core/ECaptured.h" -#include "Core/EWin.h" -#include -#include - -class CapturePointSystem : public PureSystem +class CapturePointHUDSystem : public ImpureSystem { public: - //WARNING: on new map, destroy all info in the vectors, as well as reset all variables (just make new?) - CapturePointSystem(World* world, EventBroker* eventBroker); + CapturePointHUDSystem(World* world, EventBroker* eventBroker); - //updatecomponent - virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& capturePoint, double dt) override; + virtual void Update(double dt) override; private: //methods which will take care of specific events - EventRelay m_ETriggerTouch; + /* EventRelay m_ETriggerTouch; bool CapturePointSystem::OnTriggerTouch(const Events::TriggerTouch& e); EventRelay m_ETriggerLeave; bool CapturePointSystem::OnTriggerLeave(const Events::TriggerLeave& e); EventRelay m_ECaptured; - bool CapturePointSystem::OnCaptured(const Events::Captured& e); + bool CapturePointSystem::OnCaptured(const Events::Captured& e);*/ - bool m_WinnerWasFound = false; - //need to track these variables for the captureSystem to work as per design! - const int m_NotACapturePoint = 999; - int m_RedTeamNextPossibleCapturePoint = m_NotACapturePoint; - int m_BlueTeamNextPossibleCapturePoint = m_NotACapturePoint; - int m_RedTeamHomeCapturePoint = m_NotACapturePoint; - int m_BlueTeamHomeCapturePoint = m_NotACapturePoint; + //bool m_WinnerWasFound = false; + ////need to track these variables for the captureSystem to work as per design! + //const int m_NotACapturePoint = 999; + //int m_RedTeamNextPossibleCapturePoint = m_NotACapturePoint; + //int m_BlueTeamNextPossibleCapturePoint = m_NotACapturePoint; + //int m_RedTeamHomeCapturePoint = m_NotACapturePoint; + //int m_BlueTeamHomeCapturePoint = m_NotACapturePoint; - int m_NumberOfCapturePoints = 0; - std::map m_CapturePointNumberToEntityMap; + //int m_NumberOfCapturePoints = 0; + //std::map m_CapturePointNumberToEntityMap; - //std::vector + ////std::vector - const double m_CaptureTimeToTakeOver = 15.0; - bool m_ResetTimers = false; + //const double m_CaptureTimeToTakeOver = 15.0; + //bool m_ResetTimers = false; - //vectors which will keep track of enter/leave changes - std::vector> m_ETriggerTouchVector; - std::vector> m_ETriggerLeaveVector; + ////vectors which will keep track of enter/leave changes + //std::vector> m_ETriggerTouchVector; + //std::vector> m_ETriggerLeaveVector; }; #endif \ No newline at end of file diff --git a/resources/Shaders/Sprite.frag.glsl b/resources/Shaders/Sprite.frag.glsl index c391322d..a1ff3025 100644 --- a/resources/Shaders/Sprite.frag.glsl +++ b/resources/Shaders/Sprite.frag.glsl @@ -30,12 +30,11 @@ void main() float pos = ((P * vec4(Input.Position, 1)).y + 1.0)/2.0; if(pos <= FillPercentage) { - color_result += FillColor; + color_result = FillColor*diffuseTexel.a; } sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1)); - color_result += glowTexel*3; - bloomColor = vec4(clamp(color_result.xyz - 1.0, 0, 100), 1.0); + bloomColor = vec4(clamp((glowTexel.xyz*3) - 1.0, 0, 100), 1.0); } diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 002efe26..b13cbda2 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -12,6 +12,7 @@ #include "Systems/PlayerDeathSystem.h" #include "Core/EntityFileWriter.h" #include "Game/Systems/CapturePointSystem.h" +#include "Game/Systems/CapturePointHUDSystem.h" #include "Game/Systems/PickupSpawnSystem.h" #include "Game/Systems/WeaponSystem.h" #include "Rendering/AnimationSystem.h" @@ -103,6 +104,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); // Populate Octree with collidables ++updateOrderLevel; diff --git a/src/Game/Systems/CapturePointHUDSystem.cpp b/src/Game/Systems/CapturePointHUDSystem.cpp index a943e234..5c4c2b60 100644 --- a/src/Game/Systems/CapturePointHUDSystem.cpp +++ b/src/Game/Systems/CapturePointHUDSystem.cpp @@ -1,243 +1,281 @@ -#include "Systems/CapturePointSystem.h" -#include +#include "Systems/CapturePointHUDSystem.h" -CapturePointSystem::CapturePointSystem(World* world, EventBroker* eventBroker) +CapturePointHUDSystem::CapturePointHUDSystem(World* world, EventBroker* eventBroker) : System(world, eventBroker) - , PureSystem("CapturePoint") + , ImpureSystem() { //subscribe/listenTo playerdamage,healthpickup events (using the eventBroker) - EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &CapturePointSystem::OnTriggerTouch); - EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &CapturePointSystem::OnTriggerLeave); - EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &CapturePointSystem::OnCaptured); + //EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &CapturePointSystem::OnTriggerTouch); + //EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &CapturePointSystem::OnTriggerLeave); + //EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &CapturePointSystem::OnCaptured); } -//here all capturepoints will update their component -//NOTE: needs to run each frame, since we're possibly modifying the captureTimer for the capturePoints by dt -void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, ComponentWrapper& cCapturePoint, double dt) + +void CapturePointHUDSystem::Update(double dt) { - if (m_WinnerWasFound) { - return; - } - const int capturePointNumber = cCapturePoint["CapturePointNumber"]; - const bool hasTeamComponent = capturePointEntity.HasComponent("Team"); + bool LoadCheck = false; + int redTeam; + int blueTeam; + int spectatorTeam; - //if point doesnt have a teamComponent yet, add one. since: - //what if capture point has no team -> we cant get/use the team enum from it... - if (!hasTeamComponent) { - m_World->AttachComponent(cCapturePoint.EntityID, "Team"); - ComponentWrapper& teamComponent = capturePointEntity["Team"]; - teamComponent["Team"] = (int)teamComponent["Team"].Enum("Spectator"); - } - ComponentWrapper& teamComponent = capturePointEntity["Team"]; - const int redTeam = (int)teamComponent["Team"].Enum("Red"); - const int blueTeam = (int)teamComponent["Team"].Enum("Blue"); - const int spectatorTeam = (int)teamComponent["Team"].Enum("Spectator"); + auto CapturePointHUDElements = m_World->GetComponents("CapturePointHUD"); + auto CapturePoints = m_World->GetComponents("CapturePoint"); - int homePointForTeam = (int)cCapturePoint["HomePointForTeam"]; - if (m_NumberOfCapturePoints == 0 && capturePointNumber != 0 && (homePointForTeam == redTeam || homePointForTeam == blueTeam)) { - m_NumberOfCapturePoints = capturePointNumber + 1;//ex 2 -> 0,1,2 = 3 - if (homePointForTeam == redTeam) { - m_RedTeamHomeCapturePoint = capturePointNumber; - m_BlueTeamHomeCapturePoint = 0; - } else { - m_BlueTeamHomeCapturePoint = capturePointNumber; - m_RedTeamHomeCapturePoint = 0; - } - } + for(auto& cCapturePointHUD : *CapturePointHUDElements) { + int HUD_ID = cCapturePointHUD["CapturePointNumber"]; + EntityWrapper entityHUD = EntityWrapper(m_World, cCapturePointHUD.EntityID); + EntityWrapper entityHUDparent = entityHUD.Parent(); - //if we havent received all capturepoints yet, just return - if (m_NumberOfCapturePoints == 0 || m_NumberOfCapturePoints != m_CapturePointNumberToEntityMap.size()) { - m_CapturePointNumberToEntityMap.insert(std::make_pair(capturePointNumber, capturePointEntity)); - return; - } + for(auto& cCapturePoint : *CapturePoints) { + EntityWrapper entityCP = EntityWrapper(m_World, cCapturePoint.EntityID); - //we have all capturepoints now - process stuff - int ownedBy = teamComponent["Team"]; - int redTeamPlayersStandingInside = 0; - int blueTeamPlayersStandingInside = 0; - if (capturePointEntity.HasComponent("Model")) { - //Now sets team color to the capturepoint, or white if it is uncaptured. - capturePointEntity["Model"]["Color"] = ownedBy == blueTeam ? glm::vec4(0, 0.2f, 1, 0.3) : ownedBy == redTeam ? glm::vec4(1, 0.2f, 0, 0.3) : glm::vec4(1, 1, 1, 0.3); - } - - //calculate next possible capturePoint for both teams - std::map nextPossibleCapturePoint; - nextPossibleCapturePoint["Red"] = -1; - nextPossibleCapturePoint["Blue"] = -1; - for (int i = 0; i < m_NumberOfCapturePoints; i++) - { - if (!m_CapturePointNumberToEntityMap[i].HasComponent("Team")) { - continue; - } - ComponentWrapper& capturePointOwnedBy = m_CapturePointNumberToEntityMap[i]["Team"]; - if ((int)capturePointOwnedBy["Team"] == redTeam && m_RedTeamHomeCapturePoint == 0) { - nextPossibleCapturePoint["Red"] = i + 1; - } - if ((int)capturePointOwnedBy["Team"] == blueTeam && m_BlueTeamHomeCapturePoint == 0) { - nextPossibleCapturePoint["Blue"] = i + 1; - } - } - for (int i = m_NumberOfCapturePoints - 1; i >= 0; i--) - { - if (!m_CapturePointNumberToEntityMap[i].HasComponent("Team")) { - continue; - } - ComponentWrapper& capturePointOwnedBy = m_CapturePointNumberToEntityMap[i]["Team"]; - if ((int)capturePointOwnedBy["Team"] == redTeam && m_RedTeamHomeCapturePoint != 0) { - nextPossibleCapturePoint["Red"] = i - 1; - } - if ((int)capturePointOwnedBy["Team"] == blueTeam && m_BlueTeamHomeCapturePoint != 0) { - nextPossibleCapturePoint["Blue"] = i - 1; - } - } - - //reset timers and reset the bool that triggers this - if (m_ResetTimers) { - for (int i = 0; i < m_NumberOfCapturePoints; i++) - { - ComponentWrapper& capturePoint = m_CapturePointNumberToEntityMap[i]["CapturePoint"]; - if ((int)capturePoint["CapturePointNumber"] != nextPossibleCapturePoint["Red"] && - (int)capturePoint["CapturePointNumber"] != nextPossibleCapturePoint["Blue"]) { - capturePoint["CaptureTimer"] = 0.0; - } - } - m_ResetTimers = false; - } - - //colorize next possible capturepoint - if (nextPossibleCapturePoint["Red"] == capturePointNumber) { - capturePointEntity["Model"]["Color"] = glm::vec4(1, 1, 0, 0.3); - } - if (nextPossibleCapturePoint["Blue"] == capturePointNumber) { - capturePointEntity["Model"]["Color"] = glm::vec4(0, 1, 1, 0.3); - } - - //check how many players are standing inside and are healthy - for (size_t i = m_ETriggerTouchVector.size(); i > 0; i--) - { - auto triggerTouched = m_ETriggerTouchVector[i - 1]; - if (std::get<1>(triggerTouched) == capturePointEntity) { - //some player has touched this - lets figure out: what team, health - EntityWrapper player = std::get<0>(triggerTouched); - //check if its really a player that has triggered the touch - if (!player.HasComponent("Player")) { - //if a non-player has entered the capturePoint, just erase that event and continue - m_ETriggerTouchVector.erase(m_ETriggerTouchVector.begin() + i - 1); - continue; - } - bool hasHealthComponent = player.HasComponent("Health"); - if (hasHealthComponent) { - double currentHealth = player["Health"]["Health"]; - //check if player is dead - if ((int)currentHealth == 0) { - continue; + //Check if the HUD corresponds to the Capture Point Number + if (HUD_ID == (int)entityCP["CapturePoint"]["CapturePointNumber"]) { + ComponentWrapper& teamComponent = entityCP["Team"]; + if (!LoadCheck) { + redTeam = (int)teamComponent["Team"].Enum("Red"); + blueTeam = (int)teamComponent["Team"].Enum("Blue"); + spectatorTeam = (int)teamComponent["Team"].Enum("Spectator"); } + //Color hud with team color + auto capturePointTeam = (int)teamComponent["Team"]; + entityHUDparent["Sprite"]["Color"] = capturePointTeam == blueTeam ? glm::vec4(0, 0.2f, 1, 0.7) : capturePointTeam == redTeam ? glm::vec4(1, 0.2f, 0, 0.7) : glm::vec4(1, 1, 1, 0.3); + + //Progress is scaled with time + double currentCaptureTime = (double)entityCP["CapturePoint"]["CaptureTimer"]; + double progress = glm::abs(currentCaptureTime)/15.0; + int currentCapturingTeam = currentCaptureTime > 0 ? redTeam : currentCaptureTime < 0 ? blueTeam : spectatorTeam; + ((glm::vec3&)entityHUD["Transform"]["Orientation"]).z = currentCapturingTeam == redTeam ? glm::half_pi()+glm::pi() : glm::half_pi(); + glm::vec4 fillColor = currentCapturingTeam == redTeam ? glm::vec4(1, 0.2f, 0, 0.7) : glm::vec4(0, 0.2f, 1, 0.7); + entityHUD["Fill"]["Color"] = fillColor; + entityHUD["Fill"]["Percentage"] = progress; } - //check team - spectatorNumber = "no team" - int teamNumber = player["Team"]["Team"]; - if (teamNumber == redTeam) { - redTeamPlayersStandingInside++; - } else if (teamNumber == blueTeam) { - blueTeamPlayersStandingInside++; - } - continue; } } - //create data to be used in option B - //check so this is the next possible capture point for the take-over team and see if only one team is standing inside it - double timerDeltaChange = 0.0; - int currentTeam = 0; - bool canCapture = false; - if (redTeamPlayersStandingInside > 0 && blueTeamPlayersStandingInside == 0) { - timerDeltaChange = redTeamPlayersStandingInside*dt; - currentTeam = redTeam; - canCapture = nextPossibleCapturePoint["Red"] == capturePointNumber; - } - if (redTeamPlayersStandingInside == 0 && blueTeamPlayersStandingInside > 0) { - timerDeltaChange = -blueTeamPlayersStandingInside*dt; - currentTeam = blueTeam; - canCapture = nextPossibleCapturePoint["Blue"] == capturePointNumber; - } + //if (m_WinnerWasFound) { + // return; + //} + //const int capturePointNumber = cCapturePoint["CapturePointNumber"]; + //const bool hasTeamComponent = capturePointEntity.HasComponent("Team"); - if (redTeamPlayersStandingInside == 0 && blueTeamPlayersStandingInside == 0) { - //A.nobodys standing inside - //do nothing (?) - } else if (redTeamPlayersStandingInside > 0 && blueTeamPlayersStandingInside > 0) { - //C.both teams have players inside - //do nothing (?) - } else { - //B. at most one of the teams have players inside - //if capturePoint is not owned by the take-over team, just modify the CaptureTimer accordingly - if (ownedBy != currentTeam && canCapture) { - if (abs((double)cCapturePoint["CaptureTimer"]) < 0.001f) { - LOG_DEBUG("Point is being captured by team %i", currentTeam); //Remove when we tested sufficiently. - } - cCapturePoint["CaptureTimer"] = (double)cCapturePoint["CaptureTimer"] + timerDeltaChange; - } - //if capturePoint is owned by the team, and the other team has been trying to take it, then increase/decrease the timer towards 0.0 - if ((ownedBy == currentTeam && currentTeam == redTeam && (double)cCapturePoint["CaptureTimer"] < 0.0) || - (ownedBy == currentTeam && currentTeam == blueTeam && (double)cCapturePoint["CaptureTimer"] > 0.0)) { - cCapturePoint["CaptureTimer"] = (double)cCapturePoint["CaptureTimer"] + timerDeltaChange; - } - //check if captureTimer > m_CaptureTimeToTakeOver and if so change owner and publish the eCaptured event - if (abs((double)cCapturePoint["CaptureTimer"]) > abs(m_CaptureTimeToTakeOver) && canCapture) { - teamComponent["Team"] = currentTeam; - cCapturePoint["CaptureTimer"] = 0.0; - //publish Captured event - LOG_DEBUG("Point is captured by team %i!", currentTeam); //Remove when we tested sufficiently. - Events::Captured e; - e.CapturePointID = cCapturePoint.EntityID; - e.TeamNumberThatCapturedCapturePoint = currentTeam; - m_EventBroker->Publish(e); - //NextPossibleCapturePoint will be calculated in the next update... - } - } + ////if point doesnt have a teamComponent yet, add one. since: + ////what if capture point has no team -> we cant get/use the team enum from it... + //if (!hasTeamComponent) { + // m_World->AttachComponent(cCapturePoint.EntityID, "Team"); + // ComponentWrapper& teamComponent = capturePointEntity["Team"]; + // teamComponent["Team"] = (int)teamComponent["Team"].Enum("Spectator"); + //} + //ComponentWrapper& teamComponent = capturePointEntity["Team"]; + //const int redTeam = (int)teamComponent["Team"].Enum("Red"); + //const int blueTeam = (int)teamComponent["Team"].Enum("Blue"); + //const int spectatorTeam = (int)teamComponent["Team"].Enum("Spectator"); - //check for possible winCondition = check if the homebase is owned by the other team - bool checkForWinner = false; - if (capturePointNumber == m_RedTeamHomeCapturePoint && ownedBy != redTeam) - { - checkForWinner = true; - } - if (capturePointNumber == m_BlueTeamHomeCapturePoint && ownedBy != blueTeam) - { - checkForWinner = true; - } + //int homePointForTeam = (int)cCapturePoint["HomePointForTeam"]; + //if (m_NumberOfCapturePoints == 0 && capturePointNumber != 0 && (homePointForTeam == redTeam || homePointForTeam == blueTeam)) { + // m_NumberOfCapturePoints = capturePointNumber + 1;//ex 2 -> 0,1,2 = 3 + // if (homePointForTeam == redTeam) { + // m_RedTeamHomeCapturePoint = capturePointNumber; + // m_BlueTeamHomeCapturePoint = 0; + // } else { + // m_BlueTeamHomeCapturePoint = capturePointNumber; + // m_RedTeamHomeCapturePoint = 0; + // } + //} - if (checkForWinner && !m_WinnerWasFound) - { - //publish Win event - Events::Win e; - e.TeamThatWon = ownedBy; - m_EventBroker->Publish(e); - m_WinnerWasFound = true; - } + ////if we havent received all capturepoints yet, just return + //if (m_NumberOfCapturePoints == 0 || m_NumberOfCapturePoints != m_CapturePointNumberToEntityMap.size()) { + // m_CapturePointNumberToEntityMap.insert(std::make_pair(capturePointNumber, capturePointEntity)); + // return; + //} + + ////we have all capturepoints now - process stuff + //int ownedBy = teamComponent["Team"]; + //int redTeamPlayersStandingInside = 0; + //int blueTeamPlayersStandingInside = 0; + //if (capturePointEntity.HasComponent("Model")) { + // //Now sets team color to the capturepoint, or white if it is uncaptured. + // capturePointEntity["Model"]["Color"] = ownedBy == blueTeam ? glm::vec4(0, 0.2f, 1, 0.3) : ownedBy == redTeam ? glm::vec4(1, 0.2f, 0, 0.3) : glm::vec4(1, 1, 1, 0.3); + //} + + ////calculate next possible capturePoint for both teams + //std::map nextPossibleCapturePoint; + //nextPossibleCapturePoint["Red"] = -1; + //nextPossibleCapturePoint["Blue"] = -1; + //for (int i = 0; i < m_NumberOfCapturePoints; i++) + //{ + // if (!m_CapturePointNumberToEntityMap[i].HasComponent("Team")) { + // continue; + // } + // ComponentWrapper& capturePointOwnedBy = m_CapturePointNumberToEntityMap[i]["Team"]; + // if ((int)capturePointOwnedBy["Team"] == redTeam && m_RedTeamHomeCapturePoint == 0) { + // nextPossibleCapturePoint["Red"] = i + 1; + // } + // if ((int)capturePointOwnedBy["Team"] == blueTeam && m_BlueTeamHomeCapturePoint == 0) { + // nextPossibleCapturePoint["Blue"] = i + 1; + // } + //} + //for (int i = m_NumberOfCapturePoints - 1; i >= 0; i--) + //{ + // if (!m_CapturePointNumberToEntityMap[i].HasComponent("Team")) { + // continue; + // } + // ComponentWrapper& capturePointOwnedBy = m_CapturePointNumberToEntityMap[i]["Team"]; + // if ((int)capturePointOwnedBy["Team"] == redTeam && m_RedTeamHomeCapturePoint != 0) { + // nextPossibleCapturePoint["Red"] = i - 1; + // } + // if ((int)capturePointOwnedBy["Team"] == blueTeam && m_BlueTeamHomeCapturePoint != 0) { + // nextPossibleCapturePoint["Blue"] = i - 1; + // } + //} + + ////reset timers and reset the bool that triggers this + //if (m_ResetTimers) { + // for (int i = 0; i < m_NumberOfCapturePoints; i++) + // { + // ComponentWrapper& capturePoint = m_CapturePointNumberToEntityMap[i]["CapturePoint"]; + // if ((int)capturePoint["CapturePointNumber"] != nextPossibleCapturePoint["Red"] && + // (int)capturePoint["CapturePointNumber"] != nextPossibleCapturePoint["Blue"]) { + // capturePoint["CaptureTimer"] = 0.0; + // } + // } + // m_ResetTimers = false; + //} + + ////colorize next possible capturepoint + //if (nextPossibleCapturePoint["Red"] == capturePointNumber) { + // capturePointEntity["Model"]["Color"] = glm::vec4(1, 1, 0, 0.3); + //} + //if (nextPossibleCapturePoint["Blue"] == capturePointNumber) { + // capturePointEntity["Model"]["Color"] = glm::vec4(0, 1, 1, 0.3); + //} + + ////check how many players are standing inside and are healthy + //for (size_t i = m_ETriggerTouchVector.size(); i > 0; i--) + //{ + // auto triggerTouched = m_ETriggerTouchVector[i - 1]; + // if (std::get<1>(triggerTouched) == capturePointEntity) { + // //some player has touched this - lets figure out: what team, health + // EntityWrapper player = std::get<0>(triggerTouched); + // //check if its really a player that has triggered the touch + // if (!player.HasComponent("Player")) { + // //if a non-player has entered the capturePoint, just erase that event and continue + // m_ETriggerTouchVector.erase(m_ETriggerTouchVector.begin() + i - 1); + // continue; + // } + // bool hasHealthComponent = player.HasComponent("Health"); + // if (hasHealthComponent) { + // double currentHealth = player["Health"]["Health"]; + // //check if player is dead + // if ((int)currentHealth == 0) { + // continue; + // } + // } + // //check team - spectatorNumber = "no team" + // int teamNumber = player["Team"]["Team"]; + // if (teamNumber == redTeam) { + // redTeamPlayersStandingInside++; + // } else if (teamNumber == blueTeam) { + // blueTeamPlayersStandingInside++; + // } + // continue; + // } + //} + + ////create data to be used in option B + ////check so this is the next possible capture point for the take-over team and see if only one team is standing inside it + //double timerDeltaChange = 0.0; + //int currentTeam = 0; + //bool canCapture = false; + //if (redTeamPlayersStandingInside > 0 && blueTeamPlayersStandingInside == 0) { + // timerDeltaChange = redTeamPlayersStandingInside*dt; + // currentTeam = redTeam; + // canCapture = nextPossibleCapturePoint["Red"] == capturePointNumber; + //} + //if (redTeamPlayersStandingInside == 0 && blueTeamPlayersStandingInside > 0) { + // timerDeltaChange = -blueTeamPlayersStandingInside*dt; + // currentTeam = blueTeam; + // canCapture = nextPossibleCapturePoint["Blue"] == capturePointNumber; + //} + + //if (redTeamPlayersStandingInside == 0 && blueTeamPlayersStandingInside == 0) { + // //A.nobodys standing inside + // //do nothing (?) + //} else if (redTeamPlayersStandingInside > 0 && blueTeamPlayersStandingInside > 0) { + // //C.both teams have players inside + // //do nothing (?) + //} else { + // //B. at most one of the teams have players inside + // //if capturePoint is not owned by the take-over team, just modify the CaptureTimer accordingly + // if (ownedBy != currentTeam && canCapture) { + // if (abs((double)cCapturePoint["CaptureTimer"]) < 0.001f) { + // LOG_DEBUG("Point is being captured by team %i", currentTeam); //Remove when we tested sufficiently. + // } + // cCapturePoint["CaptureTimer"] = (double)cCapturePoint["CaptureTimer"] + timerDeltaChange; + // } + // //if capturePoint is owned by the team, and the other team has been trying to take it, then increase/decrease the timer towards 0.0 + // if ((ownedBy == currentTeam && currentTeam == redTeam && (double)cCapturePoint["CaptureTimer"] < 0.0) || + // (ownedBy == currentTeam && currentTeam == blueTeam && (double)cCapturePoint["CaptureTimer"] > 0.0)) { + // cCapturePoint["CaptureTimer"] = (double)cCapturePoint["CaptureTimer"] + timerDeltaChange; + // } + // //check if captureTimer > m_CaptureTimeToTakeOver and if so change owner and publish the eCaptured event + // if (abs((double)cCapturePoint["CaptureTimer"]) > abs(m_CaptureTimeToTakeOver) && canCapture) { + // teamComponent["Team"] = currentTeam; + // cCapturePoint["CaptureTimer"] = 0.0; + // //publish Captured event + // LOG_DEBUG("Point is captured by team %i!", currentTeam); //Remove when we tested sufficiently. + // Events::Captured e; + // e.CapturePointID = cCapturePoint.EntityID; + // e.TeamNumberThatCapturedCapturePoint = currentTeam; + // m_EventBroker->Publish(e); + // //NextPossibleCapturePoint will be calculated in the next update... + // } + //} + + ////check for possible winCondition = check if the homebase is owned by the other team + //bool checkForWinner = false; + //if (capturePointNumber == m_RedTeamHomeCapturePoint && ownedBy != redTeam) + //{ + // checkForWinner = true; + //} + //if (capturePointNumber == m_BlueTeamHomeCapturePoint && ownedBy != blueTeam) + //{ + // checkForWinner = true; + //} + + //if (checkForWinner && !m_WinnerWasFound) + //{ + // //publish Win event + // Events::Win e; + // e.TeamThatWon = ownedBy; + // m_EventBroker->Publish(e); + // m_WinnerWasFound = true; + //} } - -bool CapturePointSystem::OnTriggerTouch(const Events::TriggerTouch& e) -{ - //personEntered = e.Entity, thingEntered = e.Trigger - m_ETriggerTouchVector.push_back(std::make_tuple(e.Entity, e.Trigger)); - return true; -} - -bool CapturePointSystem::OnTriggerLeave(const Events::TriggerLeave& e) -{ - for (size_t i = 0; i < m_ETriggerTouchVector.size(); i++) - { - auto triggerTouched = m_ETriggerTouchVector[i]; - if (std::get<0>(triggerTouched) == e.Entity && std::get<1>(triggerTouched) == e.Trigger) { - m_ETriggerTouchVector.erase(m_ETriggerTouchVector.begin() + i); - break; - } - } - return true; -} -bool CapturePointSystem::OnCaptured(const Events::Captured& e) -{ - //reset the timers in the next update since a capture has changed the "nextCapturePoint" for 1-2 teams - m_ResetTimers = true; - return true; -} +// +//bool CapturePointSystem::OnTriggerTouch(const Events::TriggerTouch& e) +//{ +// //personEntered = e.Entity, thingEntered = e.Trigger +// m_ETriggerTouchVector.push_back(std::make_tuple(e.Entity, e.Trigger)); +// return true; +//} +// +//bool CapturePointSystem::OnTriggerLeave(const Events::TriggerLeave& e) +//{ +// for (size_t i = 0; i < m_ETriggerTouchVector.size(); i++) +// { +// auto triggerTouched = m_ETriggerTouchVector[i]; +// if (std::get<0>(triggerTouched) == e.Entity && std::get<1>(triggerTouched) == e.Trigger) { +// m_ETriggerTouchVector.erase(m_ETriggerTouchVector.begin() + i); +// break; +// } +// } +// return true; +//} +//bool CapturePointSystem::OnCaptured(const Events::Captured& e) +//{ +// //reset the timers in the next update since a capture has changed the "nextCapturePoint" for 1-2 teams +// m_ResetTimers = true; +// return true; +//} From 9d9c6bdf1ebf04b65da97f4a0c4909d49d957bae Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Thu, 11 Feb 2016 00:08:50 +0100 Subject: [PATCH 21/31] Third person animations and shoot effects base work --- assets | 2 +- include/Game/Game.h | 2 +- include/Game/Systems/WeaponSystem.h | 114 ++++++++++-------- resources/Schema/Entities/MovementTest.xml | 4 +- resources/Schema/Entities/Player.xml | 105 +++++++++++----- resources/Schema/Entities/RayBlue.xml | 6 +- src/Engine/Rendering/RenderSystem.cpp | 4 +- src/Engine/Rendering/Skeleton.cpp | 6 - src/Game/Game.cpp | 5 +- .../Network/MultiplayerSnapshotFilter.cpp | 4 +- src/Game/Systems/PlayerMovementSystem.cpp | 76 ++++++++++-- src/Game/Systems/PlayerSpawnSystem.cpp | 2 +- src/Game/Systems/WeaponSystem.cpp | 16 +-- 13 files changed, 228 insertions(+), 118 deletions(-) diff --git a/assets b/assets index 45cbc3ab..172b3ad5 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 45cbc3abaebe5f815e2c1b58bcf884d4953a4c52 +Subproject commit 172b3ad527fc14aa6175fa72580a66a00f04e0ba diff --git a/include/Game/Game.h b/include/Game/Game.h index 42ef4d96..baf15656 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -46,7 +46,7 @@ public: private: std::string m_NetworkAddress; - int m_NetworkPort; + int m_NetworkPort = 0; ConfigFile* m_Config = nullptr; EventBroker* m_EventBroker; diff --git a/include/Game/Systems/WeaponSystem.h b/include/Game/Systems/WeaponSystem.h index 489048b8..c3daeceb 100644 --- a/include/Game/Systems/WeaponSystem.h +++ b/include/Game/Systems/WeaponSystem.h @@ -15,6 +15,7 @@ #include "Core/EntityFileParser.h" #include "Core/Octree.h" #include "Collision/EntityAABB.h" +#include "Systems/SpawnerSystem.h" class WeaponBehaviour; @@ -150,69 +151,80 @@ private: void spawnTracer() { - ComponentWrapper cTeam = m_Entity["Team"]; - ComponentInfo::EnumType team = cTeam["Team"]; + EntityWrapper spawner; + if (m_Entity == LocalPlayer) { + spawner = m_Entity.FirstChildByName("WeaponMuzzle"); + } else { + spawner = m_Entity.FirstChildByName("ThirdPersonWeaponMuzzle"); + } - // Select the right color of effect - EntityFile* rayFile = nullptr; - if (team == cTeam["Team"].Enum("Red")) { - rayFile = m_RayRed; - } - if (team == cTeam["Team"].Enum("Blue")) { - rayFile = m_RayBlue; - } - if (rayFile == nullptr) { + if (!spawner.Valid()) { return; } - // Create the entity - EntityFileParser parser(rayFile); - EntityID rayID = parser.MergeEntities(m_World); - EntityWrapper ray(m_World, rayID); + Events::SpawnerSpawn e; + e.Spawner = spawner; + m_EventBroker->Publish(e); - // Figure out where to put it - EntityWrapper attachment; - if (m_Entity == LocalPlayer || true) { - // Spawn the effect from the weapon view model for the local player - attachment = m_Entity.FirstChildByName("WeaponMuzzle"); - } - // TODO: Spawn the effect from the weapon world model once it exists + //ComponentWrapper cTeam = m_Entity["Team"]; + //ComponentInfo::EnumType team = cTeam["Team"]; - glm::mat4 transformation = Transform::AbsoluteTransformation(attachment); - glm::vec3 _scale; - glm::vec3 translation; - glm::quat _orientation; - glm::vec3 _skew; - glm::vec4 _perspective; - glm::decompose(transformation, _scale, _orientation, translation, _skew, _perspective); - - // Matrix to euler angles - glm::vec3 euler; - euler.y = glm::asin(-transformation[0][2]); - if (cos(euler.y) != 0) { - euler.x = atan2(transformation[1][2], transformation[2][2]); - euler.z = atan2(transformation[0][1], transformation[0][0]); - } else { - euler.x = atan2(-transformation[2][0], transformation[1][1]); - euler.z = 0; - } + //// Select the right color of effect + //EntityFile* rayFile = nullptr; + //if (team == cTeam["Team"].Enum("Red")) { + // rayFile = m_RayRed; + //} + //if (team == cTeam["Team"].Enum("Blue")) { + // rayFile = m_RayBlue; + //} + //if (rayFile == nullptr) { + // return; + //} - // TODO: Spread? + //// Create the entity + //EntityFileParser parser(rayFile); + //EntityID rayID = parser.MergeEntities(m_World); + //EntityWrapper ray(m_World, rayID); - (glm::vec3&)ray["Transform"]["Position"] = translation; - (glm::vec3&)ray["Transform"]["Orientation"] = euler; - glm::vec3& scale = ray["Transform"]["Scale"]; - scale.z = traceRayDistance(translation, glm::quat(euler) * glm::vec3(0.f, 0.f, -1.f)); + //// Figure out where to put it + //EntityWrapper attachment; + //if (m_Entity == LocalPlayer || true) { + // // Spawn the effect from the weapon view model for the local player + // attachment = m_Entity.FirstChildByName("WeaponMuzzle"); + //} + //// TODO: Spawn the effect from the weapon world model once it exists + + //glm::mat4 transformation = Transform::AbsoluteTransformation(attachment); + //glm::vec3 _scale; + //glm::vec3 translation; + //glm::quat _orientation; + //glm::vec3 _skew; + //glm::vec4 _perspective; + //glm::decompose(transformation, _scale, _orientation, translation, _skew, _perspective); + // + //// Matrix to euler angles + //glm::vec3 euler; + //euler.y = glm::asin(-transformation[0][2]); + //if (cos(euler.y) != 0) { + // euler.x = atan2(transformation[1][2], transformation[2][2]); + // euler.z = atan2(transformation[0][1], transformation[0][0]); + //} else { + // euler.x = atan2(-transformation[2][0], transformation[1][1]); + // euler.z = 0; + //} + + //// TODO: Spread? + + //(glm::vec3&)ray["Transform"]["Position"] = translation; + //(glm::vec3&)ray["Transform"]["Orientation"] = euler; + //glm::vec3& scale = ray["Transform"]["Scale"]; + //scale.z = traceRayDistance(translation, glm::quat(euler) * glm::vec3(0.f, 0.f, -1.f)); } float traceRayDistance(glm::vec3 origin, glm::vec3 direction) { - OctSpace::Output result; - if (m_CollisionOctree->RayCollides(Ray(origin, direction), result)) { - return result.CollideDistance; - } else { - return 0.f; - } + // TODO: Cast a ray and size tracer appropriately + return 100.f; } }; diff --git a/resources/Schema/Entities/MovementTest.xml b/resources/Schema/Entities/MovementTest.xml index b8b68ef1..16a28684 100644 --- a/resources/Schema/Entities/MovementTest.xml +++ b/resources/Schema/Entities/MovementTest.xml @@ -52,6 +52,7 @@ + sModels/Widgets/Lights/DirectionalLightWidget.mesh @@ -65,9 +66,6 @@ - - - Models/Test/ObstacleCourse.mesh diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index e0cafc23..423e729e 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -10,9 +10,7 @@ 600 - - 2 - + @@ -22,12 +20,10 @@ - + - - - + @@ -35,7 +31,7 @@ - + @@ -105,26 +101,48 @@ - + + + + + + Idle + 0.24743387388836702 + 1 + + + Models/Characters/Assault/FirstPerson.mesh + true + + + + + + + R_Arm_Weapon_Joint + - Models/Weapons/Red/AssaultWeaponRed.mesh - true + Models/Weapons/Blue/AssaultWeaponBlue.mesh - - + + - - - - - - - - - + + + + + Schema/Entities/RayBlue.xml + + + + + + + + @@ -147,18 +165,49 @@ - Hold Pos - - 1 + Idle + 1 + + AimRifle + + - Models/Characters/Assault/AssaultAnimated.mesh - + Models/Characters/Assault/AssaultAnimations.mesh + - + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Blue/AssaultWeaponBlue.mesh + + + + + + + + + + + Schema/Entities/RayBlue.xml + + + + + + + + + + diff --git a/resources/Schema/Entities/RayBlue.xml b/resources/Schema/Entities/RayBlue.xml index 8d8e6e1e..022d7769 100644 --- a/resources/Schema/Entities/RayBlue.xml +++ b/resources/Schema/Entities/RayBlue.xml @@ -6,12 +6,12 @@ 0.25 - Models/Weapons/CylinderBullet.mesh - + Models/Effects/CylinderShot.mesh + true - + diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 8dc24e14..36baea0d 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -66,8 +66,8 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs) } // Hide things parented to local player if they have the HiddenFromLocalPlayer component - if (entity.HasComponent("HiddenForLocalPlayer") && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer))) { - continue; + if ((entity.HasComponent("HiddenForLocalPlayer") || entity.FirstParentWithComponent("HiddenForLocalPlayer").Valid()) && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer))) { + //continue; } Model* model; diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index 1aabd84c..71f351e6 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -104,7 +104,6 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector 1.0f || progress < 0.0f) { - LOG_INFO("Progress: %f", progress); progress = glm::clamp(progress, 0.0f, 1.0f); } Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties; @@ -181,7 +180,6 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector 1.0f || progress < 0.0f) { - LOG_INFO("Progress: %f", progress); progress = glm::clamp(progress, 0.0f, 1.0f); } Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties; @@ -353,9 +349,7 @@ glm::mat4 Skeleton::GetOffsetTransform(const Bone* bone, AnimationOffset animati } - if (progress > 1.0f || progress < 0.0f) { - LOG_INFO("Progress: %f", progress); progress = glm::clamp(progress, 0.0f, 1.0f); } Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties; diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index a6f12f03..6057d463 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -227,11 +227,8 @@ int Game::parseArgs(int argc, char* argv[]) exit(1); } - if (vm.count("connect")) { - m_IsClient = true; - } - // HACK: Right now, client and server are mutually exclusive + m_IsClient = true; if (m_IsServer) { m_IsClient = false; } diff --git a/src/Game/Network/MultiplayerSnapshotFilter.cpp b/src/Game/Network/MultiplayerSnapshotFilter.cpp index 709ce6b1..65d40189 100644 --- a/src/Game/Network/MultiplayerSnapshotFilter.cpp +++ b/src/Game/Network/MultiplayerSnapshotFilter.cpp @@ -26,6 +26,8 @@ bool MultiplayerSnapshotFilter::FilterComponent(EntityWrapper entity, SharedComp bool MultiplayerSnapshotFilter::OnPlayerSpawned(Events::PlayerSpawned ePlayerSpawned) { - m_LocalPlayer = ePlayerSpawned.Player; + if (ePlayerSpawned.PlayerID == -1) { + m_LocalPlayer = ePlayerSpawned.Player; + } return true; } \ No newline at end of file diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index ec834715..7c69f0ce 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -29,12 +29,20 @@ void PlayerMovementSystem::updateMovementControllers(double dt) continue; } + // Aim pitch EntityWrapper cameraEntity = player.FirstChildByName("Camera"); if (cameraEntity.Valid()) { glm::vec3& cameraOrientation = cameraEntity["Transform"]["Orientation"]; cameraOrientation.x += controller->Rotation().x; // Limit camera pitch so we don't break our necks cameraOrientation.x = glm::clamp(cameraOrientation.x, -glm::half_pi(), glm::half_pi()); + // Set third person model aim pitch + EntityWrapper playerModel = player.FirstChildByName("PlayerModel"); + if (playerModel.Valid()) { + ComponentWrapper cAnimationOffset = playerModel["AnimationOffset"]; + double time = (cameraOrientation.x + glm::half_pi()) / glm::pi(); + cAnimationOffset["Time"] = time; + } } ComponentWrapper& cTransform = player["Transform"]; @@ -124,24 +132,74 @@ void PlayerMovementSystem::updateMovementControllers(double dt) EntityWrapper playerModel = player.FirstChildByName("PlayerModel"); if (playerModel.Valid()) { ComponentWrapper cAnimation = playerModel["Animation"]; + std::string& animationName1 = cAnimation["AnimationName1"]; + std::string& animationName2 = cAnimation["AnimationName2"]; + double& animationTime1 = cAnimation["Time1"]; + double& animationTime2 = cAnimation["Time2"]; + double& animationSpeed1 = cAnimation["Speed1"]; + double& animationSpeed2 = cAnimation["Speed2"]; + double& animationWeight1 = cAnimation["Weight1"]; + double& animationWeight2 = cAnimation["Weight2"]; float movementLength = glm::length(groundVelocity); //TODO: add assault dash animation here if (glm::length(controller->Movement()) > 0.f) { - if (controller->Crouching()) { - cAnimation["AnimationName1"] = "Crouch Walk"; - (double&)cAnimation["Speed1"] = 1.f * -glm::sign(controller->Movement().z); + double forwardMovement = controller->Movement().z; + double strafeMovement = controller->Movement().x; + + if (controller->Crouching() && animationName1 != "CrouchWalk") { + animationName1 = "CrouchWalk"; + animationSpeed1 = 1.0 * -glm::sign(controller->Movement().z); } else { - cAnimation["AnimationName1"] = "Run"; - (double&)cAnimation["Speed1"] = 2.f * -glm::sign(controller->Movement().z); + if (glm::abs(forwardMovement) > 0) { + if (animationName1 != "Run") { + animationName1 = "Run"; + if (animationName2 == "StrafeLeft" || animationName2 == "StrafeRight") { + animationTime1 = animationTime2; + } else { + animationTime1 = 0.0; + } + } + animationSpeed1 = 2.f * -glm::sign(forwardMovement); + } + + if (glm::abs(strafeMovement) > 0) { + if (animationName2 != "StrafeLeft" && animationName2 != "StrafeRight") { + if (strafeMovement < 0) { + animationName2 = "StrafeLeft"; + } + if (strafeMovement > 0) { + animationName2 = "StrafeRight"; + } + if (animationName1 == "Run") { + animationTime2 = animationTime1; + } else { + animationTime2 = 0.0; + } + } + animationSpeed2 = 2.f * glm::abs(strafeMovement); + } + + double strafeWeight = glm::abs(strafeMovement) / (glm::abs(forwardMovement) + glm::abs(strafeMovement)); + animationWeight2 = strafeWeight; + animationWeight1 = 1.0 - strafeWeight; } } else { if (controller->Crouching()) { - cAnimation["AnimationName1"] = "Crouch"; - (double&)cAnimation["Speed"] = 1.f; + animationName1 = "Crouch"; + animationName2 = ""; + animationSpeed1 = 1.0; + animationSpeed2 = 0.0; + animationWeight1 = 1.0; + animationWeight2 = 0.0; } else { - cAnimation["AnimationName1"] = "Hold Pos"; - (double&)cAnimation["Speed1"] = 1.f; + animationName1 = "Idle"; + animationName2 = ""; + animationSpeed1 = 1.f; + animationSpeed2 = 0.0; + animationWeight1 = 1.0; + animationWeight2 = 0.0; + //cAnimation["AnimationName2"] = "Idle"; } } } diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index 507ed0f5..2afb0de1 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -91,7 +91,7 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e) if (cameraEntity.Valid()) { Events::SetCamera e; e.CameraEntity = cameraEntity; - m_EventBroker->Publish(e); + //m_EventBroker->Publish(e); } // HACK: Set the player model color to team color diff --git a/src/Game/Systems/WeaponSystem.cpp b/src/Game/Systems/WeaponSystem.cpp index dfb84581..117176c1 100644 --- a/src/Game/Systems/WeaponSystem.cpp +++ b/src/Game/Systems/WeaponSystem.cpp @@ -20,14 +20,14 @@ void WeaponSystem::Update(double dt) void WeaponSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cPlayer, double dt) { // Update potential weapon behaviour for player - //auto it = m_ActiveWeapons.find(entity); - //if (it != m_ActiveWeapons.end()) { - // //if (it->first.Valid()) { - // it->second->Update(dt); - // //} else { - // // m_ActiveWeapons.erase(it); - // //} - //} + auto it = m_ActiveWeapons.find(entity); + if (it != m_ActiveWeapons.end()) { + if (it->first.Valid()) { + it->second->Update(dt); + } else { + m_ActiveWeapons.erase(it); + } + } } bool WeaponSystem::OnInputCommand(Events::InputCommand& e) From 73f59b89ccce4709376beb9cc5273f68afc71178 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Thu, 11 Feb 2016 00:11:37 +0100 Subject: [PATCH 22/31] Added method EntityFirstHitByRay, takes an Octree or a vector of sorted entities and outputs the frist entity hit by a ray. --- include/Engine/Collision/Collision.h | 23 +++++++-- include/Engine/Core/Octree.h | 75 ++++++++++++++++++++++++++++ src/Engine/Collision/Collision.cpp | 66 ++++++++++++++++++------ src/Engine/Core/Octree.cpp | 25 +++------- 4 files changed, 151 insertions(+), 38 deletions(-) diff --git a/include/Engine/Collision/Collision.h b/include/Engine/Collision/Collision.h index c3759393..5b4150d8 100644 --- a/include/Engine/Collision/Collision.h +++ b/include/Engine/Collision/Collision.h @@ -20,6 +20,9 @@ class World; struct ComponentWrapper; +template +class Octree; + namespace Collision { //Return true if the ray hits the box. @@ -44,21 +47,24 @@ bool RayVsTriangle(const Ray& ray, float& outVCoord, bool trueOnNegativeDistance = false); //Return true if the ray hits any of the triangles in the model. Stops checking when a hit is detected. -bool RayVsModel(const Ray& ray, - const std::vector& modelVertices, - const std::vector& modelIndices); +bool RayVsModel(const Ray& ray, + const RawModel::Vertex* modelVertices, + const std::vector& modelIndices, + const glm::mat4& modelMatrix); //Return true if the ray hits any of the triangles in the model. //Also returns the position of the intersection point. Will loop through all the whole model indices. bool RayVsModel(const Ray& ray, - const std::vector& modelVertices, + const RawModel::Vertex* modelVertices, const std::vector& modelIndices, + const glm::mat4& modelMatrix, glm::vec3& outHitPosition); //Return true if the ray hits any of the triangles in the model. //Also returns the distance from the ray origin to the closest //intersection point, and the barycentric u,v-coordinates. Will loop through all the whole model indices. bool RayVsModel(const Ray& ray, - const std::vector& modelVertices, + const RawModel::Vertex* modelVertices, const std::vector& modelIndices, + const glm::mat4& modelMatrix, float& outDistance, float& outUCoord, float& outVCoord); @@ -81,6 +87,13 @@ bool AABBVsAABB(const AABB& a, const AABB& b, glm::vec3& minimumTranslation); // Calculates an absolute AABB from an entity AABB component boost::optional EntityAbsoluteAABB(EntityWrapper& entity, bool takeModelBox = false); boost::optional AbsoluteAABBExplosionEffect(EntityWrapper& entity); +//Returns the first entity hit by the input ray. entitiesPotentiallyHitSorted needs to be sorted +//by their distance to the ray, e.g. result from Octree::ObjectsPossiblyHitByRay. +//Returns boost::none if none was hit. outDistance will be the distance to the intersection point if the ray intersects. +boost::optional EntityFirstHitByRay(const Ray& ray, std::vector entitiesPotentiallyHitSorted, float outDistance, glm::vec3& outIntersectPos); +//Returns the first entity hit by the input ray that exists in the octree. +//outDistance will be the distance to the intersection point if the ray intersects. +boost::optional EntityFirstHitByRay(const Ray& ray, Octree* octree, float outDistance, glm::vec3& outIntersectPos); } diff --git a/include/Engine/Core/Octree.h b/include/Engine/Core/Octree.h index 6bdea4d3..be0cac95 100644 --- a/include/Engine/Core/Octree.h +++ b/include/Engine/Core/Octree.h @@ -43,6 +43,8 @@ public: void ObjectsInSameRegion(const Box& box, std::vector& outObjects); //Get the objects that are inside the frustum, the objects are put in outObjects. void ObjectsInFrustum(const Frustum& frustum, std::vector& outObjects); + //Get objects, which AABB the input ray intersects, the objects are put in outObjects. + void ObjectsPossiblyHitByRay(const Ray& ray, std::vector& outObjects); //Empty the tree of all objects, static and dynamic. void ClearObjects(); //Empty the tree of all dynamic objects. Static objects remain in the tree. @@ -102,6 +104,8 @@ struct Child void ObjectsInSameRegion(const Box& box, std::vector& outObjects) const; template void ObjectsInFrustum(const Frustum& frustum, std::vector& outObjects, bool takeAllDontTest) const; + template + void ObjectsPossiblyHitByRay(const Ray& ray, std::vector& outObjects) const; void ClearObjects(); void ClearDynamicObjects(); bool RayCollides(const Ray& ray, Output& data) const; @@ -121,6 +125,15 @@ struct Child std::vector childIndicesContainingBox(const AABB& box) const; }; +//To be able to sort child nodes and contained objects based on distance to ray origin. +struct RaySorterInfo +{ + int Index; + float Distance; +}; + +bool isFirstLower(const RaySorterInfo& first, const RaySorterInfo& second); + } template @@ -166,6 +179,13 @@ void Octree::ObjectsInFrustum(const Frustum& frustum, std::vector& outObje m_Root->ObjectsInFrustum(frustum, outObjects, false); } +template +void Octree::ObjectsPossiblyHitByRay(const Ray& ray, std::vector& outObjects) +{ + falsifyObjectChecks(); + m_Root->ObjectsPossiblyHitByRay(ray, outObjects); +} + template void Octree::ClearObjects() { @@ -284,4 +304,59 @@ void OctSpace::Child::ObjectsInFrustum(const Frustum& frustum, std::vector& o } } +template +void OctSpace::Child::ObjectsPossiblyHitByRay(const Ray& ray, std::vector& outObjects) const +{ + //If the node AABB is missed, everything it contains is missed. + if (Collision::RayAABBIntr(ray, m_Box)) { + //If the ray shoots the tree, and it is a parent. + if (hasChildren()) { + //Sort children according to their distance from the ray origin. + std::vector childInfos; + childInfos.resize(8); + for (int i = 0; i < 8; ++i) { + childInfos[i] = { i, glm::distance(ray.Origin(), m_Children[i]->m_Box.Origin()) }; + } + std::sort(childInfos.begin(), childInfos.end(), isFirstLower); + //Loop through the children, starting with the one closest to the ray origin. I.e the first to be hit. + for (const RaySorterInfo& info : childInfos) { + m_Children[info.Index]->ObjectsPossiblyHitByRay(ray, outObjects); + } + } else { + //Check against boxes in the node. + bool intersected = false; + float dist; + //Sort all contained objects according to the distance from the ray origin to + //the intersection, if they are intersecting. + std::vector objectHitInfos; + objectHitInfos.reserve(m_StaticObjIndices.size() + m_DynamicObjIndices.size()); + for (int i : m_StaticObjIndices) { + //If we haven't tested against this object before, and the ray hits. + if (!m_StaticObjectsRef[i].Checked && + Collision::RayVsAABB(ray, *m_StaticObjectsRef[i].Box, dist)) { + objectHitInfos.push_back({ i, dist }); + } + m_StaticObjectsRef[i].Checked = true; + } + for (int i : m_DynamicObjIndices) { + //If we haven't tested against this object before, and the ray hits. + if (!m_DynamicObjectsRef[i].Checked && + Collision::RayVsAABB(ray, *m_DynamicObjectsRef[i].Box, dist)) { + objectHitInfos.push_back({ i + (int)m_StaticObjIndices.size(), dist }); + } + m_DynamicObjectsRef[i].Checked = true; + } + std::sort(objectHitInfos.begin(), objectHitInfos.end(), isFirstLower); + int startSize = (int)outObjects.size(); + outObjects.resize(startSize + objectHitInfos.size()); + for (int i = 0; i < objectHitInfos.size(); ++i) { + outObjects[startSize + i] = (objectHitInfos[i].Index < m_StaticObjIndices.size()) ? + *static_cast(m_StaticObjectsRef[objectHitInfos[i].Index].Box.get()) : + *static_cast(m_DynamicObjectsRef[objectHitInfos[i].Index - m_StaticObjIndices.size()].Box.get()); + } + } + } +} + + #endif \ No newline at end of file diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index b7b21969..7b182de1 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -6,6 +6,7 @@ #include "Core/World.h" #include "Rendering/Model.h" #include "imgui/imgui.h" +#include "Core/Octree.h" namespace Collision { @@ -145,13 +146,14 @@ bool RayVsTriangle(const Ray& ray, } bool RayVsModel(const Ray& ray, - const std::vector& modelVertices, - const std::vector& modelIndices) + const RawModel::Vertex* modelVertices, + const std::vector& modelIndices, + const glm::mat4& modelMatrix) { - for (int i = 0; i < modelIndices.size(); ++i) { - glm::vec3 v0 = modelVertices[modelIndices[i]].Position; - glm::vec3 v1 = modelVertices[modelIndices[++i]].Position; - glm::vec3 v2 = modelVertices[modelIndices[++i]].Position; + for (int i = 0; i < modelIndices.size();) { + glm::vec3 v0 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); + glm::vec3 v1 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); + glm::vec3 v2 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); if (RayVsTriangle(ray, v0, v1, v2)) { return true; } @@ -192,19 +194,20 @@ bool RayVsTriangle(const Ray& ray, } bool RayVsModel(const Ray& ray, - const std::vector& modelVertices, + const RawModel::Vertex* modelVertices, const std::vector& modelIndices, + const glm::mat4& modelMatrix, float& outDistance, float& outUCoord, float& outVCoord) { outDistance = INFINITY; bool hit = false; - for (int i = 0; i < modelIndices.size(); ++i) { - glm::vec3 v0 = modelVertices[modelIndices[i]].Position; - glm::vec3 v1 = modelVertices[modelIndices[++i]].Position; - glm::vec3 v2 = modelVertices[modelIndices[++i]].Position; - float dist; + for (int i = 0; i < modelIndices.size();) { + glm::vec3 v0 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); + glm::vec3 v1 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); + glm::vec3 v2 = Transform::TransformPoint(modelVertices[modelIndices[i++]].Position, modelMatrix); + float dist = INFINITY; float u; float v; if (RayVsTriangle(ray, v0, v1, v2, dist, u, v)) { @@ -218,14 +221,15 @@ bool RayVsModel(const Ray& ray, } bool RayVsModel(const Ray& ray, - const std::vector& modelVertices, + const RawModel::Vertex* modelVertices, const std::vector& modelIndices, + const glm::mat4& modelMatrix, glm::vec3& outHitPosition) { float u; float v; float dist; - bool hit = RayVsModel(ray, modelVertices, modelIndices, dist, u, v); + bool hit = RayVsModel(ray, modelVertices, modelIndices, modelMatrix, dist, u, v); outHitPosition = ray.Origin() + dist * ray.Direction(); return hit; } @@ -572,11 +576,11 @@ boost::optional EntityAbsoluteAABB(EntityWrapper& entity, bool takeM ComponentWrapper& cAABB = entity["AABB"]; modelSpaceBox = EntityAABB::FromOriginSize((glm::vec3)cAABB["Origin"], (glm::vec3)cAABB["Size"]); } else if (entity.HasComponent("Model")) { - Model* model; std::string res = entity["Model"]["Resource"]; if (res.empty()) { return boost::none; } + Model* model; try { model = ResourceManager::Load<::Model, true>(res); } catch (const Resource::StillLoadingException&) { @@ -638,4 +642,36 @@ boost::optional AbsoluteAABBExplosionEffect(EntityWrapper& entity) return aabb; } +boost::optional EntityFirstHitByRay(const Ray& ray, std::vector entitiesPotentiallyHitSorted, float outDistance, glm::vec3& outIntersectPos) +{ + for (EntityAABB& entityBox : entitiesPotentiallyHitSorted) { + if (!entityBox.Entity.HasComponent("Model")) { + continue; + } + std::string res = entityBox.Entity["Model"]["Resource"]; + if (res.empty()) { + continue; + } + Model* model; + try { + model = ResourceManager::Load<::Model, true>(res); + } catch (const std::exception&) { + continue; + } + float u, v; + if (RayVsModel(ray, model->Vertices(), model->m_RawModel->m_Indices, Transform::ModelMatrix(entityBox.Entity), outDistance, u, v)) { + outIntersectPos = ray.Origin() + outDistance * ray.Direction(); + return entityBox; + } + } + return boost::none; +} + +boost::optional EntityFirstHitByRay(const Ray& ray, Octree* octree, float outDistance, glm::vec3& outIntersectPos) +{ + std::vector outObjects; + octree->ObjectsPossiblyHitByRay(ray, outObjects); + return Collision::EntityFirstHitByRay(ray, outObjects, outDistance, outIntersectPos); +} + } \ No newline at end of file diff --git a/src/Engine/Core/Octree.cpp b/src/Engine/Core/Octree.cpp index 7eee1f81..dca06c6f 100644 --- a/src/Engine/Core/Octree.cpp +++ b/src/Engine/Core/Octree.cpp @@ -5,22 +5,6 @@ #include "Core/Octree.h" #include "Collision/Collision.h" -namespace -{ -//To be able to sort nodes based on distance to ray origin. -struct ChildInfo -{ - int Index; - float Distance; -}; - -bool isFirstLower(const ChildInfo& first, const ChildInfo& second) -{ - return first.Distance < second.Distance; -} - -} - namespace OctSpace { @@ -123,14 +107,14 @@ bool Child::RayCollides(const Ray& ray, OctSpace::Output& data) const //If the ray shoots the tree, and it is a parent to 8 children :o if (hasChildren()) { //Sort children according to their distance from the ray origin. - std::vector childInfos; + std::vector childInfos; childInfos.reserve(8); for (int i = 0; i < 8; ++i) { childInfos.push_back({ i, glm::distance(ray.Origin(), m_Children[i]->m_Box.Origin()) }); } std::sort(childInfos.begin(), childInfos.end(), isFirstLower); //Loop through the children, starting with the one closest to the ray origin. I.e the first to be hit. - for (const ChildInfo& info : childInfos) { + for (const RaySorterInfo& info : childInfos) { if (m_Children[info.Index]->RayCollides(ray, data)) { return true; } @@ -275,4 +259,9 @@ std::vector Child::childIndicesContainingBox(const AABB& box) const } } +bool isFirstLower(const RaySorterInfo& first, const RaySorterInfo& second) +{ + return first.Distance < second.Distance; +} + } \ No newline at end of file From 35e4935497910a37711fc744646d05efced90e3e Mon Sep 17 00:00:00 2001 From: Tleety Date: Thu, 11 Feb 2016 10:01:11 +0100 Subject: [PATCH 23/31] Some assets and HUD stuff --- assets | 2 +- .../Schema/Entities/CapturePointHUDGroup | 172 ++++++++++++++++++ .../Schema/Entities/QualityAssurance.xml | 75 ++++---- src/Game/Systems/CapturePointHUDSystem.cpp | 5 +- 4 files changed, 215 insertions(+), 39 deletions(-) create mode 100644 resources/Schema/Entities/CapturePointHUDGroup diff --git a/assets b/assets index 7531e441..0580eeae 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 7531e441fea639076d69c6cf05e3ae8ff7170cf9 +Subproject commit 0580eeae80919127622e16f2ec4f4083668d36cd diff --git a/resources/Schema/Entities/CapturePointHUDGroup b/resources/Schema/Entities/CapturePointHUDGroup new file mode 100644 index 00000000..9dce0ffb --- /dev/null +++ b/resources/Schema/Entities/CapturePointHUDGroup @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 2 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 3 + + + 0.80222018197612788 + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 4 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + 1 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + diff --git a/resources/Schema/Entities/QualityAssurance.xml b/resources/Schema/Entities/QualityAssurance.xml index ce6a650e..2c77bc30 100644 --- a/resources/Schema/Entities/QualityAssurance.xml +++ b/resources/Schema/Entities/QualityAssurance.xml @@ -40,7 +40,7 @@ - + @@ -180,7 +180,7 @@ - + @@ -671,7 +671,7 @@ - + @@ -718,7 +718,7 @@ - + @@ -778,7 +778,7 @@ - + @@ -825,7 +825,7 @@ - + @@ -871,7 +871,7 @@ - + @@ -918,7 +918,7 @@ - + @@ -965,7 +965,7 @@ - + @@ -1023,6 +1023,7 @@ + 15 Models/Core/UnitCube.mesh @@ -1162,7 +1163,6 @@ - -12.033302729641917 3 @@ -1212,6 +1212,7 @@ + -15 4 @@ -1378,7 +1379,7 @@ - + @@ -1387,7 +1388,7 @@ true - 0.75158864645285173 + 0.75184169309215043 3.7999999523162842 true @@ -1434,7 +1435,7 @@ - + @@ -1443,7 +1444,7 @@ - 1.2014943970669589 + 1.2017474437062576 Models/Characters/Assault/AssaultTPose.mesh @@ -1486,7 +1487,7 @@ - + @@ -1497,7 +1498,7 @@ true - 0.68494018072689011 + 0.68519322736618882 true @@ -1542,7 +1543,7 @@ - + @@ -1552,7 +1553,7 @@ true - 0.95103870157425385 + 0.95129174821355256 10 3 @@ -1600,7 +1601,7 @@ - + @@ -1610,7 +1611,7 @@ true - 1.3510669629503185 + 1.3513200095896172 true 5 true @@ -1791,7 +1792,7 @@ true - 1.3677400229854642 + 1.3679930696247629 3.7999999523162842 true @@ -1965,7 +1966,7 @@ Textures/Core/UnitHexagon.png - + @@ -1978,7 +1979,7 @@ 2 - 0.5 + Textures/Core/UnitHexagon_Rotated.png @@ -1986,7 +1987,7 @@ - + @@ -1997,7 +1998,7 @@ Textures/Core/UnitHexagon.png - + @@ -2010,7 +2011,7 @@ 3 - 0.5 + Textures/Core/UnitHexagon_Rotated.png @@ -2018,7 +2019,7 @@ - + @@ -2029,7 +2030,7 @@ Textures/Core/UnitHexagon.png - + @@ -2042,7 +2043,8 @@ 4 - 0.5 + 1 + Textures/Core/UnitHexagon_Rotated.png @@ -2050,7 +2052,7 @@ - + @@ -2061,7 +2063,7 @@ Textures/Core/UnitHexagon.png - + @@ -2074,7 +2076,7 @@ 1 - 0.5 + Textures/Core/UnitHexagon_Rotated.png @@ -2082,7 +2084,7 @@ - + @@ -2093,7 +2095,7 @@ Textures/Core/UnitHexagon.png - + @@ -2104,7 +2106,8 @@ - 0.5 + 1 + Textures/Core/UnitHexagon_Rotated.png @@ -2112,7 +2115,7 @@ - + diff --git a/src/Game/Systems/CapturePointHUDSystem.cpp b/src/Game/Systems/CapturePointHUDSystem.cpp index 5c4c2b60..ad8cc63a 100644 --- a/src/Game/Systems/CapturePointHUDSystem.cpp +++ b/src/Game/Systems/CapturePointHUDSystem.cpp @@ -13,7 +13,7 @@ CapturePointHUDSystem::CapturePointHUDSystem(World* world, EventBroker* eventBro void CapturePointHUDSystem::Update(double dt) { - bool LoadCheck = false; + bool LoadCheck = true; int redTeam; int blueTeam; int spectatorTeam; @@ -32,10 +32,11 @@ void CapturePointHUDSystem::Update(double dt) //Check if the HUD corresponds to the Capture Point Number if (HUD_ID == (int)entityCP["CapturePoint"]["CapturePointNumber"]) { ComponentWrapper& teamComponent = entityCP["Team"]; - if (!LoadCheck) { + if (LoadCheck) { redTeam = (int)teamComponent["Team"].Enum("Red"); blueTeam = (int)teamComponent["Team"].Enum("Blue"); spectatorTeam = (int)teamComponent["Team"].Enum("Spectator"); + LoadCheck = false; } //Color hud with team color auto capturePointTeam = (int)teamComponent["Team"]; From 350effd8ebc045f1614e3a1422f99d3d62fe8758 Mon Sep 17 00:00:00 2001 From: Tleety Date: Thu, 11 Feb 2016 11:32:51 +0100 Subject: [PATCH 24/31] New assets and some QA map stuff --- assets | 2 +- .../Schema/Entities/QualityAssurance.xml | 59 +++++++++++++------ 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/assets b/assets index 0580eeae..8ffd0a99 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 0580eeae80919127622e16f2ec4f4083668d36cd +Subproject commit 8ffd0a99b9a2e5c140307d382a25c4a470cc8f33 diff --git a/resources/Schema/Entities/QualityAssurance.xml b/resources/Schema/Entities/QualityAssurance.xml index 2c77bc30..40951468 100644 --- a/resources/Schema/Entities/QualityAssurance.xml +++ b/resources/Schema/Entities/QualityAssurance.xml @@ -180,7 +180,7 @@ - + @@ -671,7 +671,7 @@ - + @@ -718,7 +718,7 @@ - + @@ -778,7 +778,7 @@ - + @@ -825,7 +825,7 @@ - + @@ -871,7 +871,7 @@ - + @@ -918,7 +918,7 @@ - + @@ -965,7 +965,7 @@ - + @@ -1379,7 +1379,7 @@ - + @@ -1388,7 +1388,7 @@ true - 0.75184169309215043 + 0.75205058136495551 3.7999999523162842 true @@ -1435,7 +1435,7 @@ - + @@ -1444,7 +1444,7 @@ - 1.2017474437062576 + 1.2019563319790627 Models/Characters/Assault/AssaultTPose.mesh @@ -1487,7 +1487,7 @@ - + @@ -1498,7 +1498,7 @@ true - 0.68519322736618882 + 0.68540211563899389 true @@ -1543,7 +1543,7 @@ - + @@ -1553,7 +1553,7 @@ true - 0.95129174821355256 + 0.95150063648635763 10 3 @@ -1601,7 +1601,7 @@ - + @@ -1611,7 +1611,7 @@ true - 1.3513200095896172 + 1.3515288978624223 true 5 true @@ -1792,7 +1792,7 @@ true - 1.3679930696247629 + 1.3682019578975679 3.7999999523162842 true @@ -2124,6 +2124,27 @@ + + + + + + + + + + + + Models/Widgets/Camera.mesh + + + + + + + + + From e350074cb579a84b47445035088cd821a52a2b2f Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Thu, 11 Feb 2016 11:36:15 +0100 Subject: [PATCH 25/31] Spawner now spawns with orientation --- src/Game/Systems/SpawnerSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Game/Systems/SpawnerSystem.cpp b/src/Game/Systems/SpawnerSystem.cpp index ba0775a3..99f5df93 100644 --- a/src/Game/Systems/SpawnerSystem.cpp +++ b/src/Game/Systems/SpawnerSystem.cpp @@ -51,7 +51,7 @@ EntityWrapper SpawnerSystem::Spawn(EntityWrapper spawner, EntityWrapper parent / // Set its position and orientation to that of the SpawnPoint spawnedEntity["Transform"]["Position"] = Transform::AbsolutePosition(spawnPoint.World, spawnPoint.ID); // TODO: Quaternions, bitch - //spawnedEntity["Transform"]["Orientation"] = glm::eulerAngles(Transform::AbsoluteOrientation(spawnPoint.World, spawnPoint.ID)); + spawnedEntity["Transform"]["Orientation"] = glm::eulerAngles(Transform::AbsoluteOrientation(spawnPoint)); return spawnedEntity; } From 81943516a96ca1ef7cb0a769771a77e24acf0fc2 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Thu, 11 Feb 2016 11:36:39 +0100 Subject: [PATCH 26/31] Protected inheritance, not even once. --- include/Engine/Core/System.h | 4 +- include/Game/Systems/SoundSystem.h | 2 - include/Game/Systems/WeaponSystem.h | 79 +++++++------------------- resources/Schema/Entities/Player.xml | 13 +++-- src/Engine/Rendering/RenderSystem.cpp | 2 +- src/Game/Systems/PlayerSpawnSystem.cpp | 2 +- src/Game/Systems/SoundSystem.cpp | 11 ---- src/Game/Systems/WeaponSystem.cpp | 17 +++--- 8 files changed, 38 insertions(+), 92 deletions(-) diff --git a/include/Engine/Core/System.h b/include/Engine/Core/System.h index 43438fd5..1a387855 100644 --- a/include/Engine/Core/System.h +++ b/include/Engine/Core/System.h @@ -34,7 +34,7 @@ protected: , IsServer(params.IsServer) { if (IsClient) { - EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &System::OnPlayerSpawned); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &System::setLocalPlayer); } } virtual ~System() = default; @@ -47,7 +47,7 @@ protected: private: EventRelay m_EPlayerSpawned; - bool OnPlayerSpawned(Events::PlayerSpawned& e) + virtual bool setLocalPlayer(Events::PlayerSpawned& e) { if (e.PlayerID == -1) { LocalPlayer = e.Player; diff --git a/include/Game/Systems/SoundSystem.h b/include/Game/Systems/SoundSystem.h index 410ba2f1..962eb085 100644 --- a/include/Game/Systems/SoundSystem.h +++ b/include/Game/Systems/SoundSystem.h @@ -52,8 +52,6 @@ private: bool OnDashAbility(const Events::DashAbility &e); EventRelay m_ETriggerTouch; bool OnTriggerTouch(const Events::TriggerTouch &e); - EventRelay m_EShoot; - bool OnShoot(const Events::Shoot &e); EventRelay m_ECaptured; bool OnCaptured(const Events::Captured &e); EventRelay m_EPlayerDamage; diff --git a/include/Game/Systems/WeaponSystem.h b/include/Game/Systems/WeaponSystem.h index c3daeceb..b118b8cd 100644 --- a/include/Game/Systems/WeaponSystem.h +++ b/include/Game/Systems/WeaponSystem.h @@ -16,6 +16,7 @@ #include "Core/Octree.h" #include "Collision/EntityAABB.h" #include "Systems/SpawnerSystem.h" +#include "Sound/EPlaySoundOnEntity.h" class WeaponBehaviour; @@ -45,7 +46,7 @@ private: void selectWeapon(EntityWrapper player, ComponentInfo::EnumType slot); }; -class WeaponBehaviour : protected System +class WeaponBehaviour : public System { public: WeaponBehaviour(SystemParams systemParams, Octree* collisionOctree, EntityWrapper weaponEntity) @@ -73,10 +74,7 @@ class AssaultWeaponBehaviour : public WeaponBehaviour public: AssaultWeaponBehaviour(SystemParams systemParams, Octree* collisionOctree, EntityWrapper weaponEntity) : WeaponBehaviour(systemParams, collisionOctree, weaponEntity) - { - m_RayRed = ResourceManager::Load("Schema/Entities/RayRed.xml"); - m_RayBlue = ResourceManager::Load("Schema/Entities/RayBlue.xml"); - } + { } virtual void Fire() override { @@ -145,12 +143,17 @@ private: // Fire magAmmo -= 1; spawnTracer(); + playSound(); m_TimeSinceLastFire = 0.0; } void spawnTracer() { + if (!IsClient) { + return; + } + EntityWrapper spawner; if (m_Entity == LocalPlayer) { spawner = m_Entity.FirstChildByName("WeaponMuzzle"); @@ -165,60 +168,6 @@ private: Events::SpawnerSpawn e; e.Spawner = spawner; m_EventBroker->Publish(e); - - //ComponentWrapper cTeam = m_Entity["Team"]; - //ComponentInfo::EnumType team = cTeam["Team"]; - - //// Select the right color of effect - //EntityFile* rayFile = nullptr; - //if (team == cTeam["Team"].Enum("Red")) { - // rayFile = m_RayRed; - //} - //if (team == cTeam["Team"].Enum("Blue")) { - // rayFile = m_RayBlue; - //} - //if (rayFile == nullptr) { - // return; - //} - - //// Create the entity - //EntityFileParser parser(rayFile); - //EntityID rayID = parser.MergeEntities(m_World); - //EntityWrapper ray(m_World, rayID); - - //// Figure out where to put it - //EntityWrapper attachment; - //if (m_Entity == LocalPlayer || true) { - // // Spawn the effect from the weapon view model for the local player - // attachment = m_Entity.FirstChildByName("WeaponMuzzle"); - //} - //// TODO: Spawn the effect from the weapon world model once it exists - - //glm::mat4 transformation = Transform::AbsoluteTransformation(attachment); - //glm::vec3 _scale; - //glm::vec3 translation; - //glm::quat _orientation; - //glm::vec3 _skew; - //glm::vec4 _perspective; - //glm::decompose(transformation, _scale, _orientation, translation, _skew, _perspective); - // - //// Matrix to euler angles - //glm::vec3 euler; - //euler.y = glm::asin(-transformation[0][2]); - //if (cos(euler.y) != 0) { - // euler.x = atan2(transformation[1][2], transformation[2][2]); - // euler.z = atan2(transformation[0][1], transformation[0][0]); - //} else { - // euler.x = atan2(-transformation[2][0], transformation[1][1]); - // euler.z = 0; - //} - - //// TODO: Spread? - - //(glm::vec3&)ray["Transform"]["Position"] = translation; - //(glm::vec3&)ray["Transform"]["Orientation"] = euler; - //glm::vec3& scale = ray["Transform"]["Scale"]; - //scale.z = traceRayDistance(translation, glm::quat(euler) * glm::vec3(0.f, 0.f, -1.f)); } float traceRayDistance(glm::vec3 origin, glm::vec3 direction) @@ -226,6 +175,18 @@ private: // TODO: Cast a ray and size tracer appropriately return 100.f; } + + void playSound() + { + if (!IsClient) { + return; + } + + Events::PlaySoundOnEntity e; + e.EmitterID = m_Entity.ID; + e.FilePath = "Audio/laser/laser1.wav"; + m_EventBroker->Publish(e); + } }; #endif \ No newline at end of file diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 423e729e..4ba23a0d 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -107,7 +107,7 @@ Idle - 0.24743387388836702 + 0.52743271827223559 1 @@ -126,8 +126,8 @@ Models/Weapons/Blue/AssaultWeaponBlue.mesh - - + + @@ -137,7 +137,7 @@ Schema/Entities/RayBlue.xml - + @@ -166,6 +166,7 @@ Idle + 0.69666320633760392 1 @@ -189,8 +190,8 @@ Models/Weapons/Blue/AssaultWeaponBlue.mesh - - + + diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 36baea0d..18eab0fa 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -67,7 +67,7 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs) // Hide things parented to local player if they have the HiddenFromLocalPlayer component if ((entity.HasComponent("HiddenForLocalPlayer") || entity.FirstParentWithComponent("HiddenForLocalPlayer").Valid()) && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer))) { - //continue; + continue; } Model* model; diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index 2afb0de1..507ed0f5 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -91,7 +91,7 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e) if (cameraEntity.Valid()) { Events::SetCamera e; e.CameraEntity = cameraEntity; - //m_EventBroker->Publish(e); + m_EventBroker->Publish(e); } // HACK: Set the player model color to team color diff --git a/src/Game/Systems/SoundSystem.cpp b/src/Game/Systems/SoundSystem.cpp index a16e39a0..10dc61f7 100644 --- a/src/Game/Systems/SoundSystem.cpp +++ b/src/Game/Systems/SoundSystem.cpp @@ -3,7 +3,6 @@ SoundSystem::SoundSystem(SystemParams params) : System(params) , PureSystem("SoundEmitter") - //, ImpureSystem() { ConfigFile* config = ResourceManager::Load("Config.ini"); m_Announcer = ResourceManager::Load("Config.ini")->Get("Sound.Announcer", "female"); @@ -11,7 +10,6 @@ SoundSystem::SoundSystem(SystemParams params) EVENT_SUBSCRIBE_MEMBER(m_InputCommand, &SoundSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &SoundSystem::OnDoubleJump); EVENT_SUBSCRIBE_MEMBER(m_EDashAbility, &SoundSystem::OnDashAbility); - EVENT_SUBSCRIBE_MEMBER(m_EShoot, &SoundSystem::OnShoot); EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &SoundSystem::OnPlayerDamage); EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundSystem::OnCaptured); EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &SoundSystem::OnTriggerTouch); @@ -90,15 +88,6 @@ bool SoundSystem::drumTimer(double dt) } } -bool SoundSystem::OnShoot(const Events::Shoot & e) -{ - Events::PlaySoundOnEntity ev; - ev.EmitterID = LocalPlayer.ID; - ev.FilePath = "Audio/laser/laser1.wav"; - m_EventBroker->Publish(ev); - return true; -} - bool SoundSystem::OnCaptured(const Events::Captured & e) { int homeTeam = (int)m_World->GetComponent(e.CapturePointID, "Team")["Team"]; diff --git a/src/Game/Systems/WeaponSystem.cpp b/src/Game/Systems/WeaponSystem.cpp index 117176c1..eeb7dd00 100644 --- a/src/Game/Systems/WeaponSystem.cpp +++ b/src/Game/Systems/WeaponSystem.cpp @@ -21,13 +21,11 @@ void WeaponSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cPla { // Update potential weapon behaviour for player auto it = m_ActiveWeapons.find(entity); - if (it != m_ActiveWeapons.end()) { - if (it->first.Valid()) { - it->second->Update(dt); - } else { - m_ActiveWeapons.erase(it); - } + if (it == m_ActiveWeapons.end()) { + selectWeapon(entity, 1); } + + m_ActiveWeapons.at(entity)->Update(dt); } bool WeaponSystem::OnInputCommand(Events::InputCommand& e) @@ -45,7 +43,7 @@ bool WeaponSystem::OnInputCommand(Events::InputCommand& e) // Weapon selection if (e.Command == "SelectWeapon") { if (e.Value != 0) { - selectWeapon(player, static_cast(e.Value)); + //selectWeapon(player, static_cast(e.Value)); } } @@ -72,7 +70,7 @@ void WeaponSystem::selectWeapon(EntityWrapper player, ComponentInfo::EnumType sl if (m_ActiveWeapons.count(player) == 0) { m_ActiveWeapons.insert(std::make_pair(player, std::make_shared(m_SystemParams, m_CollisionOctree, player))); } else { - m_ActiveWeapons.erase(player); + //m_ActiveWeapons.erase(player); } } @@ -86,7 +84,6 @@ bool WeaponSystem::OnPlayerSpawned(Events::PlayerSpawned& e) { // Select primary weapon on player spawn // TODO: Select the active one specified by player component - selectWeapon(e.Player, 1); return true; } @@ -137,4 +134,4 @@ bool WeaponSystem::OnShoot(Events::Shoot& eShoot) m_EventBroker->Publish(ePlayerDamage); return true; -} +} \ No newline at end of file From 9f657ada4ebd5ed1177b7ca078c5870c8df5f1a4 Mon Sep 17 00:00:00 2001 From: Tleety Date: Thu, 11 Feb 2016 14:52:52 +0100 Subject: [PATCH 27/31] merge fixes --- include/Game/Systems/CapturePointHUDSystem.h | 2 +- src/Engine/Rendering/DrawFinalPass.cpp | 1 - src/Game/Systems/CapturePointHUDSystem.cpp | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/include/Game/Systems/CapturePointHUDSystem.h b/include/Game/Systems/CapturePointHUDSystem.h index 102c52ce..94be3798 100644 --- a/include/Game/Systems/CapturePointHUDSystem.h +++ b/include/Game/Systems/CapturePointHUDSystem.h @@ -12,7 +12,7 @@ class CapturePointHUDSystem : public ImpureSystem { public: - CapturePointHUDSystem(World* world, EventBroker* eventBroker); + CapturePointHUDSystem(SystemParams params); virtual void Update(double dt) override; diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 42cbd22b..362f2252 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -323,7 +323,6 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightCullingPass->LightGridSSBO()); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightCullingPass->LightIndexSSBO()); - for (auto &job : jobs) { auto explosionEffectJob = std::dynamic_pointer_cast(job); if (explosionEffectJob) { diff --git a/src/Game/Systems/CapturePointHUDSystem.cpp b/src/Game/Systems/CapturePointHUDSystem.cpp index ad8cc63a..c2d62c4b 100644 --- a/src/Game/Systems/CapturePointHUDSystem.cpp +++ b/src/Game/Systems/CapturePointHUDSystem.cpp @@ -1,7 +1,7 @@ #include "Systems/CapturePointHUDSystem.h" -CapturePointHUDSystem::CapturePointHUDSystem(World* world, EventBroker* eventBroker) - : System(world, eventBroker) +CapturePointHUDSystem::CapturePointHUDSystem(SystemParams params) + : System(params) , ImpureSystem() { //subscribe/listenTo playerdamage,healthpickup events (using the eventBroker) From 6ba1e95da77a8c5e7c4d34a6357d2026bab0ea9e Mon Sep 17 00:00:00 2001 From: Tleety Date: Thu, 11 Feb 2016 15:27:07 +0100 Subject: [PATCH 28/31] Fixed depth sorting for HUD elements. --- include/Engine/Rendering/SpriteJob.h | 9 ++++--- include/Game/Systems/CapturePointHUDSystem.h | 27 -------------------- resources/Schema/Components/Sprite.xml | 1 + resources/Schema/Components/Sprite.xsd | 3 +++ src/Engine/Rendering/DrawFinalPass.cpp | 6 ++++- src/Engine/Rendering/RenderSystem.cpp | 4 ++- 6 files changed, 18 insertions(+), 32 deletions(-) diff --git a/include/Engine/Rendering/SpriteJob.h b/include/Engine/Rendering/SpriteJob.h index 2708ab0e..3bb43a1c 100644 --- a/include/Engine/Rendering/SpriteJob.h +++ b/include/Engine/Rendering/SpriteJob.h @@ -17,7 +17,7 @@ struct SpriteJob : RenderJob { - SpriteJob(ComponentWrapper cSprite, Camera* camera, glm::mat4 matrix, World* world, glm::vec4 fillColor, float fillPercentage) + SpriteJob(ComponentWrapper cSprite, Camera* camera, glm::mat4 matrix, World* world, glm::vec4 fillColor, float fillPercentage, bool depthSorted) : RenderJob() { Model = ResourceManager::Load<::Model>("Models/Core/UnitQuad.mesh"); @@ -34,8 +34,11 @@ struct SpriteJob : RenderJob Color = cSprite["Color"]; Entity = cSprite.EntityID; Position = Transform::AbsolutePosition(world, cSprite.EntityID); - glm::vec3 viewpos = glm::vec3(camera->ViewMatrix() * glm::vec4(Position, 1)); - Depth = viewpos.z; + Depth = 0; + if (depthSorted) { + glm::vec3 viewpos = glm::vec3(camera->ViewMatrix() * glm::vec4(Position, 1)); + Depth = viewpos.z; + } World = world; FillColor = fillColor; diff --git a/include/Game/Systems/CapturePointHUDSystem.h b/include/Game/Systems/CapturePointHUDSystem.h index 94be3798..41db0c12 100644 --- a/include/Game/Systems/CapturePointHUDSystem.h +++ b/include/Game/Systems/CapturePointHUDSystem.h @@ -17,33 +17,6 @@ public: virtual void Update(double dt) override; private: - //methods which will take care of specific events - /* EventRelay m_ETriggerTouch; - bool CapturePointSystem::OnTriggerTouch(const Events::TriggerTouch& e); - EventRelay m_ETriggerLeave; - bool CapturePointSystem::OnTriggerLeave(const Events::TriggerLeave& e); - EventRelay m_ECaptured; - bool CapturePointSystem::OnCaptured(const Events::Captured& e);*/ - - //bool m_WinnerWasFound = false; - ////need to track these variables for the captureSystem to work as per design! - //const int m_NotACapturePoint = 999; - //int m_RedTeamNextPossibleCapturePoint = m_NotACapturePoint; - //int m_BlueTeamNextPossibleCapturePoint = m_NotACapturePoint; - //int m_RedTeamHomeCapturePoint = m_NotACapturePoint; - //int m_BlueTeamHomeCapturePoint = m_NotACapturePoint; - - //int m_NumberOfCapturePoints = 0; - //std::map m_CapturePointNumberToEntityMap; - - ////std::vector - - //const double m_CaptureTimeToTakeOver = 15.0; - //bool m_ResetTimers = false; - - ////vectors which will keep track of enter/leave changes - //std::vector> m_ETriggerTouchVector; - //std::vector> m_ETriggerLeaveVector; }; #endif \ No newline at end of file diff --git a/resources/Schema/Components/Sprite.xml b/resources/Schema/Components/Sprite.xml index c2a2057f..ce4a6e1b 100644 --- a/resources/Schema/Components/Sprite.xml +++ b/resources/Schema/Components/Sprite.xml @@ -4,4 +4,5 @@ true + true diff --git a/resources/Schema/Components/Sprite.xsd b/resources/Schema/Components/Sprite.xsd index c8f0c187..3c3d124a 100644 --- a/resources/Schema/Components/Sprite.xsd +++ b/resources/Schema/Components/Sprite.xsd @@ -21,6 +21,9 @@ Whether the model is visible or not + + Whether the sprite should be sorted with depth or not. Only use false for textures that are on HUD + diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 362f2252..83bacd37 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -623,9 +623,13 @@ void DrawFinalPass::DrawSprites(std::list>&jobs, Rend for(auto& job : jobs) { auto spriteJob = std::dynamic_pointer_cast(job); + RenderState jobState; if (spriteJob) { - + if(spriteJob->Depth == 0) + { + jobState.Disable(GL_DEPTH_TEST); + } glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(spriteJob->Matrix)); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index f10e6043..6600bc4f 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -62,6 +62,7 @@ void RenderSystem::fillSprites(std::list>& jobs, Worl std::string diffuseResource = cSprite["DiffuseTexture"]; std::string glowResource = cSprite["GlowMap"]; + bool depthSorted = cSprite["DepthSort"]; if (diffuseResource.empty() && glowResource.empty()) { continue; } @@ -77,7 +78,8 @@ void RenderSystem::fillSprites(std::list>& jobs, Worl glm::mat4 modelMatrix = Transform::ModelMatrix(entity.ID, world); //modelMatrix *= m_Camera->BillboardMatrix(); - std::shared_ptr spriteJob = std::shared_ptr(new SpriteJob(cSprite, m_Camera, modelMatrix, world, fillColor, fillPercentage)); + + std::shared_ptr spriteJob = std::shared_ptr(new SpriteJob(cSprite, m_Camera, modelMatrix, world, fillColor, fillPercentage, depthSorted)); jobs.push_back(spriteJob); } From 7ccaf5b040363df66989c749780b367ac9a16cab Mon Sep 17 00:00:00 2001 From: Tleety Date: Thu, 11 Feb 2016 15:42:27 +0100 Subject: [PATCH 29/31] Removed commeted code --- src/Game/Systems/CapturePointHUDSystem.cpp | 236 +-------------------- 1 file changed, 3 insertions(+), 233 deletions(-) diff --git a/src/Game/Systems/CapturePointHUDSystem.cpp b/src/Game/Systems/CapturePointHUDSystem.cpp index c2d62c4b..784c7e16 100644 --- a/src/Game/Systems/CapturePointHUDSystem.cpp +++ b/src/Game/Systems/CapturePointHUDSystem.cpp @@ -4,10 +4,6 @@ CapturePointHUDSystem::CapturePointHUDSystem(SystemParams params) : System(params) , ImpureSystem() { - //subscribe/listenTo playerdamage,healthpickup events (using the eventBroker) - //EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &CapturePointSystem::OnTriggerTouch); - //EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &CapturePointSystem::OnTriggerLeave); - //EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &CapturePointSystem::OnCaptured); } @@ -21,12 +17,12 @@ void CapturePointHUDSystem::Update(double dt) auto CapturePointHUDElements = m_World->GetComponents("CapturePointHUD"); auto CapturePoints = m_World->GetComponents("CapturePoint"); - for(auto& cCapturePointHUD : *CapturePointHUDElements) { + for (auto& cCapturePointHUD : *CapturePointHUDElements) { int HUD_ID = cCapturePointHUD["CapturePointNumber"]; EntityWrapper entityHUD = EntityWrapper(m_World, cCapturePointHUD.EntityID); EntityWrapper entityHUDparent = entityHUD.Parent(); - for(auto& cCapturePoint : *CapturePoints) { + for (auto& cCapturePoint : *CapturePoints) { EntityWrapper entityCP = EntityWrapper(m_World, cCapturePoint.EntityID); //Check if the HUD corresponds to the Capture Point Number @@ -53,230 +49,4 @@ void CapturePointHUDSystem::Update(double dt) } } } - - //if (m_WinnerWasFound) { - // return; - //} - //const int capturePointNumber = cCapturePoint["CapturePointNumber"]; - //const bool hasTeamComponent = capturePointEntity.HasComponent("Team"); - - ////if point doesnt have a teamComponent yet, add one. since: - ////what if capture point has no team -> we cant get/use the team enum from it... - //if (!hasTeamComponent) { - // m_World->AttachComponent(cCapturePoint.EntityID, "Team"); - // ComponentWrapper& teamComponent = capturePointEntity["Team"]; - // teamComponent["Team"] = (int)teamComponent["Team"].Enum("Spectator"); - //} - //ComponentWrapper& teamComponent = capturePointEntity["Team"]; - //const int redTeam = (int)teamComponent["Team"].Enum("Red"); - //const int blueTeam = (int)teamComponent["Team"].Enum("Blue"); - //const int spectatorTeam = (int)teamComponent["Team"].Enum("Spectator"); - - //int homePointForTeam = (int)cCapturePoint["HomePointForTeam"]; - //if (m_NumberOfCapturePoints == 0 && capturePointNumber != 0 && (homePointForTeam == redTeam || homePointForTeam == blueTeam)) { - // m_NumberOfCapturePoints = capturePointNumber + 1;//ex 2 -> 0,1,2 = 3 - // if (homePointForTeam == redTeam) { - // m_RedTeamHomeCapturePoint = capturePointNumber; - // m_BlueTeamHomeCapturePoint = 0; - // } else { - // m_BlueTeamHomeCapturePoint = capturePointNumber; - // m_RedTeamHomeCapturePoint = 0; - // } - //} - - ////if we havent received all capturepoints yet, just return - //if (m_NumberOfCapturePoints == 0 || m_NumberOfCapturePoints != m_CapturePointNumberToEntityMap.size()) { - // m_CapturePointNumberToEntityMap.insert(std::make_pair(capturePointNumber, capturePointEntity)); - // return; - //} - - ////we have all capturepoints now - process stuff - //int ownedBy = teamComponent["Team"]; - //int redTeamPlayersStandingInside = 0; - //int blueTeamPlayersStandingInside = 0; - //if (capturePointEntity.HasComponent("Model")) { - // //Now sets team color to the capturepoint, or white if it is uncaptured. - // capturePointEntity["Model"]["Color"] = ownedBy == blueTeam ? glm::vec4(0, 0.2f, 1, 0.3) : ownedBy == redTeam ? glm::vec4(1, 0.2f, 0, 0.3) : glm::vec4(1, 1, 1, 0.3); - //} - - ////calculate next possible capturePoint for both teams - //std::map nextPossibleCapturePoint; - //nextPossibleCapturePoint["Red"] = -1; - //nextPossibleCapturePoint["Blue"] = -1; - //for (int i = 0; i < m_NumberOfCapturePoints; i++) - //{ - // if (!m_CapturePointNumberToEntityMap[i].HasComponent("Team")) { - // continue; - // } - // ComponentWrapper& capturePointOwnedBy = m_CapturePointNumberToEntityMap[i]["Team"]; - // if ((int)capturePointOwnedBy["Team"] == redTeam && m_RedTeamHomeCapturePoint == 0) { - // nextPossibleCapturePoint["Red"] = i + 1; - // } - // if ((int)capturePointOwnedBy["Team"] == blueTeam && m_BlueTeamHomeCapturePoint == 0) { - // nextPossibleCapturePoint["Blue"] = i + 1; - // } - //} - //for (int i = m_NumberOfCapturePoints - 1; i >= 0; i--) - //{ - // if (!m_CapturePointNumberToEntityMap[i].HasComponent("Team")) { - // continue; - // } - // ComponentWrapper& capturePointOwnedBy = m_CapturePointNumberToEntityMap[i]["Team"]; - // if ((int)capturePointOwnedBy["Team"] == redTeam && m_RedTeamHomeCapturePoint != 0) { - // nextPossibleCapturePoint["Red"] = i - 1; - // } - // if ((int)capturePointOwnedBy["Team"] == blueTeam && m_BlueTeamHomeCapturePoint != 0) { - // nextPossibleCapturePoint["Blue"] = i - 1; - // } - //} - - ////reset timers and reset the bool that triggers this - //if (m_ResetTimers) { - // for (int i = 0; i < m_NumberOfCapturePoints; i++) - // { - // ComponentWrapper& capturePoint = m_CapturePointNumberToEntityMap[i]["CapturePoint"]; - // if ((int)capturePoint["CapturePointNumber"] != nextPossibleCapturePoint["Red"] && - // (int)capturePoint["CapturePointNumber"] != nextPossibleCapturePoint["Blue"]) { - // capturePoint["CaptureTimer"] = 0.0; - // } - // } - // m_ResetTimers = false; - //} - - ////colorize next possible capturepoint - //if (nextPossibleCapturePoint["Red"] == capturePointNumber) { - // capturePointEntity["Model"]["Color"] = glm::vec4(1, 1, 0, 0.3); - //} - //if (nextPossibleCapturePoint["Blue"] == capturePointNumber) { - // capturePointEntity["Model"]["Color"] = glm::vec4(0, 1, 1, 0.3); - //} - - ////check how many players are standing inside and are healthy - //for (size_t i = m_ETriggerTouchVector.size(); i > 0; i--) - //{ - // auto triggerTouched = m_ETriggerTouchVector[i - 1]; - // if (std::get<1>(triggerTouched) == capturePointEntity) { - // //some player has touched this - lets figure out: what team, health - // EntityWrapper player = std::get<0>(triggerTouched); - // //check if its really a player that has triggered the touch - // if (!player.HasComponent("Player")) { - // //if a non-player has entered the capturePoint, just erase that event and continue - // m_ETriggerTouchVector.erase(m_ETriggerTouchVector.begin() + i - 1); - // continue; - // } - // bool hasHealthComponent = player.HasComponent("Health"); - // if (hasHealthComponent) { - // double currentHealth = player["Health"]["Health"]; - // //check if player is dead - // if ((int)currentHealth == 0) { - // continue; - // } - // } - // //check team - spectatorNumber = "no team" - // int teamNumber = player["Team"]["Team"]; - // if (teamNumber == redTeam) { - // redTeamPlayersStandingInside++; - // } else if (teamNumber == blueTeam) { - // blueTeamPlayersStandingInside++; - // } - // continue; - // } - //} - - ////create data to be used in option B - ////check so this is the next possible capture point for the take-over team and see if only one team is standing inside it - //double timerDeltaChange = 0.0; - //int currentTeam = 0; - //bool canCapture = false; - //if (redTeamPlayersStandingInside > 0 && blueTeamPlayersStandingInside == 0) { - // timerDeltaChange = redTeamPlayersStandingInside*dt; - // currentTeam = redTeam; - // canCapture = nextPossibleCapturePoint["Red"] == capturePointNumber; - //} - //if (redTeamPlayersStandingInside == 0 && blueTeamPlayersStandingInside > 0) { - // timerDeltaChange = -blueTeamPlayersStandingInside*dt; - // currentTeam = blueTeam; - // canCapture = nextPossibleCapturePoint["Blue"] == capturePointNumber; - //} - - //if (redTeamPlayersStandingInside == 0 && blueTeamPlayersStandingInside == 0) { - // //A.nobodys standing inside - // //do nothing (?) - //} else if (redTeamPlayersStandingInside > 0 && blueTeamPlayersStandingInside > 0) { - // //C.both teams have players inside - // //do nothing (?) - //} else { - // //B. at most one of the teams have players inside - // //if capturePoint is not owned by the take-over team, just modify the CaptureTimer accordingly - // if (ownedBy != currentTeam && canCapture) { - // if (abs((double)cCapturePoint["CaptureTimer"]) < 0.001f) { - // LOG_DEBUG("Point is being captured by team %i", currentTeam); //Remove when we tested sufficiently. - // } - // cCapturePoint["CaptureTimer"] = (double)cCapturePoint["CaptureTimer"] + timerDeltaChange; - // } - // //if capturePoint is owned by the team, and the other team has been trying to take it, then increase/decrease the timer towards 0.0 - // if ((ownedBy == currentTeam && currentTeam == redTeam && (double)cCapturePoint["CaptureTimer"] < 0.0) || - // (ownedBy == currentTeam && currentTeam == blueTeam && (double)cCapturePoint["CaptureTimer"] > 0.0)) { - // cCapturePoint["CaptureTimer"] = (double)cCapturePoint["CaptureTimer"] + timerDeltaChange; - // } - // //check if captureTimer > m_CaptureTimeToTakeOver and if so change owner and publish the eCaptured event - // if (abs((double)cCapturePoint["CaptureTimer"]) > abs(m_CaptureTimeToTakeOver) && canCapture) { - // teamComponent["Team"] = currentTeam; - // cCapturePoint["CaptureTimer"] = 0.0; - // //publish Captured event - // LOG_DEBUG("Point is captured by team %i!", currentTeam); //Remove when we tested sufficiently. - // Events::Captured e; - // e.CapturePointID = cCapturePoint.EntityID; - // e.TeamNumberThatCapturedCapturePoint = currentTeam; - // m_EventBroker->Publish(e); - // //NextPossibleCapturePoint will be calculated in the next update... - // } - //} - - ////check for possible winCondition = check if the homebase is owned by the other team - //bool checkForWinner = false; - //if (capturePointNumber == m_RedTeamHomeCapturePoint && ownedBy != redTeam) - //{ - // checkForWinner = true; - //} - //if (capturePointNumber == m_BlueTeamHomeCapturePoint && ownedBy != blueTeam) - //{ - // checkForWinner = true; - //} - - //if (checkForWinner && !m_WinnerWasFound) - //{ - // //publish Win event - // Events::Win e; - // e.TeamThatWon = ownedBy; - // m_EventBroker->Publish(e); - // m_WinnerWasFound = true; - //} - -} -// -//bool CapturePointSystem::OnTriggerTouch(const Events::TriggerTouch& e) -//{ -// //personEntered = e.Entity, thingEntered = e.Trigger -// m_ETriggerTouchVector.push_back(std::make_tuple(e.Entity, e.Trigger)); -// return true; -//} -// -//bool CapturePointSystem::OnTriggerLeave(const Events::TriggerLeave& e) -//{ -// for (size_t i = 0; i < m_ETriggerTouchVector.size(); i++) -// { -// auto triggerTouched = m_ETriggerTouchVector[i]; -// if (std::get<0>(triggerTouched) == e.Entity && std::get<1>(triggerTouched) == e.Trigger) { -// m_ETriggerTouchVector.erase(m_ETriggerTouchVector.begin() + i); -// break; -// } -// } -// return true; -//} -//bool CapturePointSystem::OnCaptured(const Events::Captured& e) -//{ -// //reset the timers in the next update since a capture has changed the "nextCapturePoint" for 1-2 teams -// m_ResetTimers = true; -// return true; -//} +} \ No newline at end of file From 51e0b852d2ef4ddb785a43be8fc4ad864274c596 Mon Sep 17 00:00:00 2001 From: Tleety Date: Thu, 11 Feb 2016 15:43:41 +0100 Subject: [PATCH 30/31] Adamfix --- src/Engine/Rendering/DrawFinalPass.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 83bacd37..5e1d7f6e 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -626,8 +626,7 @@ void DrawFinalPass::DrawSprites(std::list>&jobs, Rend RenderState jobState; if (spriteJob) { - if(spriteJob->Depth == 0) - { + if(spriteJob->Depth == 0) { jobState.Disable(GL_DEPTH_TEST); } glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(spriteJob->Matrix)); From 4e23e7bf3097abd5ff60dbf1468dc89e435ff848 Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Thu, 11 Feb 2016 15:58:58 +0100 Subject: [PATCH 31/31] misc changes do the DoubleJumpHexagon.xml --- resources/Schema/Entities/DoubleJumpHexagon.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/Schema/Entities/DoubleJumpHexagon.xml b/resources/Schema/Entities/DoubleJumpHexagon.xml index bbc41119..c1aaec34 100644 --- a/resources/Schema/Entities/DoubleJumpHexagon.xml +++ b/resources/Schema/Entities/DoubleJumpHexagon.xml @@ -3,8 +3,8 @@ - Models/JumpEffectHexagon.mesh - + Models/Effects/JumpEffectHexagon.mesh + true @@ -12,14 +12,14 @@ - 1.5 + 0.5 true true - 3 + 0.5 true