From 0e9fb16399a648a4571351b579da9e02ecadd135 Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Mon, 8 Feb 2016 17:58:07 +0100 Subject: [PATCH 01/26] Work started on DamageIndicatorSystem. Made some initial tests and test calculations --- include/Engine/Core/EPlayerDamage.h | 1 + include/Game/Systems/DamageIndicatorSystem.h | 41 ++ resources/Schema/Entities/GameMapTest.xml | 430 ++++++++++++++++++ .../Schema/Entities/SpriteTestTemporary.xml | 24 + src/Game/Game.cpp | 2 + src/Game/Systems/DamageIndicatorSystem.cpp | 101 ++++ 6 files changed, 599 insertions(+) create mode 100644 include/Game/Systems/DamageIndicatorSystem.h create mode 100644 resources/Schema/Entities/GameMapTest.xml create mode 100644 resources/Schema/Entities/SpriteTestTemporary.xml create mode 100644 src/Game/Systems/DamageIndicatorSystem.cpp diff --git a/include/Engine/Core/EPlayerDamage.h b/include/Engine/Core/EPlayerDamage.h index 8ba3907e..c11b121f 100644 --- a/include/Engine/Core/EPlayerDamage.h +++ b/include/Engine/Core/EPlayerDamage.h @@ -11,6 +11,7 @@ struct PlayerDamage : Event { //NOTE: this struct is missing information on what the damageSource is EntityWrapper Player; + EntityWrapper PlayerShooter; double Damage; }; diff --git a/include/Game/Systems/DamageIndicatorSystem.h b/include/Game/Systems/DamageIndicatorSystem.h new file mode 100644 index 00000000..646887e2 --- /dev/null +++ b/include/Game/Systems/DamageIndicatorSystem.h @@ -0,0 +1,41 @@ +#ifndef DamageIndicatorSystem_h__ +#define DamageIndicatorSystem_h__ + +#include "Core/System.h" +#include "Core/Transform.h" +#include "Core/ResourceManager.h" +#include "Core/EntityFileParser.h" +#include "Core/EPickupSpawned.h" +#include "Core/EPlayerDamage.h" +#include "Engine/Collision/ETrigger.h" +#include "Common.h" +#include + +//temp +#include "Input/EInputCommand.h" +#include "Rendering/ESetCamera.h" + +#include + +class DamageIndicatorSystem : public ImpureSystem +{ +public: + DamageIndicatorSystem(World* world, EventBroker* eventBroker); + + virtual void Update(double dt) override; + +private: + + EventRelay m_DamageTakenFromPlayer; + bool OnPlayerDamageTaken(Events::PlayerDamage& e); + + //temp + EventRelay m_EInputCommand; + bool OnInputCommand(Events::InputCommand& e); + + EventRelay m_ESetCamera; + bool OnSetCamera(const Events::SetCamera& e); + + EntityID m_CurrentCamera = -1; +}; +#endif diff --git a/resources/Schema/Entities/GameMapTest.xml b/resources/Schema/Entities/GameMapTest.xml new file mode 100644 index 00000000..ee68da96 --- /dev/null +++ b/resources/Schema/Entities/GameMapTest.xml @@ -0,0 +1,430 @@ + + + + + + + + + + + + + + + Models\MapVersion1.mesh + + + + + + + + + 2 + + + Models/DirectionalLightWidget.mesh + false + + + + + + + + + + + + + 8 + 2.7999999523162842 + + + + + + + + + + + 8 + 2.7999999523162842 + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + false + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + false + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 99 + + + + + + 5 + + + + + + + + + + + + + + + + + + + + + + + Fonts/DroidSans.ttf,100 + + + + + + + + + + + + + + Models/Camera.mesh + false + + + + + + + + + + + + + + + + + + + 0.99000000953674316 + + + + + Models/Core/UnitHexagon.mesh + + + + + + + + + + + + + + Models/CrosshairQuad.mesh + + + + + + + + + + + + + Models/AssaultWeaponRed.mesh + + + + + + + + + + + + + + + + + + + + + + + + + Models/Camera.mesh + false + + + + + + + + + + + + Hold Pos + + 1 + + + + Models/AssaultAnimated.mesh + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + + + + diff --git a/resources/Schema/Entities/SpriteTestTemporary.xml b/resources/Schema/Entities/SpriteTestTemporary.xml new file mode 100644 index 00000000..f66e9158 --- /dev/null +++ b/resources/Schema/Entities/SpriteTestTemporary.xml @@ -0,0 +1,24 @@ + + + + + + Textures/DefenderGunRedDiff.png + Textures/DefenderGunRedIncd.png + + + + Models/Core/UnitQuad.mesh + + + + + + + 1.5 + + + + + + diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 0cc41a73..5875bc81 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -12,6 +12,7 @@ #include "Core/EntityFileWriter.h" #include "Game/Systems/CapturePointSystem.h" #include "Game/Systems/PickupSpawnSystem.h" +#include "Game/Systems/DamageIndicatorSystem.h" #include "Game/Systems/WeaponSystem.h" #include "Game/Systems/PlayerHUD.h" #include "Game/Systems/LifetimeSystem.h" @@ -96,6 +97,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); // Populate Octree with collidables ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision, "Collidable"); diff --git a/src/Game/Systems/DamageIndicatorSystem.cpp b/src/Game/Systems/DamageIndicatorSystem.cpp new file mode 100644 index 00000000..5f6ad725 --- /dev/null +++ b/src/Game/Systems/DamageIndicatorSystem.cpp @@ -0,0 +1,101 @@ +#include "Systems/DamageIndicatorSystem.h" + +DamageIndicatorSystem::DamageIndicatorSystem(World* m_World, EventBroker* eventBroker) + : System(m_World, eventBroker) +{ + EVENT_SUBSCRIBE_MEMBER(m_DamageTakenFromPlayer, &DamageIndicatorSystem::OnPlayerDamageTaken); + //TEMP + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &DamageIndicatorSystem::OnInputCommand); + //current camera + EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &DamageIndicatorSystem::OnSetCamera); + +} + +void DamageIndicatorSystem::Update(double dt) +{ + +} + + +bool DamageIndicatorSystem::OnPlayerDamageTaken(Events::PlayerDamage& e) +{ + auto test1 = (glm::vec3)e.PlayerShooter["Transform"]["Orientation"]; + auto test2 = (glm::vec3)e.Player["Transform"]["Orientation"]; + //calculate direction + auto enemyOrientation = glm::quat(((glm::vec3)e.PlayerShooter["Transform"]["Orientation"])); + auto playerOrientation = glm::quat((glm::vec3)e.Player["Transform"]["Orientation"]); + //calculate difference in angle (quaternion math) + auto angle1 = glm::angle(playerOrientation); + auto angle2 = glm::angle(enemyOrientation); + auto quat = glm::angleAxis(angle2 - angle1, glm::vec3(0, 1, 0)); + auto vec3Orientation = glm::eulerAngles(quat); + + //load & set the "2d" sprite + auto entityFile = ResourceManager::Load("Schema/Entities/SpriteTestTemporary.xml"); + EntityFileParser parser(entityFile); + EntityID spriteID = parser.MergeEntities(m_World); + m_World->SetParent(spriteID, m_CurrentCamera); + auto cameraWrapper = EntityWrapper(m_World, spriteID); + cameraWrapper["Transform"]["Orientation"] = vec3Orientation; + + return true; +} + +//TEMP +bool DamageIndicatorSystem::OnInputCommand(Events::InputCommand& e) +{ + if (e.Command != "Jump" || e.Value > 0) { + return false; + } + //auto entityFile = ResourceManager::Load("Schema/Entities/SpriteTestTemporary.xml"); + //EntityFileParser parser(entityFile); + //EntityID spriteID = parser.MergeEntities(m_World); + ////get currently active camera + ////auto cameras = m_World->GetComponents("Camera"); + ////for (auto& cCamera : *cameras) { + //// + //// //auto temp = m_World->GetParent(cCamera.EntityID); + //// m_World->SetParent(spriteID, cCamera.EntityID); + ////} + ////m_CurrentCamera + //m_World->SetParent(spriteID, m_CurrentCamera); + + //auto cameraWrapper = EntityWrapper(m_World, spriteID); + //cameraWrapper["Transform"]["Orientation"] = glm::vec3(1, 1, 1); + //ray player-enemyplayer eller bara spelarnas direction + + + //TODO: life time, rotering +//den ska väl vara där hela tiden, bara det att den inte syns + + + //EntityWrapper(m_World, spriteID); + + auto players = m_World->GetComponents("Player"); + EntityID id1 = (*players->begin()).EntityID; + EntityID id2; + int lameCounter = 0; + for (auto& cPlayers : *players) { + if (lameCounter == 1) { + id2 = cPlayers.EntityID; + } + lameCounter++; + } + if (lameCounter != 2) { + return false; + } + + //do something here + Events::PlayerDamage ePlayerDamage; + ePlayerDamage.Player = EntityWrapper(m_World, id1); + ePlayerDamage.PlayerShooter = EntityWrapper(m_World, id2); + ePlayerDamage.Damage = 1; + m_EventBroker->Publish(ePlayerDamage); + + return true; +} + +bool DamageIndicatorSystem::OnSetCamera(const Events::SetCamera& e) { + m_CurrentCamera = e.CameraEntity.ID; + return true; +} \ No newline at end of file From 971fee4a0cfaa0b9017718a8a9e2ade928bc05f2 Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Tue, 9 Feb 2016 15:38:21 +0100 Subject: [PATCH 02/26] DamageIndicatorSystem code looking good. Test working well. Sprite display fixed by Viktor --- include/Game/Systems/DamageIndicatorSystem.h | 1 + .../Schema/Entities/SpriteTestTemporary.xml | 7 +--- resources/Shaders/Sprite.vert.glsl | 2 +- src/Game/Systems/DamageIndicatorSystem.cpp | 42 +++++++++++++++---- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/include/Game/Systems/DamageIndicatorSystem.h b/include/Game/Systems/DamageIndicatorSystem.h index 646887e2..561654d1 100644 --- a/include/Game/Systems/DamageIndicatorSystem.h +++ b/include/Game/Systems/DamageIndicatorSystem.h @@ -16,6 +16,7 @@ #include "Rendering/ESetCamera.h" #include +#include class DamageIndicatorSystem : public ImpureSystem { diff --git a/resources/Schema/Entities/SpriteTestTemporary.xml b/resources/Schema/Entities/SpriteTestTemporary.xml index f66e9158..2d02443c 100644 --- a/resources/Schema/Entities/SpriteTestTemporary.xml +++ b/resources/Schema/Entities/SpriteTestTemporary.xml @@ -3,13 +3,10 @@ - Textures/DefenderGunRedDiff.png - Textures/DefenderGunRedIncd.png + Textures/TempDamageIndicator.png + Textures/TempDamageIndicator.png - - Models/Core/UnitQuad.mesh - diff --git a/resources/Shaders/Sprite.vert.glsl b/resources/Shaders/Sprite.vert.glsl index e910a26a..61b387ad 100644 --- a/resources/Shaders/Sprite.vert.glsl +++ b/resources/Shaders/Sprite.vert.glsl @@ -16,7 +16,7 @@ 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/Game/Systems/DamageIndicatorSystem.cpp b/src/Game/Systems/DamageIndicatorSystem.cpp index 5f6ad725..24d1cfa4 100644 --- a/src/Game/Systems/DamageIndicatorSystem.cpp +++ b/src/Game/Systems/DamageIndicatorSystem.cpp @@ -21,22 +21,46 @@ bool DamageIndicatorSystem::OnPlayerDamageTaken(Events::PlayerDamage& e) { auto test1 = (glm::vec3)e.PlayerShooter["Transform"]["Orientation"]; auto test2 = (glm::vec3)e.Player["Transform"]["Orientation"]; - //calculate direction - auto enemyOrientation = glm::quat(((glm::vec3)e.PlayerShooter["Transform"]["Orientation"])); + + //grab players direction auto playerOrientation = glm::quat((glm::vec3)e.Player["Transform"]["Orientation"]); - //calculate difference in angle (quaternion math) - auto angle1 = glm::angle(playerOrientation); - auto angle2 = glm::angle(enemyOrientation); - auto quat = glm::angleAxis(angle2 - angle1, glm::vec3(0, 1, 0)); - auto vec3Orientation = glm::eulerAngles(quat); + + //get the position vectors, but ignore the y-height + auto enemyPosition = (glm::vec3) e.PlayerShooter["Transform"]["Position"]; + auto playerPosition = (glm::vec3) e.Player["Transform"]["Position"]; + enemyPosition.y = 0.0f; + playerPosition.y = 0.0f; + + //calculate the enemy to player vector + auto enemyPlayerVector = glm::normalize((glm::vec3) playerPosition - enemyPosition); + + //get angle from players current rotation, this angle is how much you rotate around the y-axis + auto playerAngle = glm::angle(playerOrientation); + auto playerRotationVector = glm::normalize(glm::rotateY(glm::vec3(0, 0, 1), playerAngle)); + + //dot product of players direction-vector and enemys-to-playervector will give the cos of the angle between the vectors + auto playerRotationDot = glm::dot(playerRotationVector, enemyPlayerVector); + //to get the angle between the vectors just do cos-inverse + auto angleBetweenVectors = glm::acos(playerRotationDot); + + //rotate the direction-vector 90 degrees to get the players side-vector + auto playerSideVector = glm::normalize(glm::rotateY(glm::vec3(0, 0, 1), playerAngle + 1.57f)); + //dot of sidevector positive = enemy is on the right side, dot sidevector negative = left side + auto playerSideVectorDot = glm::dot(playerSideVector, enemyPlayerVector); + if (playerSideVectorDot < 0) { + angleBetweenVectors = -angleBetweenVectors; + } + + //LOG_INFO("vector angle %f %f %f %f", t1, t3, t4, enemyPlayerVector.x); //load & set the "2d" sprite auto entityFile = ResourceManager::Load("Schema/Entities/SpriteTestTemporary.xml"); EntityFileParser parser(entityFile); EntityID spriteID = parser.MergeEntities(m_World); m_World->SetParent(spriteID, m_CurrentCamera); - auto cameraWrapper = EntityWrapper(m_World, spriteID); - cameraWrapper["Transform"]["Orientation"] = vec3Orientation; + auto spriteWrapper = EntityWrapper(m_World, spriteID); + //simply set the rotation z-wise to the angleBetweenVectors + spriteWrapper["Transform"]["Orientation"] = glm::vec3(0, 0, angleBetweenVectors); return true; } From 8bdf87da12663aeb6b8b6a23b7288b032411b8f0 Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Tue, 9 Feb 2016 16:15:19 +0100 Subject: [PATCH 03/26] Some cleanup of the code --- include/Game/Systems/DamageIndicatorSystem.h | 14 +--- src/Game/Systems/DamageIndicatorSystem.cpp | 70 +------------------- src/Game/Systems/WeaponSystem.cpp | 1 + 3 files changed, 5 insertions(+), 80 deletions(-) diff --git a/include/Game/Systems/DamageIndicatorSystem.h b/include/Game/Systems/DamageIndicatorSystem.h index 561654d1..fd3ba33f 100644 --- a/include/Game/Systems/DamageIndicatorSystem.h +++ b/include/Game/Systems/DamageIndicatorSystem.h @@ -5,35 +5,23 @@ #include "Core/Transform.h" #include "Core/ResourceManager.h" #include "Core/EntityFileParser.h" -#include "Core/EPickupSpawned.h" #include "Core/EPlayerDamage.h" -#include "Engine/Collision/ETrigger.h" #include "Common.h" #include -//temp -#include "Input/EInputCommand.h" #include "Rendering/ESetCamera.h" - #include #include -class DamageIndicatorSystem : public ImpureSystem +class DamageIndicatorSystem : public System { public: DamageIndicatorSystem(World* world, EventBroker* eventBroker); - virtual void Update(double dt) override; - private: - EventRelay m_DamageTakenFromPlayer; bool OnPlayerDamageTaken(Events::PlayerDamage& e); - //temp - EventRelay m_EInputCommand; - bool OnInputCommand(Events::InputCommand& e); - EventRelay m_ESetCamera; bool OnSetCamera(const Events::SetCamera& e); diff --git a/src/Game/Systems/DamageIndicatorSystem.cpp b/src/Game/Systems/DamageIndicatorSystem.cpp index 24d1cfa4..0acb24c3 100644 --- a/src/Game/Systems/DamageIndicatorSystem.cpp +++ b/src/Game/Systems/DamageIndicatorSystem.cpp @@ -4,23 +4,15 @@ DamageIndicatorSystem::DamageIndicatorSystem(World* m_World, EventBroker* eventB : System(m_World, eventBroker) { EVENT_SUBSCRIBE_MEMBER(m_DamageTakenFromPlayer, &DamageIndicatorSystem::OnPlayerDamageTaken); - //TEMP - EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &DamageIndicatorSystem::OnInputCommand); //current camera EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &DamageIndicatorSystem::OnSetCamera); - } -void DamageIndicatorSystem::Update(double dt) -{ - -} - - bool DamageIndicatorSystem::OnPlayerDamageTaken(Events::PlayerDamage& e) { - auto test1 = (glm::vec3)e.PlayerShooter["Transform"]["Orientation"]; - auto test2 = (glm::vec3)e.Player["Transform"]["Orientation"]; + if (m_CurrentCamera == -1) { + return false; + } //grab players direction auto playerOrientation = glm::quat((glm::vec3)e.Player["Transform"]["Orientation"]); @@ -51,8 +43,6 @@ bool DamageIndicatorSystem::OnPlayerDamageTaken(Events::PlayerDamage& e) angleBetweenVectors = -angleBetweenVectors; } - //LOG_INFO("vector angle %f %f %f %f", t1, t3, t4, enemyPlayerVector.x); - //load & set the "2d" sprite auto entityFile = ResourceManager::Load("Schema/Entities/SpriteTestTemporary.xml"); EntityFileParser parser(entityFile); @@ -65,60 +55,6 @@ bool DamageIndicatorSystem::OnPlayerDamageTaken(Events::PlayerDamage& e) return true; } -//TEMP -bool DamageIndicatorSystem::OnInputCommand(Events::InputCommand& e) -{ - if (e.Command != "Jump" || e.Value > 0) { - return false; - } - //auto entityFile = ResourceManager::Load("Schema/Entities/SpriteTestTemporary.xml"); - //EntityFileParser parser(entityFile); - //EntityID spriteID = parser.MergeEntities(m_World); - ////get currently active camera - ////auto cameras = m_World->GetComponents("Camera"); - ////for (auto& cCamera : *cameras) { - //// - //// //auto temp = m_World->GetParent(cCamera.EntityID); - //// m_World->SetParent(spriteID, cCamera.EntityID); - ////} - ////m_CurrentCamera - //m_World->SetParent(spriteID, m_CurrentCamera); - - //auto cameraWrapper = EntityWrapper(m_World, spriteID); - //cameraWrapper["Transform"]["Orientation"] = glm::vec3(1, 1, 1); - //ray player-enemyplayer eller bara spelarnas direction - - - //TODO: life time, rotering -//den ska väl vara där hela tiden, bara det att den inte syns - - - //EntityWrapper(m_World, spriteID); - - auto players = m_World->GetComponents("Player"); - EntityID id1 = (*players->begin()).EntityID; - EntityID id2; - int lameCounter = 0; - for (auto& cPlayers : *players) { - if (lameCounter == 1) { - id2 = cPlayers.EntityID; - } - lameCounter++; - } - if (lameCounter != 2) { - return false; - } - - //do something here - Events::PlayerDamage ePlayerDamage; - ePlayerDamage.Player = EntityWrapper(m_World, id1); - ePlayerDamage.PlayerShooter = EntityWrapper(m_World, id2); - ePlayerDamage.Damage = 1; - m_EventBroker->Publish(ePlayerDamage); - - return true; -} - bool DamageIndicatorSystem::OnSetCamera(const Events::SetCamera& e) { m_CurrentCamera = e.CameraEntity.ID; return true; diff --git a/src/Game/Systems/WeaponSystem.cpp b/src/Game/Systems/WeaponSystem.cpp index 1613cb7a..bc7c86b6 100644 --- a/src/Game/Systems/WeaponSystem.cpp +++ b/src/Game/Systems/WeaponSystem.cpp @@ -134,6 +134,7 @@ bool WeaponSystem::OnShoot(Events::Shoot& eShoot) // TODO: Weapon damage calculations etc Events::PlayerDamage ePlayerDamage; ePlayerDamage.Player = player; + ePlayerDamage.PlayerShooter = eShoot.Player; ePlayerDamage.Damage = 100; m_EventBroker->Publish(ePlayerDamage); From e9f5a3d263bc6a00b7526db945732e7dcfc448d0 Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Tue, 9 Feb 2016 16:28:43 +0100 Subject: [PATCH 04/26] Renamed some files from temporary filenames to DamageIndicator filenames --- .../Entities/{SpriteTestTemporary.xml => DamageIndicator.xml} | 0 .../Entities/{GameMapTest.xml => DamageIndicatorTest.xml} | 0 src/Game/Systems/DamageIndicatorSystem.cpp | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) rename resources/Schema/Entities/{SpriteTestTemporary.xml => DamageIndicator.xml} (100%) rename resources/Schema/Entities/{GameMapTest.xml => DamageIndicatorTest.xml} (100%) diff --git a/resources/Schema/Entities/SpriteTestTemporary.xml b/resources/Schema/Entities/DamageIndicator.xml similarity index 100% rename from resources/Schema/Entities/SpriteTestTemporary.xml rename to resources/Schema/Entities/DamageIndicator.xml diff --git a/resources/Schema/Entities/GameMapTest.xml b/resources/Schema/Entities/DamageIndicatorTest.xml similarity index 100% rename from resources/Schema/Entities/GameMapTest.xml rename to resources/Schema/Entities/DamageIndicatorTest.xml diff --git a/src/Game/Systems/DamageIndicatorSystem.cpp b/src/Game/Systems/DamageIndicatorSystem.cpp index 0acb24c3..638307bf 100644 --- a/src/Game/Systems/DamageIndicatorSystem.cpp +++ b/src/Game/Systems/DamageIndicatorSystem.cpp @@ -44,7 +44,7 @@ bool DamageIndicatorSystem::OnPlayerDamageTaken(Events::PlayerDamage& e) } //load & set the "2d" sprite - auto entityFile = ResourceManager::Load("Schema/Entities/SpriteTestTemporary.xml"); + auto entityFile = ResourceManager::Load("Schema/Entities/DamageIndicator.xml"); EntityFileParser parser(entityFile); EntityID spriteID = parser.MergeEntities(m_World); m_World->SetParent(spriteID, m_CurrentCamera); From 4b8f4981a36f819512c1faf535bd29f5d6dd2c4f Mon Sep 17 00:00:00 2001 From: antc13 Date: Thu, 11 Feb 2016 00:05:27 +0100 Subject: [PATCH 05/26] New Map with Meshes, WIP. --- assets | 2 +- resources/Schema/Entities/NewMap.xml | 1287 +++++++- resources/Schema/Entities/NewMapBackup.xml | 3222 ++++++++++++++++++++ resources/Schema/Entities/StoneWall.xml | 147 + 4 files changed, 4591 insertions(+), 67 deletions(-) create mode 100644 resources/Schema/Entities/NewMapBackup.xml create mode 100644 resources/Schema/Entities/StoneWall.xml diff --git a/assets b/assets index e0ad8b8d..c56f6380 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit e0ad8b8d45a79b8f17876f9541cc5e03758ae16c +Subproject commit c56f6380ab05c23419beafe14190013d1432e32c diff --git a/resources/Schema/Entities/NewMap.xml b/resources/Schema/Entities/NewMap.xml index a79fee7b..8a5227aa 100644 --- a/resources/Schema/Entities/NewMap.xml +++ b/resources/Schema/Entities/NewMap.xml @@ -134,7 +134,7 @@ - + @@ -199,7 +199,7 @@ Models/Props/Pillars/SciFiPillar1.mesh - + @@ -213,7 +213,7 @@ Models/Props/Pillars/SciFiPillar1.mesh - + @@ -292,7 +292,7 @@ Models/Props/Pillars/SciFiPillar2.mesh - + @@ -338,7 +338,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -363,7 +363,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -388,7 +388,8 @@ Models/Props/Walls/BigWall.mesh - + + @@ -413,7 +414,8 @@ Models/Props/Walls/BigWall.mesh - + + @@ -438,7 +440,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -713,8 +715,8 @@ Models/Props/Walls/MediumWall3.mesh - - + + @@ -725,7 +727,7 @@ Models/Props/Walls/MediumWall3.mesh - + @@ -737,7 +739,7 @@ Models/Props/Walls/MediumWall3.mesh - + @@ -801,7 +803,8 @@ Models/Props/Walls/BigWall.mesh - + + @@ -813,7 +816,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -966,7 +969,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -1136,6 +1139,247 @@ + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + Models/Props/Walls/SpecialWall1.mesh + + + + + + + + + + + + + Models/Props/Flora/SpecialRoot.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + @@ -1150,8 +1394,8 @@ Models/Props/Bridges/WoodenBridge.mesh - - + + @@ -1178,8 +1422,8 @@ Models/Props/Bridges/WoodenBridge.mesh - - + + @@ -1205,12 +1449,118 @@ Models/Props/Bridges/SciFiBridge.mesh - + - + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + @@ -1254,7 +1604,7 @@ Models/Props/Pillars/SciFiBridgePillar1.mesh - + @@ -1506,7 +1856,7 @@ true - + @@ -1517,7 +1867,7 @@ true - + @@ -1529,7 +1879,7 @@ true - + @@ -1541,7 +1891,7 @@ true - + @@ -1553,7 +1903,7 @@ true - + @@ -1565,7 +1915,7 @@ true - + @@ -1612,6 +1962,227 @@ + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + Models/Props/Flora/SpecialRoot.mesh + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + @@ -1679,7 +2250,8 @@ Models/Props/Stones/MediumStone1.mesh - + + @@ -1717,8 +2289,8 @@ Models/Props/Stones/MediumStone1.mesh - - + + @@ -1730,8 +2302,8 @@ Models/Props/Stones/MediumStone1.mesh - - + + @@ -1756,7 +2328,7 @@ Models/Props/Stones/MediumStone1.mesh - + @@ -1768,21 +2340,8 @@ Models/Props/Stones/MediumStone1.mesh - - - - - - - - - - - Models/Props/Stones/BigStone.mesh - - - - + + @@ -1794,7 +2353,7 @@ Models/Props/Stones/MediumStone1.mesh - + @@ -1819,7 +2378,7 @@ Models/Props/Stones/MediumStone1.mesh - + @@ -2093,6 +2652,226 @@ + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystal.mesh + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystal.mesh + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystal.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + @@ -2107,7 +2886,7 @@ Models/Props/PickUps/PickUpHolder.mesh - + @@ -2184,6 +2963,168 @@ + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + + + @@ -2193,9 +3134,6 @@ - - - @@ -2203,7 +3141,8 @@ Models/Props/CapturePoint.mesh - + + true @@ -2219,13 +3158,13 @@ - 1 Models/Props/CapturePoint.mesh - + + true @@ -2237,12 +3176,13 @@ - 2 Models/Props/CapturePoint.mesh + + true @@ -2254,13 +3194,13 @@ - 3 Models/Props/CapturePoint.mesh - + + true @@ -2272,7 +3212,6 @@ - @@ -2281,7 +3220,8 @@ Models/Props/CapturePoint.mesh - + + true @@ -2373,7 +3313,7 @@ 1 - + @@ -2386,11 +3326,226 @@ Models/Characters/Assault/AssaultTPose.mesh - + + + + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + + + + diff --git a/resources/Schema/Entities/NewMapBackup.xml b/resources/Schema/Entities/NewMapBackup.xml new file mode 100644 index 00000000..15ec64cf --- /dev/null +++ b/resources/Schema/Entities/NewMapBackup.xml @@ -0,0 +1,3222 @@ + + + + + + + + + + + + + + + + + + Models/Props/Ground.mesh + + + + + + + + + Models/Props/Highground1.mesh + + + + + + + + + + Models/Props/Highground2.mesh + + + + + + + + + + Models/Props/Highground1.mesh + + + + + + + + + + + + Models/Props/Highground2.mesh + + + + + + + + + + + + Models/Props/Highground3.mesh + + + + + + + + + + Models/Props/Highground4.mesh + + + + + + + + + + Models/Props/Highground5.mesh + + + + + + + + + + Models/Props/Highground6.mesh + + + + + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar1.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar1.mesh + + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar3.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar1.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar1.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar3.mesh + + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2.mesh + + + + + + + + + + + + + Models/Props/Pillars/SciFiPillar2.mesh + + + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + Models/Props/Pillars/StonePillar.mesh + + + + + + + + + + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall4.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/SmallWall4.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall4.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + Models/Props/Walls/SmallWall2.mesh + + + + + + + + + + + + Models/Props/Walls/BigWall.mesh + + + + + + + + + + + + + + Models/Props/Walls/SmallWall3.mesh + + + + + + + + + + + + Models/Props/Walls/SpecialWall1.mesh + + + + + + + + + + + + + Models/Props/Flora/SpecialRoot.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Bridges/WoodenBridge.mesh + + + + + + + + + + + + + + Models/Props/Bridges/WoodenBridge.mesh + + + + + + + + + + + + + + Models/Props/Bridges/WoodenBridge.mesh + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge.mesh + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridge.mesh + + + + + + + + + + + + + + Models/Props/Flora/TreeLog.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + Models/Props/Walls/MediumWall2.mesh + + + + + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + Models/Props/Walls/MediumWall3.mesh + + + + + + + + + + + + + + Models/Props/Pillars/SciFiBridgePillar1.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + Models/Props/Walls/MediumWall1.mesh + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + + Models/Props/Flora/TreeLog.mesh + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + Models/Props/Flora/SpecialRoot.mesh + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + Models/Props/Flora/AliveBush.mesh + true + + + + + + + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + + Models/Props/Stones/BigStone.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystal.mesh + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystal.mesh + + + + + + + + + + + + + Models/Props/Stones/ShinyStoneCrystal.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + Models/Props/PickUps/PickUpHolder.mesh + + + + + + + + + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + Models/Props/Stones/AssaultHolder.mesh + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Models/Props/CapturePoint.mesh + + true + + + + + + + + + + + + + + + + + + 1 + + + Models/Props/CapturePoint.mesh + + true + + + + + + + + + + + + + + 2 + + + Models/Props/CapturePoint.mesh + + true + + + + + + + + + + + + + + 3 + + + Models/Props/CapturePoint.mesh + + true + + + + + + + + + + + + + + + + + 4 + + + Models/Props/CapturePoint.mesh + + true + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + + + + + + + 10 + + + + + + + + + + 10 + + + + + + + + + + + + + 10 + + + + + + + + + + + 10 + + + + + + + + + + + 10 + + + + + + + + + + + 1 + + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + + + + + + + + + + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + + + + + + + + + + + + Models/Characters/Assault/AssaultTPose.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + + + + + + + diff --git a/resources/Schema/Entities/StoneWall.xml b/resources/Schema/Entities/StoneWall.xml new file mode 100644 index 00000000..e578d339 --- /dev/null +++ b/resources/Schema/Entities/StoneWall.xml @@ -0,0 +1,147 @@ + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + + + Models/Props/Stones/MediumStone1.mesh + + + + + + + + + + + From 73f59b89ccce4709376beb9cc5273f68afc71178 Mon Sep 17 00:00:00 2001 From: William Moberg Date: Thu, 11 Feb 2016 00:11:37 +0100 Subject: [PATCH 06/26] 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 607150189c7a4717b0be98b167bab6ccf1ffaab1 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Thu, 11 Feb 2016 10:51:11 +0100 Subject: [PATCH 07/26] Different animations can now be played on multiple meshes, AnimationOffset seems to make the lighting buggy --- include/Engine/Rendering/ModelJob.h | 30 +- include/Engine/Rendering/Skeleton.h | 33 +- resources/Schema/Entities/AnimationTests2.xml | 87 ++++- resources/Schema/Entities/AnimationTests3.xml | 75 ++-- src/Engine/Rendering/AnimationSystem.cpp | 27 -- src/Engine/Rendering/BoneAttachmentSystem.cpp | 5 +- src/Engine/Rendering/DrawFinalPass.cpp | 48 ++- src/Engine/Rendering/PickingPass.cpp | 24 +- src/Engine/Rendering/Skeleton.cpp | 328 +++++++++--------- 9 files changed, 380 insertions(+), 277 deletions(-) diff --git a/include/Engine/Rendering/ModelJob.h b/include/Engine/Rendering/ModelJob.h index 4bb1b51f..ba801f60 100644 --- a/include/Engine/Rendering/ModelJob.h +++ b/include/Engine/Rendering/ModelJob.h @@ -120,6 +120,32 @@ struct ModelJob : RenderJob if (model->IsSkinned()) { 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; + } + } } }; @@ -140,8 +166,8 @@ struct ModelJob : RenderJob glm::vec4 Color; const ::Model* Model = nullptr; ::Skeleton* Skeleton = nullptr; - // const ::Skeleton::Animation* Animation = nullptr; - + std::vector<::Skeleton::AnimationData> Animations; + ::Skeleton::AnimationOffset AnimationOffset; diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index a8dd982d..ccf3e2b4 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -100,13 +100,13 @@ public: int GetBoneID(std::string name); - void CalculateFrameBones(std::vector animations, AnimationOffset animationOffset, bool noRootMotion = false); - void CalculateFrameBones(std::vector animations, bool noRootMotion = false); + std::vector GetFrameBones(std::vector animations, AnimationOffset animationOffset, bool noRootMotion = false); + std::vector GetFrameBones(std::vector animations, bool noRootMotion = false); 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 AccumulateBoneTransforms(bool noRootMotion, std::vector animations, std::map& frameBones, const Bone* bone, glm::mat4 parentMatrix); + void AccumulateBoneTransforms(bool noRootMotion, std::vector animations, AnimationOffset animationOffset, std::map& frameBones, const Bone* bone, glm::mat4 parentMatrix); void PrintSkeleton(); void PrintSkeleton(const Bone* parent, int depthCount); @@ -115,35 +115,12 @@ 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 6536a839..f027dd1d 100644 --- a/resources/Schema/Entities/AnimationTests2.xml +++ b/resources/Schema/Entities/AnimationTests2.xml @@ -15,7 +15,9 @@ - + + + Models/Widgets/Lights/DirectionalLightWidget.mesh @@ -26,29 +28,24 @@ - + Run 0.5 - 0.78014858943309839 - 1 + 0.99150007800799234 + -1 1 - StrafeRight 0.5 - 0.78620929522779459 - ShootFastRifle - 0.13809128482706701 + 0.96957233017255007 + 0.093923612201312068 1 AimRifle - Models/Characters/Assault/AssaultAnimations.mesh - - true @@ -62,13 +59,11 @@ - Models/Weapons/Blue/AssaultWeapon.mesh - - true + Models/Weapons/Red/AssaultWeaponRed.mesh - - + + @@ -78,13 +73,27 @@ + 10 - + - + + + + + + 10 + + + + + + + + @@ -97,6 +106,48 @@ + + + + ShootFastRifle + 0.068159934509623099 + 1 + 1 + Run + 0.5 + 0.19240865965109588 + StrafeRight + 0.5 + 0.12533627444542628 + 1 + + + AimRifle + + + + Models/Characters/Assault/AssaultAnimations.mesh + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Red/AssaultWeaponRed.mesh + + + + + + + + + + diff --git a/resources/Schema/Entities/AnimationTests3.xml b/resources/Schema/Entities/AnimationTests3.xml index bd985b2d..39043231 100644 --- a/resources/Schema/Entities/AnimationTests3.xml +++ b/resources/Schema/Entities/AnimationTests3.xml @@ -26,57 +26,48 @@ - + Run 0.5 - 0.97312056690160276 - 1 + 0.14873348341666759 + -1 1 - ReloadSwitch - 0.91310356788604263 - LeftRight - 0 - 0.040207288496060478 + + 0.5 + 0.96957233017255007 + + 0.093923612201312068 1 - DownUp - + AimRifle - Models/Characters/Assault/FirstPerson.mesh - - true + Models/Characters/Assault/AssaultAnimations.mesh - + - + R_Arm_Weapon_Joint + - Models/Weapons/Blue/AssaultWeapon.mesh + Models/Weapons/Red/AssaultWeaponRed.mesh - - + + - - - - - - - @@ -101,6 +92,40 @@ + + + + ShootFastRifle + 0.11093210511546658 + 1 + + + AimRifle + + + + Models/Characters/Assault/AssaultAnimations.mesh + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Red/AssaultWeaponRed.mesh + + + + + + + + + + diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index 48681e6e..55edffe2 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -54,32 +54,5 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a (double&)animationComponent["Time" + std::to_string(i)] = nextTime; } } - - //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 a9588a16..c0c2b8de 100644 --- a/src/Engine/Rendering/BoneAttachmentSystem.cpp +++ b/src/Engine/Rendering/BoneAttachmentSystem.cpp @@ -38,10 +38,7 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp return; } - - glm::mat4 boneTransform = skeleton->GetBoneTransformSuper(id); - //glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], animation, (double)parent["Animation"]["Time1"], glm::mat4(1)); - + glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], animation, (double)parent["Animation"]["Time1"], glm::mat4(1)); glm::vec3 scale; glm::quat rotation; glm::vec3 translation; diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 00b85528..c3381632 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -328,7 +328,11 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& //bind textures BindExplosionTextures(explosionSkinnedHandle, explosionEffectJob); std::vector frameBones; - frameBones = explosionEffectJob->Skeleton->GetBones(); + if (explosionEffectJob->AnimationOffset.animation != nullptr) { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); + } else { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); + } glUniformMatrix4fv(glGetUniformLocation(explosionSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { m_ExplosionEffectProgram->Bind(); @@ -351,7 +355,11 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& BindExplosionTextures(explosionSplatMapSkinnedHandle, explosionEffectJob); GLERROR("asdasd"); std::vector frameBones; - frameBones = explosionEffectJob->Skeleton->GetBones(); + if (explosionEffectJob->AnimationOffset.animation != nullptr) { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); + } else { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); + } glUniformMatrix4fv(glGetUniformLocation(explosionSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { @@ -392,7 +400,11 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& //bind textures BindModelTextures(forwardSkinnedHandle, modelJob); std::vector frameBones; - frameBones = modelJob->Skeleton->GetBones(); + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } glUniformMatrix4fv(glGetUniformLocation(forwardSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { @@ -416,7 +428,11 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& BindModelTextures(forwardSplatMapSkinnedHandle, modelJob); GLERROR("asdasd"); std::vector frameBones; - frameBones = modelJob->Skeleton->GetBones(); + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } glUniformMatrix4fv(glGetUniformLocation(forwardSplatMapSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { @@ -460,7 +476,11 @@ void DrawFinalPass::DrawShieldToStencilBuffer(std::listViewMatrix())); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); std::vector frameBones; - frameBones = modelJob->Skeleton->GetBones(); + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { m_ShieldToStencilProgram->Bind(); @@ -514,7 +534,11 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list frameBones; - frameBones = explosionEffectJob->Skeleton->GetBones(); + if (explosionEffectJob->AnimationOffset.animation != nullptr) { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations, explosionEffectJob->AnimationOffset); + } else { + frameBones = explosionEffectJob->Skeleton->GetFrameBones(explosionEffectJob->Animations); + } glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); if (GLERROR("Animation")) { @@ -549,7 +573,11 @@ void DrawFinalPass::DrawShieldedModelRenderQueue(std::list frameBones; - frameBones = modelJob->Skeleton->GetBones(); + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); @@ -581,7 +609,11 @@ void DrawFinalPass::DrawToDepthBuffer(std::list>& job glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); std::vector frameBones; - frameBones = modelJob->Skeleton->GetBones(); + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } 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 cc9837ff..fa1b3ca3 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -103,7 +103,11 @@ void PickingPass::Draw(RenderScene& scene) if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { std::vector frameBones; - frameBones = modelJob->Skeleton->GetBones(); + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } @@ -156,7 +160,11 @@ void PickingPass::Draw(RenderScene& scene) glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); std::vector frameBones; - frameBones = modelJob->Skeleton->GetBones(); + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { m_PickingProgram->Bind(); @@ -207,7 +215,11 @@ void PickingPass::Draw(RenderScene& scene) glUniform2fv(glGetUniformLocation(shaderSkinnedHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); std::vector frameBones; - frameBones = modelJob->Skeleton->GetBones(); + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } else { @@ -264,7 +276,11 @@ void PickingPass::Draw(RenderScene& scene) if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { std::vector frameBones; - frameBones = modelJob->Skeleton->GetBones(); + if (modelJob->AnimationOffset.animation != nullptr) { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations, modelJob->AnimationOffset); + } else { + frameBones = modelJob->Skeleton->GetFrameBones(modelJob->Animations); + } glUniformMatrix4fv(glGetUniformLocation(shaderSkinnedHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); } diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index 5da95558..f85efd17 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -30,30 +30,6 @@ 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) { @@ -65,7 +41,167 @@ const Skeleton::Animation* Skeleton::GetAnimation(std::string name) } } -void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vector animations, AnimationOffset animationOffset, const Bone* bone, glm::mat4 parentMatrix) +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, 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) { + nextFrame = currentFrame; + 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; @@ -148,12 +284,10 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vectorOffsetMatrix) * bone->Parent->OffsetMatrix)); } - m_BoneLocalTransforms[bone->ID] = boneMatrix * bone->OffsetMatrix; - m_BoneTransforms[bone->ID] = boneMatrix; + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; } else { boneMatrix = offset * glm::inverse(bone->OffsetMatrix); - m_BoneLocalTransforms[bone->ID] = parentMatrix; - m_BoneTransforms[bone->ID] = boneMatrix; + boneMatrices[bone->ID] = parentMatrix; } } else { @@ -189,136 +323,11 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, std::vectorID] = boneMatrix * bone->OffsetMatrix; - m_BoneTransforms[bone->ID] = boneMatrix; + boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; } for (auto &child : bone->Children) { - 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) { - nextFrame = currentFrame; - 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); + AccumulateBoneTransforms(noRootMotion, animations, animationOffset, boneMatrices, child, boneMatrix); } } @@ -356,11 +365,8 @@ 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); - } + progress = glm::clamp(progress, 0.0f, 1.0f); + Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties; Animation::Keyframe::BoneProperty nextBoneProperty = nextFrame.BoneProperties; From f11bd24d539cd9847b3307250bea8202272f02f3 Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Thu, 11 Feb 2016 11:46:34 +0100 Subject: [PATCH 08/26] Added CapturePointMaxTimer in CapturePointComponent. Removed next-capturepoint Color. Modified captureTimer to +-captureTimeToTakeOver after a capture. --- include/Game/Systems/CapturePointSystem.h | 1 - resources/Schema/Components/CapturePoint.xml | 1 + resources/Schema/Components/CapturePoint.xsd | 6 +- .../Schema/Entities/CaptureTestState5.xml | 323 ++++++++++++++---- src/Game/Systems/CapturePointSystem.cpp | 29 +- 5 files changed, 273 insertions(+), 87 deletions(-) diff --git a/include/Game/Systems/CapturePointSystem.h b/include/Game/Systems/CapturePointSystem.h index 18c32c76..33ba40c8 100644 --- a/include/Game/Systems/CapturePointSystem.h +++ b/include/Game/Systems/CapturePointSystem.h @@ -44,7 +44,6 @@ private: //std::vector - const double m_CaptureTimeToTakeOver = 15.0; bool m_ResetTimers = false; //vectors which will keep track of enter/leave changes diff --git a/resources/Schema/Components/CapturePoint.xml b/resources/Schema/Components/CapturePoint.xml index ba164fd9..638b16c3 100644 --- a/resources/Schema/Components/CapturePoint.xml +++ b/resources/Schema/Components/CapturePoint.xml @@ -2,5 +2,6 @@ 0 0 + 15 \ No newline at end of file diff --git a/resources/Schema/Components/CapturePoint.xsd b/resources/Schema/Components/CapturePoint.xsd index fbdb3568..3c91dfdd 100644 --- a/resources/Schema/Components/CapturePoint.xsd +++ b/resources/Schema/Components/CapturePoint.xsd @@ -20,7 +20,11 @@ CapturePointNumber specify an int number for this - + + + The time needed to take over a Capture Point + + Specify if this is a HomePoint for either team diff --git a/resources/Schema/Entities/CaptureTestState5.xml b/resources/Schema/Entities/CaptureTestState5.xml index 8fe85068..c733706c 100644 --- a/resources/Schema/Entities/CaptureTestState5.xml +++ b/resources/Schema/Entities/CaptureTestState5.xml @@ -2,12 +2,246 @@ - - - + + + + + + + + + Models/LevelBase/MapVersion1.mesh + + + + + + + + + 2 + + + Models/Widgets/Lights/DirectionalLightWidget.mesh + false + + + + + + + + + + + + + 8 + 2.7999999523162842 + + + + + + + + + + + 8 + 2.7999999523162842 + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + false + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + false + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -15,10 +249,12 @@ + 15 Models/Core/UnitSphere.mesh - + + true @@ -26,7 +262,7 @@ - + @@ -40,11 +276,12 @@ Models/Core/UnitSphere.mesh - + + true - + @@ -58,15 +295,12 @@ Models/Core/UnitSphere.mesh - + + true - - - - - + - + @@ -76,11 +310,13 @@ + -15 3 Models/Core/UnitSphere.mesh - + + true @@ -88,7 +324,7 @@ - + @@ -101,11 +337,13 @@ + -15 4 Models/Core/UnitSphere.mesh - + + true @@ -113,61 +351,12 @@ - + - - - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - - - - - - Models/Core/UnitCube.mesh - - - - - - - - - - - - - - - - - Models/Test/DummyScene.mesh - - - - - - - diff --git a/src/Game/Systems/CapturePointSystem.cpp b/src/Game/Systems/CapturePointSystem.cpp index a943e234..971c194c 100644 --- a/src/Game/Systems/CapturePointSystem.cpp +++ b/src/Game/Systems/CapturePointSystem.cpp @@ -1,7 +1,7 @@ #include "Systems/CapturePointSystem.h" #include -CapturePointSystem::CapturePointSystem(World* world, EventBroker* eventBroker) +CapturePointSystem::CapturePointSystem(World* world, EventBroker* eventBroker) : System(world, eventBroker) , PureSystem("CapturePoint") { @@ -32,6 +32,7 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp const int redTeam = (int)teamComponent["Team"].Enum("Red"); const int blueTeam = (int)teamComponent["Team"].Enum("Blue"); const int spectatorTeam = (int)teamComponent["Team"].Enum("Spectator"); + const double captureTimeToTakeOver = (double)cCapturePoint["CapturePointMaxTimer"]; int homePointForTeam = (int)cCapturePoint["HomePointForTeam"]; if (m_NumberOfCapturePoints == 0 && capturePointNumber != 0 && (homePointForTeam == redTeam || homePointForTeam == blueTeam)) { @@ -57,7 +58,7 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp 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); + capturePointEntity["Model"]["Color"] = ownedBy == blueTeam ? glm::vec4(0, 0.0f, 1, 0.3) : ownedBy == redTeam ? glm::vec4(1, 0.0f, 0, 0.3) : glm::vec4(1, 1, 1, 0.3); } //calculate next possible capturePoint for both teams @@ -98,20 +99,16 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp ComponentWrapper& capturePoint = m_CapturePointNumberToEntityMap[i]["CapturePoint"]; if ((int)capturePoint["CapturePointNumber"] != nextPossibleCapturePoint["Red"] && (int)capturePoint["CapturePointNumber"] != nextPossibleCapturePoint["Blue"]) { - capturePoint["CaptureTimer"] = 0.0; + //RED = +, BLUE = -, NONE + auto teamOwners = (int)m_CapturePointNumberToEntityMap[i]["Team"]["Team"]; + if (teamOwners == redTeam || teamOwners == blueTeam) { + capturePoint["CaptureTimer"] = teamOwners == blueTeam ? -captureTimeToTakeOver : captureTimeToTakeOver; + } } } 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--) { @@ -170,9 +167,6 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp //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 @@ -180,12 +174,11 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp (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) { + //check if captureTimer > captureTimeToTakeOver and if so change owner and publish the eCaptured event + if (abs((double)cCapturePoint["CaptureTimer"]) > captureTimeToTakeOver && canCapture) { teamComponent["Team"] = currentTeam; - cCapturePoint["CaptureTimer"] = 0.0; + cCapturePoint["CaptureTimer"] = glm::sign((double)cCapturePoint["CaptureTimer"])*captureTimeToTakeOver; //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; From 2f640d224ced2eb89b32762a1351e964ea938a0b Mon Sep 17 00:00:00 2001 From: antc13 Date: Thu, 11 Feb 2016 12:23:20 +0100 Subject: [PATCH 09/26] New Map with Meshes WIP --- resources/Schema/Entities/NewMap.xml | 65 ++++++++++++++-------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/resources/Schema/Entities/NewMap.xml b/resources/Schema/Entities/NewMap.xml index 8a5227aa..7a1d620b 100644 --- a/resources/Schema/Entities/NewMap.xml +++ b/resources/Schema/Entities/NewMap.xml @@ -338,7 +338,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -349,6 +349,7 @@ Models/Props/Walls/BigWall.mesh + @@ -363,7 +364,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -440,7 +441,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -452,7 +453,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -466,7 +467,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -482,7 +483,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -494,7 +495,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -507,7 +508,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -753,7 +754,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -764,7 +765,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -776,7 +777,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -803,7 +804,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -830,7 +831,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -841,7 +842,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -853,7 +854,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -879,7 +880,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -1030,7 +1031,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -1057,7 +1058,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -1068,7 +1069,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -1080,7 +1081,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -1092,7 +1093,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -1106,7 +1107,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -1118,7 +1119,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -1183,7 +1184,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -1195,7 +1196,7 @@ Models/Props/Walls/BigWall.mesh - + @@ -1449,7 +1450,7 @@ Models/Props/Bridges/SciFiBridge.mesh - + @@ -1462,7 +1463,7 @@ Models/Props/Bridges/SciFiBridgeDefense.mesh - + @@ -1515,7 +1516,7 @@ Models/Props/Bridges/SciFiBridgeDefense.mesh - + @@ -1604,7 +1605,7 @@ Models/Props/Pillars/SciFiBridgePillar1.mesh - + @@ -2886,9 +2887,9 @@ Models/Props/PickUps/PickUpHolder.mesh - + - + @@ -3117,7 +3118,7 @@ Models/Props/SciFiHolder1.mesh - + From 97de31be65e4bc32ef9461f0cc6dd19716d025d1 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Thu, 11 Feb 2016 13:36:27 +0100 Subject: [PATCH 10/26] Fixed BoneAttachment component --- include/Engine/Rendering/Skeleton.h | 2 + resources/Schema/Entities/AnimationTests2.xml | 28 +- src/Engine/Rendering/BoneAttachmentSystem.cpp | 46 +++- src/Engine/Rendering/Skeleton.cpp | 243 ++++++++++++++++++ 4 files changed, 294 insertions(+), 25 deletions(-) diff --git a/include/Engine/Rendering/Skeleton.h b/include/Engine/Rendering/Skeleton.h index ccf3e2b4..28a5ef6a 100644 --- a/include/Engine/Rendering/Skeleton.h +++ b/include/Engine/Rendering/Skeleton.h @@ -113,6 +113,8 @@ public: std::map Animations; glm::mat4 GetBoneTransform(const Bone* bone, const Animation* animation, float time, glm::mat4 childMatrix); + glm::mat4 GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector animations, AnimationOffset animationOffset, glm::mat4 childMatrix); + glm::mat4 GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector animations, glm::mat4 childMatrix); int GetKeyframe(const Animation& animation, double time); private: diff --git a/resources/Schema/Entities/AnimationTests2.xml b/resources/Schema/Entities/AnimationTests2.xml index f027dd1d..413c7e67 100644 --- a/resources/Schema/Entities/AnimationTests2.xml +++ b/resources/Schema/Entities/AnimationTests2.xml @@ -15,9 +15,7 @@ - - - + Models/Widgets/Lights/DirectionalLightWidget.mesh @@ -33,7 +31,7 @@ Run 0.5 - 0.99150007800799234 + 0.60188997954429357 -1 1 0.5 @@ -43,6 +41,7 @@ AimRifle + Models/Characters/Assault/AssaultAnimations.mesh @@ -62,8 +61,8 @@ Models/Weapons/Red/AssaultWeaponRed.mesh - - + + @@ -110,21 +109,17 @@ ShootFastRifle - 0.068159934509623099 + 0.056234247235838808 1 1 - Run + Idl 0.5 - 0.19240865965109588 - StrafeRight + 1.8308673495784191 + StrafeRigh 0.5 - 0.12533627444542628 + 0.32167823998061529 1 - - AimRifle - - Models/Characters/Assault/AssaultAnimations.mesh @@ -140,8 +135,7 @@ Models/Weapons/Red/AssaultWeaponRed.mesh - - + diff --git a/src/Engine/Rendering/BoneAttachmentSystem.cpp b/src/Engine/Rendering/BoneAttachmentSystem.cpp index c0c2b8de..3effaf2c 100644 --- a/src/Engine/Rendering/BoneAttachmentSystem.cpp +++ b/src/Engine/Rendering/BoneAttachmentSystem.cpp @@ -19,6 +19,9 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp return; } + if (!model->IsSkinned()) { + return; + } Skeleton* skeleton = model->m_RawModel->m_Skeleton; @@ -26,19 +29,46 @@ void BoneAttachmentSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapp return; } - const Skeleton::Animation* animation = skeleton->GetAnimation(parent["Animation"]["AnimationName1"]); - - if (!animation) { - return; - } - int id = skeleton->GetBoneID(entity["BoneAttachment"]["BoneName"]); - if(id == -1) { + if (id == -1) { return; } - glm::mat4 boneTransform = skeleton->GetBoneTransform(skeleton->Bones[id], animation, (double)parent["Animation"]["Time1"], glm::mat4(1)); + std::vector<::Skeleton::AnimationData> Animations; + ::Skeleton::AnimationOffset AnimationOffset; + glm::mat4 boneTransform; + + if (parent.HasComponent("Animation")) { + for (int i = 1; i <= 3; i++) { + ::Skeleton::AnimationData animationData; + animationData.animation = model->m_RawModel->m_Skeleton->GetAnimation(parent["Animation"]["AnimationName" + std::to_string(i)]); + if (animationData.animation == nullptr) { + continue; + } + animationData.time = (double)parent["Animation"]["Time" + std::to_string(i)]; + animationData.weight = (double)parent["Animation"]["Weight" + std::to_string(i)]; + + Animations.push_back(animationData); + } + } + + if (parent.HasComponent("AnimationOffset")) { + AnimationOffset.animation = model->m_RawModel->m_Skeleton->GetAnimation(parent["AnimationOffset"]["AnimationName"]); + AnimationOffset.time = (double)parent["AnimationOffset"]["Time"]; + + if(AnimationOffset.animation != nullptr) { + boneTransform = skeleton->GetBoneTransform(false, skeleton->Bones.at(id), Animations, AnimationOffset, glm::mat4(1)); + } else { + boneTransform = skeleton->GetBoneTransform(false, skeleton->Bones.at(id), Animations, glm::mat4(1)); + } + + } else { + boneTransform = skeleton->GetBoneTransform(false, skeleton->Bones.at(id), Animations, glm::mat4(1)); + } + + + glm::vec3 scale; glm::quat rotation; glm::vec3 translation; diff --git a/src/Engine/Rendering/Skeleton.cpp b/src/Engine/Rendering/Skeleton.cpp index f85efd17..e390d694 100644 --- a/src/Engine/Rendering/Skeleton.cpp +++ b/src/Engine/Rendering/Skeleton.cpp @@ -448,6 +448,249 @@ glm::mat4 Skeleton::GetBoneTransform(const Bone* bone, const Animation* animatio } } + +glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector animations, AnimationOffset animationOffset, glm::mat4 childMatrix) +{ + 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) { + nextFrame = currentFrame; + 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 + + } + + } + + + glm::mat4 offset = GetOffsetTransform(bone, animationOffset); + + if (JointTransforms.size() == 0) { + if (bone->Parent) { + if (offset != glm::mat4(1)) { + boneMatrix = offset * childMatrix;// *((glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix)); + } else { + boneMatrix = ((glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix)) * childMatrix; + } + } else { + boneMatrix = offset * glm::inverse(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); + } + + } + + if (offset != glm::mat4(1)) { + boneMatrix = ((glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp)) + offset) * childMatrix; + } else { + boneMatrix = (glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp)) * childMatrix; + } + } + + if (bone->Parent != nullptr) { + return GetBoneTransform(noRootMotion, bone->Parent, animations, animationOffset, boneMatrix); + } else { + return boneMatrix; + } +} + + +glm::mat4 Skeleton::GetBoneTransform(bool noRootMotion, const Bone* bone, std::vector animations, glm::mat4 childMatrix) +{ + 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) { + nextFrame = currentFrame; + 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 = glm::inverse(bone->OffsetMatrix) * bone->Parent->OffsetMatrix * childMatrix; + } else { + boneMatrix = glm::inverse(bone->OffsetMatrix) * childMatrix; + } + } else if (JointTransforms.size() == 1) { + boneMatrix = (glm::translate(JointTransforms.at(0).PositionInterp) * glm::toMat4(JointTransforms.at(0).RotationInterp) * glm::scale(JointTransforms.at(0).ScaleInterp)) * childMatrix; + } 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 = (glm::translate(finalPosInterp) * glm::toMat4(finalRotInterp) * glm::scale(finalScaleInterp)) * childMatrix; + } + + + + if (bone->Parent != nullptr) { + return GetBoneTransform(noRootMotion, bone->Parent, animations, boneMatrix); + } else { + return boneMatrix; + } +} + int Skeleton::GetBoneID(std::string name) { if (m_BonesByName.find(name) == m_BonesByName.end()) { From 1d14094e903ca7baa09263fcea33a52cb298232e Mon Sep 17 00:00:00 2001 From: antc13 Date: Thu, 11 Feb 2016 16:52:10 +0100 Subject: [PATCH 11/26] NewMap Updated. Still WIP --- assets | 2 +- resources/Schema/Entities/NewMap.xml | 422 ++++++++++++++++++++++----- 2 files changed, 353 insertions(+), 71 deletions(-) diff --git a/assets b/assets index c56f6380..66e2a73b 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit c56f6380ab05c23419beafe14190013d1432e32c +Subproject commit 66e2a73bdb2c385cac37476980809cc587e2e612 diff --git a/resources/Schema/Entities/NewMap.xml b/resources/Schema/Entities/NewMap.xml index 7a1d620b..f4c768f0 100644 --- a/resources/Schema/Entities/NewMap.xml +++ b/resources/Schema/Entities/NewMap.xml @@ -104,6 +104,100 @@ + + + + Models/Props/Walls/SciFiWallTop.mesh + + + + + + + + + Models/Props/Walls/SciFiWallBig.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallMedium.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallSmall1.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallSmall2.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallBig.mesh + + + + + + + + + + + + Models/Props/Walls/SciFiWallMedium.mesh + + + + + + + + + + + + Models/Props/Walls/SciFiWallSmall3.mesh + + + + + + + + + + Models/Props/Walls/SciFiWallSmall4.mesh + + + + + + + @@ -1436,12 +1530,117 @@ Models/Props/Bridges/SciFiBridge.mesh - + - + - + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + Models/Props/Bridges/SciFiBridgeDefense.mesh + + + + + + + + + + + + + + @@ -1591,9 +1790,9 @@ Models/Props/Pillars/SciFiBridgePillar1.mesh - + - + @@ -2901,9 +3100,9 @@ Models/Props/PickUps/PickUpHolder.mesh - + - + @@ -3124,6 +3323,19 @@ + + + + + Models/Props/SciFiHolder1.mesh + + + + + + + + @@ -3135,106 +3347,176 @@ - - - - - + - Models/Props/CapturePoint.mesh - - true + Models/Props/CapturePoint/CapturePointBlue.mesh - - - - - - + - - + + + + + + + + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + - - 1 - + - Models/Props/CapturePoint.mesh - - true + Models/Props/CapturePoint/CapturePointNeutral.mesh - - + - - + + + + + 1 + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + - - 2 - + - Models/Props/CapturePoint.mesh - - true + Models/Props/CapturePoint/CapturePointNeutral.mesh - - + - - + + + + + 2 + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + - - 3 - + - Models/Props/CapturePoint.mesh - - true + Models/Props/CapturePoint/CapturePointNeutral.mesh - - + - - + + + + + 3 + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + - - - - - 4 - + - Models/Props/CapturePoint.mesh - - true + Models/Props/CapturePoint/CapturePointNeutral.mesh - - - - - - + - - + + + + + + + + 4 + + + Models/Core/UnitCylinder.mesh + + true + + + + + + + + + + + + + + + From e47201ff6108627fc7997bf7aa5e22f2658b70d8 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Thu, 11 Feb 2016 17:06:34 +0100 Subject: [PATCH 12/26] First person shoot animations --- .../Systems/Weapon/AssaultWeaponBehaviour.h | 34 ++++ include/Game/Systems/Weapon/WeaponBehaviour.h | 31 +++ include/Game/Systems/Weapon/WeaponSystem.h | 46 +++++ include/Game/Systems/WeaponSystem.h | 192 ------------------ resources/Schema/Components/AssaultWeapon.xml | 1 + resources/Schema/Components/AssaultWeapon.xsd | 3 + resources/Schema/Components/Player.xml | 1 + resources/Schema/Components/Player.xsd | 3 +- src/Engine/Rendering/AnimationSystem.cpp | 21 +- src/Game/CMakeLists.txt | 7 + src/Game/Game.cpp | 2 +- src/Game/Systems/PlayerMovementSystem.cpp | 3 +- .../Systems/Weapon/AssaultWeaponBehaviour.cpp | 190 +++++++++++++++++ .../Systems/{ => Weapon}/WeaponSystem.cpp | 5 +- 14 files changed, 338 insertions(+), 201 deletions(-) create mode 100644 include/Game/Systems/Weapon/AssaultWeaponBehaviour.h create mode 100644 include/Game/Systems/Weapon/WeaponBehaviour.h create mode 100644 include/Game/Systems/Weapon/WeaponSystem.h delete mode 100644 include/Game/Systems/WeaponSystem.h create mode 100644 src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp rename src/Game/Systems/{ => Weapon}/WeaponSystem.cpp (97%) diff --git a/include/Game/Systems/Weapon/AssaultWeaponBehaviour.h b/include/Game/Systems/Weapon/AssaultWeaponBehaviour.h new file mode 100644 index 00000000..58d7755f --- /dev/null +++ b/include/Game/Systems/Weapon/AssaultWeaponBehaviour.h @@ -0,0 +1,34 @@ +#include "Sound/EPlaySoundOnEntity.h" +#include "Rendering/AnimationSystem.h" +#include "WeaponBehaviour.h" +#include "../SpawnerSystem.h" + +class AssaultWeaponBehaviour : public WeaponBehaviour +{ +public: + AssaultWeaponBehaviour(SystemParams systemParams, Octree* collisionOctree, EntityWrapper weaponEntity); + + virtual void Fire() override; + virtual void CeaseFire() override; + virtual void Reload() override; + + virtual void Update(double dt) override; + +private: + EntityWrapper m_FirstPersonModel; + // State + bool m_Firing = false; + bool m_Reloading = false; + double m_TimeSinceLastFire = 0.0; + + EventRelay m_EAnimationComplete; + bool OnAnimationComplete(Events::AnimationComplete& e); + + void fireRound(); + void spawnTracer(); + float traceRayDistance(glm::vec3 origin, glm::vec3 direction); + void playSound(); + void viewPunch(); + void playShootAnimation(); + void playIdleAnimation(); +}; diff --git a/include/Game/Systems/Weapon/WeaponBehaviour.h b/include/Game/Systems/Weapon/WeaponBehaviour.h new file mode 100644 index 00000000..38ab5f58 --- /dev/null +++ b/include/Game/Systems/Weapon/WeaponBehaviour.h @@ -0,0 +1,31 @@ +#ifndef WeaponBehaviour_h__ +#define WeaponBehaviour_h__ + +#include "Core/System.h" +#include "Core/Octree.h" +#include "Collision/EntityAABB.h" + +class WeaponBehaviour : public System +{ +public: + 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() { } + virtual void Reload() { } + virtual void Update(double dt) { } + +protected: + Octree* m_CollisionOctree; + EntityWrapper m_Entity; +}; + +#endif diff --git a/include/Game/Systems/Weapon/WeaponSystem.h b/include/Game/Systems/Weapon/WeaponSystem.h new file mode 100644 index 00000000..68cf2ef3 --- /dev/null +++ b/include/Game/Systems/Weapon/WeaponSystem.h @@ -0,0 +1,46 @@ +#ifndef WeaponSystem_h__ +#define WeaponSystem_h__ + +#include "Rendering/IRenderer.h" + +#include "Common.h" +#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 "Core/Octree.h" +#include "Collision/EntityAABB.h" +#include "Systems/SpawnerSystem.h" +#include "Sound/EPlaySoundOnEntity.h" +#include "AssaultWeaponBehaviour.h" + +class WeaponSystem : public PureSystem, ImpureSystem +{ +public: + WeaponSystem(SystemParams params, IRenderer* renderer, Octree* collisionOctree); + + virtual void Update(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; + + // Events + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(Events::PlayerSpawned& e); + EventRelay m_EShoot; + bool OnShoot(Events::Shoot& e); + EventRelay m_EInputCommand; + bool OnInputCommand(Events::InputCommand& e); + + void selectWeapon(EntityWrapper player, ComponentInfo::EnumType slot); +}; + +#endif \ No newline at end of file diff --git a/include/Game/Systems/WeaponSystem.h b/include/Game/Systems/WeaponSystem.h deleted file mode 100644 index b118b8cd..00000000 --- a/include/Game/Systems/WeaponSystem.h +++ /dev/null @@ -1,192 +0,0 @@ -#ifndef WeaponSystem_h__ -#define WeaponSystem_h__ - -//#include -//#include -#include "Rendering/IRenderer.h" - -#include "Common.h" -#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 "Core/Octree.h" -#include "Collision/EntityAABB.h" -#include "Systems/SpawnerSystem.h" -#include "Sound/EPlaySoundOnEntity.h" - -class WeaponBehaviour; - -class WeaponSystem : public PureSystem, ImpureSystem -{ -public: - WeaponSystem(SystemParams params, IRenderer* renderer, Octree* collisionOctree); - - virtual void Update(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; - - // Events - EventRelay m_EPlayerSpawned; - bool OnPlayerSpawned(Events::PlayerSpawned& e); - EventRelay m_EShoot; - bool OnShoot(Events::Shoot& e); - EventRelay m_EInputCommand; - bool OnInputCommand(Events::InputCommand& e); - - void selectWeapon(EntityWrapper player, ComponentInfo::EnumType slot); -}; - -class WeaponBehaviour : public System -{ -public: - 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() { } - virtual void Reload() { } - virtual void Update(double dt) { } - -protected: - Octree* m_CollisionOctree; - EntityWrapper m_Entity; -}; - -class AssaultWeaponBehaviour : public WeaponBehaviour -{ -public: - AssaultWeaponBehaviour(SystemParams systemParams, Octree* collisionOctree, EntityWrapper weaponEntity) - : WeaponBehaviour(systemParams, collisionOctree, weaponEntity) - { } - - virtual void Fire() override - { - m_TimeSinceLastFire = 0.0; - m_Firing = true; - fireRound(); - } - - virtual void CeaseFire() override - { - 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) { - return; - } - - m_TimeSinceLastFire += dt; - - ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"]; - if (m_TimeSinceLastFire >= 1.0 / ((double)cAssaultWeapon["RPM"] / 60.0)) { - fireRound(); - } - } - -private: - bool m_Firing = false; - double m_TimeSinceLastFire = 0.0; - EntityFile* m_RayRed = nullptr; - EntityFile* m_RayBlue = nullptr; - - void fireRound() - { - ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"]; - - int& magAmmo = cAssaultWeapon["MagazineAmmo"]; - int ammo = cAssaultWeapon["Ammo"]; - - // Reload if our magazine is empty - if (magAmmo <= 0) { - Reload(); - return; - } - - // 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"); - } else { - spawner = m_Entity.FirstChildByName("ThirdPersonWeaponMuzzle"); - } - - if (!spawner.Valid()) { - return; - } - - Events::SpawnerSpawn e; - e.Spawner = spawner; - m_EventBroker->Publish(e); - } - - float traceRayDistance(glm::vec3 origin, glm::vec3 direction) - { - // 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/Components/AssaultWeapon.xml b/resources/Schema/Components/AssaultWeapon.xml index 902795c1..c7dbfb0d 100755 --- a/resources/Schema/Components/AssaultWeapon.xml +++ b/resources/Schema/Components/AssaultWeapon.xml @@ -6,4 +6,5 @@ 360 5 120 + 0.01 \ No newline at end of file diff --git a/resources/Schema/Components/AssaultWeapon.xsd b/resources/Schema/Components/AssaultWeapon.xsd index 1b2704ea..65558db5 100755 --- a/resources/Schema/Components/AssaultWeapon.xsd +++ b/resources/Schema/Components/AssaultWeapon.xsd @@ -22,6 +22,9 @@ Rate of fire in rounds per minute + + View punch in radians for each bullet fired + diff --git a/resources/Schema/Components/Player.xml b/resources/Schema/Components/Player.xml index b51326aa..00cff257 100644 --- a/resources/Schema/Components/Player.xml +++ b/resources/Schema/Components/Player.xml @@ -2,4 +2,5 @@ 3 1.5 + \ No newline at end of file diff --git a/resources/Schema/Components/Player.xsd b/resources/Schema/Components/Player.xsd index 13948dc2..1b33d222 100644 --- a/resources/Schema/Components/Player.xsd +++ b/resources/Schema/Components/Player.xsd @@ -5,12 +5,13 @@ - The player charachter + The player entity + diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index 48681e6e..d5b5984d 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -34,19 +34,32 @@ void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& a if (!(bool)animationComponent["Loop" + std::to_string(i)]) { if (nextTime > animation->Duration) { nextTime = animation->Duration; + Events::AnimationComplete e; + e.Entity = entity; + e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)]; + m_EventBroker->Publish(e); } else if (nextTime < 0) { + Events::AnimationComplete e; + e.Entity = entity; + e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)]; + m_EventBroker->Publish(e); 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 (nextTime > animation->Duration) { + Events::AnimationComplete e; + e.Entity = entity; + e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)]; + m_EventBroker->Publish(e); nextTime -= animation->Duration; } else if (nextTime < 0) { + Events::AnimationComplete e; + e.Entity = entity; + e.Name = (std::string)animationComponent["AnimationName" + std::to_string(i)]; + m_EventBroker->Publish(e); nextTime += animation->Duration; } } diff --git a/src/Game/CMakeLists.txt b/src/Game/CMakeLists.txt index db923364..f188d7fa 100644 --- a/src/Game/CMakeLists.txt +++ b/src/Game/CMakeLists.txt @@ -16,6 +16,12 @@ file(GLOB SOURCE_FILES_Systems ) source_group(Systems FILES ${SOURCE_FILES_Systems}) +file(GLOB SOURCE_FILES_Systems_Weapon + "${INCLUDE_PATH}/Systems/Weapon/*.h" + "Systems/Weapon/*.cpp" +) +source_group(Systems\\Weapon FILES ${SOURCE_FILES_Systems_Weapon}) + file(GLOB SOURCE_FILES_Events "${INCLUDE_PATH}/Events/*.h" "Events/*.cpp" @@ -31,6 +37,7 @@ set(SOURCE_FILES ${SOURCE_FILES} "Game.cpp" ${SOURCE_FILES_Systems} + ${SOURCE_FILES_Systems_Weapon} ${SOURCE_FILES_Events} ${SOURCE_FILES_Network} ) diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 6057d463..cf14fc76 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -13,7 +13,7 @@ #include "Core/EntityFileWriter.h" #include "Game/Systems/CapturePointSystem.h" #include "Game/Systems/PickupSpawnSystem.h" -#include "Game/Systems/WeaponSystem.h" +#include "Game/Systems/Weapon/WeaponSystem.h" #include "Rendering/AnimationSystem.h" #include "Game/Systems/PlayerHUDSystem.h" #include "Rendering/BoneAttachmentSystem.h" diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 7c69f0ce..65f7c302 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -51,6 +51,7 @@ void PlayerMovementSystem::updateMovementControllers(double dt) float playerMovementSpeed = player["Player"]["MovementSpeed"]; float playerCrouchSpeed = player["Player"]["CrouchSpeed"]; + glm::vec3& wishDirection = player["Player"]["CurrentWishDirection"]; if (player.HasComponent("Physics")) { ComponentWrapper cPhysics = player["Physics"]; @@ -58,7 +59,7 @@ void PlayerMovementSystem::updateMovementControllers(double dt) if (player.HasComponent("DashAbility")) { controller->AssaultDashCheck(dt, ((glm::vec3)cPhysics["Velocity"]).y != 0.0f, player["DashAbility"]["CoolDownMaxTimer"]); } - glm::vec3 wishDirection = controller->Movement() * glm::inverse(glm::quat(ori)); + wishDirection = controller->Movement() * glm::inverse(glm::quat(ori)); //this makes sure you can only dash in the 4 directions: forw,backw,left,right if (controller->AssaultDashDoubleTapped() && controller->Movement().z != 0 && controller->Movement().x != 0) { wishDirection = glm::vec3(controller->Movement().x, 0, 0)* glm::inverse(glm::quat(ori)); diff --git a/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp b/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp new file mode 100644 index 00000000..bb5a025f --- /dev/null +++ b/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp @@ -0,0 +1,190 @@ +#include "Systems/Weapon/AssaultWeaponBehaviour.h" + +AssaultWeaponBehaviour::AssaultWeaponBehaviour(SystemParams systemParams, Octree* collisionOctree, EntityWrapper weaponEntity) + : WeaponBehaviour(systemParams, collisionOctree, weaponEntity) +{ + m_FirstPersonModel = m_Entity.FirstChildByName("Hands"); + EVENT_SUBSCRIBE_MEMBER(m_EAnimationComplete, &AssaultWeaponBehaviour::OnAnimationComplete); +} + +void AssaultWeaponBehaviour::Fire() +{ + m_TimeSinceLastFire = 0.0; + m_Firing = true; + fireRound(); + playShootAnimation(); +} + +void AssaultWeaponBehaviour::CeaseFire() +{ + m_Firing = false; +} + +void AssaultWeaponBehaviour::Reload() +{ + 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; +} + +void AssaultWeaponBehaviour::Update(double dt) +{ + if (m_Firing) { + m_TimeSinceLastFire += dt; + + ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"]; + if (m_TimeSinceLastFire >= 1.0 / ((double)cAssaultWeapon["RPM"] / 60.0)) { + fireRound(); + } + } + + if (!m_Firing && !m_Reloading) { + playIdleAnimation(); + } +} + +bool AssaultWeaponBehaviour::OnAnimationComplete(Events::AnimationComplete& e) +{ + if (e.Entity != m_FirstPersonModel) { + return false; + } + + //if (e.Name == "ShootRifle") { + // if (!m_Firing) { + // playIdleAnimation(); + // } + //} + + return true; +} + +void AssaultWeaponBehaviour::fireRound() +{ + ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"]; + + int& magAmmo = cAssaultWeapon["MagazineAmmo"]; + int ammo = cAssaultWeapon["Ammo"]; + + // Reload if our magazine is empty + if (magAmmo <= 0) { + Reload(); + return; + } + + // Fire + magAmmo -= 1; + spawnTracer(); + playSound(); + viewPunch(); + + m_TimeSinceLastFire = 0.0; +} + +void AssaultWeaponBehaviour::spawnTracer() +{ + if (!IsClient) { + return; + } + + EntityWrapper spawner; + if (m_Entity == LocalPlayer) { + spawner = m_Entity.FirstChildByName("WeaponMuzzle"); + } else { + spawner = m_Entity.FirstChildByName("ThirdPersonWeaponMuzzle"); + } + + if (!spawner.Valid()) { + return; + } + + Events::SpawnerSpawn e; + e.Spawner = spawner; + m_EventBroker->Publish(e); +} + +float AssaultWeaponBehaviour::traceRayDistance(glm::vec3 origin, glm::vec3 direction) +{ + // TODO: Cast a ray and size tracer appropriately + return 100.f; +} + +void AssaultWeaponBehaviour::playSound() +{ + if (!IsClient) { + return; + } + + Events::PlaySoundOnEntity e; + e.EmitterID = m_Entity.ID; + e.FilePath = "Audio/laser/laser1.wav"; + m_EventBroker->Publish(e); +} + +void AssaultWeaponBehaviour::viewPunch() +{ + EntityWrapper playerCamera = m_Entity.FirstChildByName("Camera"); + if (!playerCamera.Valid()) { + return; + } + float viewPunch = m_Entity["AssaultWeapon"]["ViewPunch"]; + ComponentWrapper cTransform = playerCamera["Transform"]; + glm::vec3& orientation = cTransform["Orientation"]; + orientation.x += viewPunch; +} + +void AssaultWeaponBehaviour::playShootAnimation() +{ + EntityWrapper firstPersonWeapon = m_Entity.FirstChildByName("Hands"); + ComponentWrapper cAnimation = firstPersonWeapon["Animation"]; + cAnimation["AnimationName1"] = "ShootRifle"; + cAnimation["Weight1"] = 1.0; + cAnimation["Time1"] = 0.0; + cAnimation["Speed1"] = 1.0; + cAnimation["Loop1"] = true; +} + +void AssaultWeaponBehaviour::playIdleAnimation() +{ + if (!m_FirstPersonModel.Valid()) { + return; + } + + ComponentWrapper cAnimation = m_FirstPersonModel["Animation"]; + std::string& animationName1 = cAnimation["AnimationName1"]; + double& animationSpeed1 = cAnimation["Speed1"]; + + std::string animationToPlay = "Idle"; + double speedToSet = 1.0; + + ComponentWrapper cPlayer = m_Entity["Player"]; + glm::vec3 movementDirection = cPlayer["CurrentWishDirection"]; + if (glm::length2(movementDirection) > 0) { + animationToPlay = "Run"; + ComponentWrapper cPhysics = m_Entity["Physics"]; + speedToSet = glm::length((glm::vec3)cPhysics["Velocity"]) / (float)cPlayer["MovementSpeed"]; + } + + if (animationName1 != animationToPlay) { + cAnimation["AnimationName1"] = animationToPlay; + cAnimation["Weight1"] = 1.0; + cAnimation["Time1"] = 0.0; + cAnimation["Loop1"] = true; + } + + if (animationSpeed1 != speedToSet) { + cAnimation["Speed1"] = speedToSet; + } +} + diff --git a/src/Game/Systems/WeaponSystem.cpp b/src/Game/Systems/Weapon/WeaponSystem.cpp similarity index 97% rename from src/Game/Systems/WeaponSystem.cpp rename to src/Game/Systems/Weapon/WeaponSystem.cpp index eeb7dd00..bdd27ea9 100644 --- a/src/Game/Systems/WeaponSystem.cpp +++ b/src/Game/Systems/Weapon/WeaponSystem.cpp @@ -1,4 +1,4 @@ -#include "Systems/WeaponSystem.h" +#include "Systems/Weapon/WeaponSystem.h" WeaponSystem::WeaponSystem(SystemParams params, IRenderer* renderer, Octree* collisionOctree) : System(params) @@ -24,7 +24,8 @@ void WeaponSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cPla if (it == m_ActiveWeapons.end()) { selectWeapon(entity, 1); } - + + m_EventBroker->Process(); m_ActiveWeapons.at(entity)->Update(dt); } From 6caa7e94a4945cfd7bf2944cfe0bb8b515a6a701 Mon Sep 17 00:00:00 2001 From: Teejoon Date: Thu, 11 Feb 2016 18:28:33 +0100 Subject: [PATCH 13/26] RGB is now the only channels thats beeing usesed in splatmap --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index c56f6380..0107c7df 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit c56f6380ab05c23419beafe14190013d1432e32c +Subproject commit 0107c7dfdfd02bc4966b35ed6ee0f0f3e366f23d From f088aa1d85d82bbc78a50006a6effc19c7330bfa Mon Sep 17 00:00:00 2001 From: Teejoon Date: Thu, 11 Feb 2016 18:45:48 +0100 Subject: [PATCH 14/26] Commit the files now.... --- .../Shaders/ForwardPlusSplatMapRGB.frag.glsl | 245 ++++++++++++++++++ src/Engine/Rendering/DrawFinalPass.cpp | 16 +- 2 files changed, 253 insertions(+), 8 deletions(-) create mode 100644 resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl diff --git a/resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl b/resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl new file mode 100644 index 00000000..e862d926 --- /dev/null +++ b/resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl @@ -0,0 +1,245 @@ +#version 430 + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; +uniform vec2 ScreenDimensions; +uniform float FillPercentage; +uniform vec4 DiffuseColor; +uniform vec4 FillColor; +uniform vec4 Color; +uniform vec4 AmbientColor; + +//Get bineded at the same time as the textures +uniform vec2 DiffuseUVRepeat1; +uniform vec2 DiffuseUVRepeat2; +uniform vec2 DiffuseUVRepeat3; +uniform vec2 NormalUVRepeat1; +uniform vec2 NormalUVRepeat2; +uniform vec2 NormalUVRepeat3; +uniform vec2 SpecularUVRepeat1; +uniform vec2 SpecularUVRepeat2; +uniform vec2 SpecularUVRepeat3; +uniform vec2 GlowUVRepeat1; +uniform vec2 GlowUVRepeat2; +uniform vec2 GlowUVRepeat3; +layout (binding = 0) uniform sampler2D SplatMapTexture; +layout (binding = 1) uniform sampler2D DiffuseTexture1; +layout (binding = 2) uniform sampler2D DiffuseTexture2; +layout (binding = 3) uniform sampler2D DiffuseTexture3; +layout (binding = 4) uniform sampler2D NormalMapTexture1; +layout (binding = 5) uniform sampler2D NormalMapTexture2; +layout (binding = 6) uniform sampler2D NormalMapTexture3; +layout (binding = 7) uniform sampler2D SpecularMapTexture1; +layout (binding = 8) uniform sampler2D SpecularMapTexture2; +layout (binding = 9) uniform sampler2D SpecularMapTexture3; +layout (binding = 10) uniform sampler2D GlowMapTexture1; +layout (binding = 11) uniform sampler2D GlowMapTexture2; +layout (binding = 12) uniform sampler2D GlowMapTexture3; + +#define TILE_SIZE 16 + +struct LightSource { + vec4 Position; + vec4 Direction; + vec4 Color; + float Radius; + float Intensity; + float Falloff; + int Type; +}; + +layout (std430, binding = 1) buffer LightBuffer +{ + LightSource List[]; +} LightSources; + +struct LightGrid { + float Start; + float Amount; + vec2 Padding; +}; + +layout (std430, binding = 2) buffer LightGridBuffer +{ + LightGrid Data[]; +} LightGrids; + +layout (std430, binding = 4) buffer LightIndexBuffer +{ + float LightIndex[]; +}; + + +in VertexData{ + vec3 Position; + vec3 Normal; + vec3 Tangent; + vec3 BiTangent; + vec2 TextureCoordinate; + vec4 ExplosionColor; + float ExplosionPercentageElapsed; +}Input; + +out vec4 sceneColor; +out vec4 bloomColor; + +struct LightResult { + vec4 Diffuse; + vec4 Specular; +}; + +float CalcAttenuation(float radius, float dist, float falloff) { + return 1.0 - smoothstep(radius * 0.3, radius, dist); +} + +vec4 CalcSpecular(vec4 lightColor, vec4 viewVec, vec4 lightVec, vec4 normal) { + vec4 R = normalize( reflect(-lightVec, normal)); + float RdotV = max( dot(R, viewVec), 0.0); + return lightColor * pow(RdotV, 90.0); +} + +vec4 CalcDiffuse(vec4 lightColor, vec4 lightVec, vec4 normal) { + float power = max( dot(normal, lightVec), 0.0); + return lightColor * power; +} + +LightResult CalcPointLightSource(vec4 lightPos, float lightRadius, vec4 lightColor, float intensity, vec4 viewVec, vec4 position, vec4 normal, float falloff) +{ + vec4 L = lightPos - position; + float dist = length(L); + L = normalize(L); + + float attenuation = CalcAttenuation(lightRadius, dist, falloff); + + LightResult result; + result.Diffuse = CalcDiffuse(lightColor, L, normal) * attenuation * intensity; + result.Specular = CalcSpecular(lightColor, viewVec, L, normal) * attenuation * intensity; + return result; +} + +LightResult CalcDirectionalLightSource(vec4 direction, vec4 color, float intensity, vec4 viewVec, vec4 vertNormal) +{ + vec4 L = normalize( -vec4(direction.xyz, 0) ); + + LightResult result; + result.Diffuse = CalcDiffuse(color, L, vertNormal) * intensity; + result.Specular = CalcSpecular(color, viewVec, L, vertNormal) * intensity; + return result; +} + +vec4 CalcNormalMappedValue(vec3 normal, vec3 tangent, vec3 bitangent, vec2 textureCoordinate, sampler2D normalMap) +{ + mat3 TBN = mat3(tangent, bitangent, normal); + vec3 NormalMap = texture(normalMap, textureCoordinate).xyz * 2.0 - vec3(1.0); + return vec4(TBN * normalize(NormalMap), 0.0); +} + +vec4 CalcBlendedTexel(vec4 blendValue, sampler2D R, sampler2D G, sampler2D B, + vec2 R_TileValues, vec2 G_TileValues, vec2 B_TileValues){ + vec4 R_Channel = texture2D(R, Input.TextureCoordinate * R_TileValues); + vec4 G_Channel = texture2D(G, Input.TextureCoordinate * G_TileValues); + vec4 B_Channel = texture2D(B, Input.TextureCoordinate * B_TileValues); + + float total = blendValue.r + blendValue.g + blendValue.b; + float totalDiv = 1.0f / total; + blendValue.r = blendValue.r * totalDiv; + blendValue.g = blendValue.g * totalDiv; + blendValue.b = blendValue.b * totalDiv; + + return blendValue.r * R_Channel + + blendValue.g * G_Channel + + blendValue.b * B_Channel; +} + +vec4 CalcBlendedNormal(vec4 blendValue, sampler2D R, sampler2D G, sampler2D B, + vec2 R_TileValues, vec2 G_TileValues, vec2 B_TileValues){ + mat3 TBN = mat3(Input.Tangent, Input.BiTangent, Input.Normal); + vec3 R_Channel = texture(R, Input.TextureCoordinate * R_TileValues).xyz * 2.0 - vec3(1.0); + vec3 G_Channel = texture(G, Input.TextureCoordinate * G_TileValues).xyz * 2.0 - vec3(1.0); + vec3 B_Channel = texture(B, Input.TextureCoordinate * B_TileValues).xyz * 2.0 - vec3(1.0); + + float total = blendValue.r + blendValue.g + blendValue.b + blendValue.a; + float totalDiv = 1 / total; + blendValue.r = blendValue.r * totalDiv; + blendValue.g = blendValue.g * totalDiv; + blendValue.b = blendValue.b * totalDiv; + + vec3 Normal_result = blendValue.r * R_Channel + + blendValue.g * G_Channel + + blendValue.b * B_Channel; + + return vec4(TBN * normalize(Normal_result), 0.0); +} + +void main() +{ + vec4 splatTexel = texture2D(SplatMapTexture, Input.TextureCoordinate); + + vec4 diffuseTexel = CalcBlendedTexel(splatTexel, DiffuseTexture1, DiffuseTexture2, DiffuseTexture3, + DiffuseUVRepeat1, DiffuseUVRepeat2, DiffuseUVRepeat3); + vec4 glowTexel = CalcBlendedTexel(splatTexel, GlowMapTexture1, GlowMapTexture2, GlowMapTexture3, + GlowUVRepeat1, GlowUVRepeat2, GlowUVRepeat3); + vec4 specularTexel = CalcBlendedTexel(splatTexel, SpecularMapTexture1, SpecularMapTexture2, SpecularMapTexture3, + SpecularUVRepeat1, SpecularUVRepeat2, SpecularUVRepeat3); + vec4 position = V * M * vec4(Input.Position, 1.0); + //vec4 normal = V * CalcNormalMappedValue(Input.Normal, Input.Tangent, Input.BiTangent, Input.TextureCoordinate, SplatMapTexture); + vec4 normal = V * CalcBlendedNormal(splatTexel, NormalMapTexture1, NormalMapTexture2, NormalMapTexture3, + NormalUVRepeat1, NormalUVRepeat2, NormalUVRepeat3); + normal = normalize(normal); + //vec4 normal = normalize(V * vec4(Input.Normal, 0.0)); + vec4 viewVec = normalize(-position); + + vec2 tilePos; + tilePos.x = int(gl_FragCoord.x/TILE_SIZE); + tilePos.y = int(gl_FragCoord.y/TILE_SIZE); + + LightResult totalLighting; + totalLighting.Diffuse = vec4(AmbientColor.rgb, 1.0); + int currentTile = int(floor(gl_FragCoord.x/TILE_SIZE) + (floor(gl_FragCoord.y/TILE_SIZE) * int(ScreenDimensions.x/TILE_SIZE))); + + int start = int(LightGrids.Data[currentTile].Start); + int amount = int(LightGrids.Data[currentTile].Amount); + + for(int i = start; i < start + amount; i++) { + + int l = int(LightIndex[i]); + LightSource light = LightSources.List[l]; + + LightResult light_result; + //These if statements should be removed. + if(light.Type == 1) { // point + light_result = CalcPointLightSource(V * light.Position, light.Radius, light.Color, light.Intensity, viewVec, position, normal, light.Falloff); + } else if (light.Type == 2) { //Directional + light_result = CalcDirectionalLightSource(V * light.Direction, light.Color, light.Intensity, viewVec, normal); + } + totalLighting.Diffuse += light_result.Diffuse; + totalLighting.Specular += light_result.Specular; + } + + vec4 color_result = mix((Color * diffuseTexel * DiffuseColor), Input.ExplosionColor, Input.ExplosionPercentageElapsed); + color_result = color_result * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)); + //vec4 color_result = (DiffuseColor + Input.ExplosionColor) * (totalLighting.Diffuse + (totalLighting.Specular * specularTexel)) * diffuseTexel * Color; + + + 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); + + //Tiled Debug Code + /* + if(int(gl_FragCoord.x)%16 == 0 || int(gl_FragCoord.y)%16 == 0 ) { + sceneColor += vec4(0.5, 0, 0, 0); + } else { + sceneColor += vec4(LightGrids.Data[int(tilePos.x + tilePos.y*80)].Amount/LightSources.List.length(), 0, 0, 1); + } + */ +} + + diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 0d08b98f..bd57df3a 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -81,7 +81,7 @@ void DrawFinalPass::InitializeShaderPrograms() m_ForwardPlusSplatMapProgram = ResourceManager::Load("#ForwardPlusSplatMapProgram"); m_ForwardPlusSplatMapProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlus.vert.glsl"))); - m_ForwardPlusSplatMapProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusSplatMap.frag.glsl"))); + m_ForwardPlusSplatMapProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusSplatMapRGB.frag.glsl"))); m_ForwardPlusSplatMapProgram->Compile(); m_ForwardPlusSplatMapProgram->BindFragDataLocation(0, "sceneColor"); m_ForwardPlusSplatMapProgram->BindFragDataLocation(1, "bloomColor"); @@ -91,7 +91,7 @@ void DrawFinalPass::InitializeShaderPrograms() m_ExplosionEffectSplatMapProgram = ResourceManager::Load("#ExplosionEffectSplatMapProgram"); m_ExplosionEffectSplatMapProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlus.vert.glsl"))); m_ExplosionEffectSplatMapProgram->AddShader(std::shared_ptr(new GeometryShader("Shaders/ExplosionEffect.geom.glsl"))); - m_ExplosionEffectSplatMapProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusSplatMap.frag.glsl"))); + m_ExplosionEffectSplatMapProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusSplatMapRGB.frag.glsl"))); m_ExplosionEffectSplatMapProgram->Compile(); m_ExplosionEffectSplatMapProgram->BindFragDataLocation(0, "sceneColor"); m_ExplosionEffectSplatMapProgram->BindFragDataLocation(1, "bloomColor"); @@ -119,7 +119,7 @@ void DrawFinalPass::InitializeShaderPrograms() m_ExplosionEffectSplatMapSkinnedProgram = ResourceManager::Load("#ExplosionEffectSplatMapSkinnedProgram"); m_ExplosionEffectSplatMapSkinnedProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlusSkinned.vert.glsl"))); - m_ExplosionEffectSplatMapSkinnedProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusSplatMap.frag.glsl"))); + m_ExplosionEffectSplatMapSkinnedProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusSplatMapRGB.frag.glsl"))); m_ExplosionEffectSplatMapSkinnedProgram->Compile(); m_ExplosionEffectSplatMapSkinnedProgram->BindFragDataLocation(0, "sceneColor"); m_ExplosionEffectSplatMapSkinnedProgram->BindFragDataLocation(1, "bloomColor"); @@ -128,7 +128,7 @@ void DrawFinalPass::InitializeShaderPrograms() m_ForwardPlusSplatMapSkinnedProgram = ResourceManager::Load("#ForwardPlusSplatMapSkinnedProgram"); m_ForwardPlusSplatMapSkinnedProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ForwardPlusSkinned.vert.glsl"))); - m_ForwardPlusSplatMapSkinnedProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusSplatMap.frag.glsl"))); + m_ForwardPlusSplatMapSkinnedProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ForwardPlusSplatMapRGB.frag.glsl"))); m_ForwardPlusSplatMapSkinnedProgram->Compile(); m_ForwardPlusSplatMapSkinnedProgram->BindFragDataLocation(0, "sceneColor"); m_ForwardPlusSplatMapSkinnedProgram->BindFragDataLocation(1, "bloomColor"); @@ -892,7 +892,7 @@ void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptrDiffuseTexture.size() > i && job->DiffuseTexture[i]->Texture != nullptr) { glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture[i]->Texture->m_Texture); @@ -906,7 +906,7 @@ void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptrNormalTexture.size() > i && job->NormalTexture[i]->Texture != nullptr) { glBindTexture(GL_TEXTURE_2D, job->NormalTexture[i]->Texture->m_Texture); @@ -920,7 +920,7 @@ void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptrSpecularTexture.size() > i && job->SpecularTexture[i]->Texture != nullptr) { glBindTexture(GL_TEXTURE_2D, job->SpecularTexture[i]->Texture->m_Texture); @@ -934,7 +934,7 @@ void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptrIncandescenceTexture.size() > i && job->IncandescenceTexture[i]->Texture != nullptr) { glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture[i]->Texture->m_Texture); From 99747c518efec59e8270caf5b410fcdc915be44a Mon Sep 17 00:00:00 2001 From: Teejoon Date: Thu, 11 Feb 2016 18:48:07 +0100 Subject: [PATCH 15/26] commit assets --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 66e2a73b..105b22fc 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 66e2a73bdb2c385cac37476980809cc587e2e612 +Subproject commit 105b22fc67b68993db43deec3250084ed625d893 From f79649cf9a5a80eed6699581342d34516a12172d Mon Sep 17 00:00:00 2001 From: Teejoon Date: Thu, 11 Feb 2016 19:38:43 +0100 Subject: [PATCH 16/26] Fixed material file reading bug --- src/Engine/Rendering/RawModelCustom.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engine/Rendering/RawModelCustom.cpp b/src/Engine/Rendering/RawModelCustom.cpp index 4ebf80b6..dd6a96de 100644 --- a/src/Engine/Rendering/RawModelCustom.cpp +++ b/src/Engine/Rendering/RawModelCustom.cpp @@ -277,8 +277,8 @@ void RawModelCustom::ReadMaterialTextureProperties(RawModelCustom::TextureProper throw Resource::FailedLoadingException("Reading Material texture UVTiling failed"); } memcpy(&texture.UVRepeat[0], fileData + offset, sizeof(glm::vec2)); - offset += sizeof(glm::vec2); } + offset += sizeof(glm::vec2); } void RawModelCustom::ReadAnimationFile(std::string filePath) From fee1ed6d6d4e65e51403b5da162900c5a82fb624 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Thu, 11 Feb 2016 20:00:59 +0100 Subject: [PATCH 17/26] FIXME: Temporarily removed glow from sprite shader to prevent transparent sprite from occluding other glow --- resources/Shaders/Sprite.frag.glsl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/Shaders/Sprite.frag.glsl b/resources/Shaders/Sprite.frag.glsl index a1ff3025..9ce2bbdf 100644 --- a/resources/Shaders/Sprite.frag.glsl +++ b/resources/Shaders/Sprite.frag.glsl @@ -34,7 +34,8 @@ void main() } sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1)); - bloomColor = vec4(clamp((glowTexel.xyz*3) - 1.0, 0, 100), 1.0); + //bloomColor = vec4(clamp((glowTexel.xyz*3) - 1.0, 0, 100), 1.0); + bloomColor = vec4(1.0, 1.0, 1.0, 0.0); } From 5e05e51309d2eae3434c0d368710b2bec776aa71 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Thu, 11 Feb 2016 20:01:23 +0100 Subject: [PATCH 18/26] Fixed EntityFirstHitByRay not returning outDistance properly --- include/Engine/Collision/Collision.h | 4 ++-- src/Engine/Collision/Collision.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/Engine/Collision/Collision.h b/include/Engine/Collision/Collision.h index 5b4150d8..546d03f5 100644 --- a/include/Engine/Collision/Collision.h +++ b/include/Engine/Collision/Collision.h @@ -90,10 +90,10 @@ 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); +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); +boost::optional EntityFirstHitByRay(const Ray& ray, Octree* octree, float& outDistance, glm::vec3& outIntersectPos); } diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index 7b182de1..ab2098b7 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -642,7 +642,7 @@ boost::optional AbsoluteAABBExplosionEffect(EntityWrapper& entity) return aabb; } -boost::optional EntityFirstHitByRay(const Ray& ray, std::vector entitiesPotentiallyHitSorted, float outDistance, glm::vec3& outIntersectPos) +boost::optional EntityFirstHitByRay(const Ray& ray, std::vector entitiesPotentiallyHitSorted, float& outDistance, glm::vec3& outIntersectPos) { for (EntityAABB& entityBox : entitiesPotentiallyHitSorted) { if (!entityBox.Entity.HasComponent("Model")) { @@ -667,7 +667,7 @@ boost::optional EntityFirstHitByRay(const Ray& ray, std::vector EntityFirstHitByRay(const Ray& ray, Octree* octree, float outDistance, glm::vec3& outIntersectPos) +boost::optional EntityFirstHitByRay(const Ray& ray, Octree* octree, float& outDistance, glm::vec3& outIntersectPos) { std::vector outObjects; octree->ObjectsPossiblyHitByRay(ray, outObjects); From bd385a0d59a90edec4aca9beb5de614e59a4b17b Mon Sep 17 00:00:00 2001 From: viktorljung Date: Thu, 11 Feb 2016 20:15:56 +0100 Subject: [PATCH 19/26] new assets --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index c56f6380..01df0799 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit c56f6380ab05c23419beafe14190013d1432e32c +Subproject commit 01df07998ba0d7ddc2e32168bd88b6adf502e094 From 8f500965d481a2621a8f4a9e5d8536f5938d9d92 Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Thu, 11 Feb 2016 20:34:25 +0100 Subject: [PATCH 20/26] Changed DamageIndicator.xml to not use a glowmap and not a depthsort. --- include/Game/Systems/DamageIndicatorSystem.h | 5 ++++- resources/Schema/Entities/DamageIndicator.xml | 5 +++-- resources/Schema/Entities/DamageIndicatorTest.xml | 8 ++------ src/Game/Systems/CapturePointHUDSystem.cpp | 3 +++ src/Game/Systems/DamageIndicatorSystem.cpp | 10 +++++++--- 5 files changed, 19 insertions(+), 12 deletions(-) diff --git a/include/Game/Systems/DamageIndicatorSystem.h b/include/Game/Systems/DamageIndicatorSystem.h index fd3ba33f..e70a69a9 100644 --- a/include/Game/Systems/DamageIndicatorSystem.h +++ b/include/Game/Systems/DamageIndicatorSystem.h @@ -13,10 +13,12 @@ #include #include +#include "Rendering/Util/CommonFunctions.h" + class DamageIndicatorSystem : public System { public: - DamageIndicatorSystem(World* world, EventBroker* eventBroker); + DamageIndicatorSystem(SystemParams params); private: EventRelay m_DamageTakenFromPlayer; @@ -26,5 +28,6 @@ private: bool OnSetCamera(const Events::SetCamera& e); EntityID m_CurrentCamera = -1; + }; #endif diff --git a/resources/Schema/Entities/DamageIndicator.xml b/resources/Schema/Entities/DamageIndicator.xml index 2d02443c..3e9e4fef 100644 --- a/resources/Schema/Entities/DamageIndicator.xml +++ b/resources/Schema/Entities/DamageIndicator.xml @@ -3,8 +3,9 @@ - Textures/TempDamageIndicator.png - Textures/TempDamageIndicator.png + Textures/DamageIndicator.png + + false diff --git a/resources/Schema/Entities/DamageIndicatorTest.xml b/resources/Schema/Entities/DamageIndicatorTest.xml index ee68da96..1155ddd5 100644 --- a/resources/Schema/Entities/DamageIndicatorTest.xml +++ b/resources/Schema/Entities/DamageIndicatorTest.xml @@ -382,14 +382,10 @@ - - Hold Pos - - 1 - + - Models/AssaultAnimated.mesh + Models/Characters/Assault/AssaultAnimations.mesh diff --git a/src/Game/Systems/CapturePointHUDSystem.cpp b/src/Game/Systems/CapturePointHUDSystem.cpp index 784c7e16..21737fbe 100644 --- a/src/Game/Systems/CapturePointHUDSystem.cpp +++ b/src/Game/Systems/CapturePointHUDSystem.cpp @@ -16,6 +16,9 @@ void CapturePointHUDSystem::Update(double dt) auto CapturePointHUDElements = m_World->GetComponents("CapturePointHUD"); auto CapturePoints = m_World->GetComponents("CapturePoint"); + if (CapturePointHUDElements == nullptr) { + return; + } for (auto& cCapturePointHUD : *CapturePointHUDElements) { int HUD_ID = cCapturePointHUD["CapturePointNumber"]; diff --git a/src/Game/Systems/DamageIndicatorSystem.cpp b/src/Game/Systems/DamageIndicatorSystem.cpp index 638307bf..93385e48 100644 --- a/src/Game/Systems/DamageIndicatorSystem.cpp +++ b/src/Game/Systems/DamageIndicatorSystem.cpp @@ -1,11 +1,15 @@ #include "Systems/DamageIndicatorSystem.h" -DamageIndicatorSystem::DamageIndicatorSystem(World* m_World, EventBroker* eventBroker) - : System(m_World, eventBroker) +DamageIndicatorSystem::DamageIndicatorSystem(SystemParams params) + : System(params) { EVENT_SUBSCRIBE_MEMBER(m_DamageTakenFromPlayer, &DamageIndicatorSystem::OnPlayerDamageTaken); //current camera EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &DamageIndicatorSystem::OnSetCamera); + + //load texture to cache + auto texture = CommonFunctions::LoadTexture("Textures/DamageIndicator.png", false); + auto entityFile = ResourceManager::Load("Schema/Entities/DamageIndicator.xml"); } bool DamageIndicatorSystem::OnPlayerDamageTaken(Events::PlayerDamage& e) @@ -58,4 +62,4 @@ bool DamageIndicatorSystem::OnPlayerDamageTaken(Events::PlayerDamage& e) bool DamageIndicatorSystem::OnSetCamera(const Events::SetCamera& e) { m_CurrentCamera = e.CameraEntity.ID; return true; -} \ No newline at end of file +} From 3a15550b57faf975d0e651199b748f933d0e49b2 Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Thu, 11 Feb 2016 21:07:47 +0100 Subject: [PATCH 21/26] maybe a good commit --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 8ffd0a99..dfa0fc61 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 8ffd0a99b9a2e5c140307d382a25c4a470cc8f33 +Subproject commit dfa0fc61ab88456f3461779bd7c6ac97d15f6493 From 4a17e3c8f384dc2a998d75f55baeb5a350d978cd Mon Sep 17 00:00:00 2001 From: verysecrethero Date: Thu, 11 Feb 2016 21:42:29 +0100 Subject: [PATCH 22/26] airFriction changed to 2.0 to fix the dash ability in the air --- src/Game/Systems/PlayerMovementSystem.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index 93f0cd3d..bad512df 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -233,7 +233,8 @@ void PlayerMovementSystem::updateVelocity(double dt) float speed = glm::length(velocity); static float groundFriction = 7.f; ImGui::InputFloat("groundFriction", &groundFriction); - static float airFriction = 0.f; + static float airFriction = 2.f; + ImGui::InputFloat("airFriction", &airFriction); float friction = isOnGround ? groundFriction : airFriction; if (speed > 0) { From d1213f9f59d36d25813e8a5cd90f6106edcdd322 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Thu, 11 Feb 2016 22:50:44 +0100 Subject: [PATCH 23/26] Working damage dealing, a super cool reload effect and hit markers! --- assets | 2 +- include/Engine/Core/EPlayerDamage.h | 4 +- include/Engine/Core/EShoot.h | 3 +- .../Systems/Weapon/AssaultWeaponBehaviour.h | 12 +- include/Game/Systems/Weapon/WeaponBehaviour.h | 9 +- include/Game/Systems/Weapon/WeaponSystem.h | 2 - resources/Schema/Components/AssaultWeapon.xml | 1 + resources/Schema/Components/AssaultWeapon.xsd | 3 + resources/Schema/Entities/HitMarker.xml | 20 ++ resources/Schema/Entities/MovementTest.xml | 158 ++++++++++++- resources/Schema/Entities/Player.xml | 46 +++- .../Schema/Entities/WeaponReloadEffect.xml | 31 +++ src/Engine/Core/EntityFilePreprocessor.cpp | 1 - src/Engine/Network/Client.cpp | 3 +- src/Engine/Network/Server.cpp | 3 +- src/Game/Systems/HealthSystem.cpp | 4 +- src/Game/Systems/PlayerDeathSystem.cpp | 14 +- src/Game/Systems/SoundSystem.cpp | 2 +- src/Game/Systems/SpawnerSystem.cpp | 10 +- .../Systems/Weapon/AssaultWeaponBehaviour.cpp | 218 +++++++++++++++--- src/Game/Systems/Weapon/WeaponSystem.cpp | 60 +---- src/Tests/HealthSystemTest.cpp | 2 +- 22 files changed, 473 insertions(+), 135 deletions(-) create mode 100644 resources/Schema/Entities/HitMarker.xml create mode 100644 resources/Schema/Entities/WeaponReloadEffect.xml diff --git a/assets b/assets index 8ffd0a99..4d36fdce 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 8ffd0a99b9a2e5c140307d382a25c4a470cc8f33 +Subproject commit 4d36fdced7007a594a56b7371bb26861876889aa diff --git a/include/Engine/Core/EPlayerDamage.h b/include/Engine/Core/EPlayerDamage.h index 8ba3907e..6f3f2c12 100644 --- a/include/Engine/Core/EPlayerDamage.h +++ b/include/Engine/Core/EPlayerDamage.h @@ -9,8 +9,8 @@ namespace Events struct PlayerDamage : Event { - //NOTE: this struct is missing information on what the damageSource is - EntityWrapper Player; + EntityWrapper Inflictor; + EntityWrapper Victim; double Damage; }; diff --git a/include/Engine/Core/EShoot.h b/include/Engine/Core/EShoot.h index 76821a24..28346abb 100644 --- a/include/Engine/Core/EShoot.h +++ b/include/Engine/Core/EShoot.h @@ -9,7 +9,8 @@ namespace Events struct Shoot : Event { - EntityWrapper Player; + EntityWrapper Inflictor; + double Damage; }; } diff --git a/include/Game/Systems/Weapon/AssaultWeaponBehaviour.h b/include/Game/Systems/Weapon/AssaultWeaponBehaviour.h index 58d7755f..915854ff 100644 --- a/include/Game/Systems/Weapon/AssaultWeaponBehaviour.h +++ b/include/Game/Systems/Weapon/AssaultWeaponBehaviour.h @@ -1,12 +1,15 @@ #include "Sound/EPlaySoundOnEntity.h" +#include "Collision/Collision.h" #include "Rendering/AnimationSystem.h" #include "WeaponBehaviour.h" #include "../SpawnerSystem.h" +#include "Core/EPlayerDamage.h" +#include "Core/EShoot.h" class AssaultWeaponBehaviour : public WeaponBehaviour { public: - AssaultWeaponBehaviour(SystemParams systemParams, Octree* collisionOctree, EntityWrapper weaponEntity); + AssaultWeaponBehaviour(SystemParams systemParams, IRenderer* renderer, Octree* collisionOctree, EntityWrapper weaponEntity); virtual void Fire() override; virtual void CeaseFire() override; @@ -19,16 +22,23 @@ private: // State bool m_Firing = false; bool m_Reloading = false; + double m_ReloadTimer = 0.0; + EntityWrapper m_ReloadImpersonator; double m_TimeSinceLastFire = 0.0; EventRelay m_EAnimationComplete; bool OnAnimationComplete(Events::AnimationComplete& e); + bool hasAmmo(); void fireRound(); void spawnTracer(); float traceRayDistance(glm::vec3 origin, glm::vec3 direction); void playSound(); void viewPunch(); + void finishReload(); void playShootAnimation(); void playIdleAnimation(); + void playReloadAnimation(); + bool shoot(double damage); + void showHitMarker(); }; diff --git a/include/Game/Systems/Weapon/WeaponBehaviour.h b/include/Game/Systems/Weapon/WeaponBehaviour.h index 38ab5f58..7a0b4626 100644 --- a/include/Game/Systems/Weapon/WeaponBehaviour.h +++ b/include/Game/Systems/Weapon/WeaponBehaviour.h @@ -2,16 +2,18 @@ #define WeaponBehaviour_h__ #include "Core/System.h" +#include "Rendering/IRenderer.h" #include "Core/Octree.h" #include "Collision/EntityAABB.h" class WeaponBehaviour : public System { public: - WeaponBehaviour(SystemParams systemParams, Octree* collisionOctree, EntityWrapper weaponEntity) + WeaponBehaviour(SystemParams systemParams, IRenderer* renderer, Octree* collisionOctree, EntityWrapper player) : System(systemParams) + , m_Renderer(renderer) , m_CollisionOctree(collisionOctree) - , m_Entity(weaponEntity) + , m_Player(player) { } virtual ~WeaponBehaviour() = default; @@ -24,8 +26,9 @@ public: virtual void Update(double dt) { } protected: + IRenderer* m_Renderer; Octree* m_CollisionOctree; - EntityWrapper m_Entity; + EntityWrapper m_Player; }; #endif diff --git a/include/Game/Systems/Weapon/WeaponSystem.h b/include/Game/Systems/Weapon/WeaponSystem.h index 68cf2ef3..b8278bc4 100644 --- a/include/Game/Systems/Weapon/WeaponSystem.h +++ b/include/Game/Systems/Weapon/WeaponSystem.h @@ -35,8 +35,6 @@ private: // Events EventRelay m_EPlayerSpawned; bool OnPlayerSpawned(Events::PlayerSpawned& e); - EventRelay m_EShoot; - bool OnShoot(Events::Shoot& e); EventRelay m_EInputCommand; bool OnInputCommand(Events::InputCommand& e); diff --git a/resources/Schema/Components/AssaultWeapon.xml b/resources/Schema/Components/AssaultWeapon.xml index c7dbfb0d..6c645624 100755 --- a/resources/Schema/Components/AssaultWeapon.xml +++ b/resources/Schema/Components/AssaultWeapon.xml @@ -7,4 +7,5 @@ 5 120 0.01 + 2 \ No newline at end of file diff --git a/resources/Schema/Components/AssaultWeapon.xsd b/resources/Schema/Components/AssaultWeapon.xsd index 65558db5..95df64b7 100755 --- a/resources/Schema/Components/AssaultWeapon.xsd +++ b/resources/Schema/Components/AssaultWeapon.xsd @@ -25,6 +25,9 @@ View punch in radians for each bullet fired + + Time it takes to reload the weapon in seconds + diff --git a/resources/Schema/Entities/HitMarker.xml b/resources/Schema/Entities/HitMarker.xml new file mode 100644 index 00000000..74a539d0 --- /dev/null +++ b/resources/Schema/Entities/HitMarker.xml @@ -0,0 +1,20 @@ + + + + + + 0.1 + + + Textures/Weapons/Crosshair/SmallThickHoleDot.png + false + + + + + + + + + + diff --git a/resources/Schema/Entities/MovementTest.xml b/resources/Schema/Entities/MovementTest.xml index 16a28684..84aaa03a 100644 --- a/resources/Schema/Entities/MovementTest.xml +++ b/resources/Schema/Entities/MovementTest.xml @@ -124,10 +124,14 @@ + + 600 + - + + - false + 5 @@ -138,8 +142,7 @@ - - + @@ -147,7 +150,7 @@ - + @@ -156,10 +159,9 @@ Fonts/DroidSans.ttf,100 - false - + @@ -170,6 +172,7 @@ Models/Widgets/Camera.mesh + false @@ -178,6 +181,100 @@ + + + + + + + + + + + 1 + + + + + Models/Core/UnitHexagon.mesh + + + + + + + + + + + + + + Textures/Weapons/Crosshair/SmallThickHoleDot.png + false + + + + + + + + + + + + + + Idle + 1.9569972344146196 + 1 + + + Models/Characters/Assault/FirstPerson.mesh + true + + + + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Blue/AssaultWeaponBlue.mesh + true + + + + + + + + + + + Schema/Entities/RayBlue.xml + + + + + + + + + + + + + Schema/Entities/WeaponReloadEffect.xml + + + + + + + @@ -196,15 +293,52 @@ + + Idle + 1.8055945618467364 + 1 + + + AimRifle + + + - Models/Characters/Assault/AssaultHeadless.mesh + Models/Characters/Assault/AssaultAnimations.mesh - - - + - + + + + + R_Arm_Weapon_Joint + + + Models/Weapons/Blue/AssaultWeaponBlue.mesh + false + + + + + + + + + + + Schema/Entities/RayBlue.xml + + + + + + + + + + diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 4ba23a0d..9f8e0955 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -23,7 +23,9 @@ - + + + @@ -90,24 +92,33 @@ - - Models/Weapons/CrosshairQuad.mesh - + + Textures/Weapons/Crosshair/SmallThickHoleDot.png + false + - - + + + + + Schema/Entities/HitMarker.xml + + + + + Idle - 0.52743271827223559 + 0.1719161089749548 1 @@ -124,10 +135,11 @@ Models/Weapons/Blue/AssaultWeaponBlue.mesh + true - - + + @@ -144,6 +156,15 @@ + + + + Schema/Entities/WeaponReloadEffect.xml + + + + + @@ -166,7 +187,7 @@ Idle - 0.69666320633760392 + 1.8038469763698401 1 @@ -188,10 +209,11 @@ Models/Weapons/Blue/AssaultWeaponBlue.mesh + false - - + + diff --git a/resources/Schema/Entities/WeaponReloadEffect.xml b/resources/Schema/Entities/WeaponReloadEffect.xml new file mode 100644 index 00000000..3099b405 --- /dev/null +++ b/resources/Schema/Entities/WeaponReloadEffect.xml @@ -0,0 +1,31 @@ + + + + + + R_Arm_Weapon_Joint + + + 2 + + + true + + + true + + true + + + Models/Weapons/Blue/AssaultWeaponBlue.mesh + true + + + + + + + + + + diff --git a/src/Engine/Core/EntityFilePreprocessor.cpp b/src/Engine/Core/EntityFilePreprocessor.cpp index 86217979..a1370dd2 100644 --- a/src/Engine/Core/EntityFilePreprocessor.cpp +++ b/src/Engine/Core/EntityFilePreprocessor.cpp @@ -65,7 +65,6 @@ void EntityFilePreprocessor::parseComponentInfo() // Name compInfo.Name = XS::ToString(element->getName()); - bool brk = compInfo.Name == "HiddenForLocalPlayer"; // Known allocation compInfo.Meta->Allocation = m_ComponentCounts[compInfo.Name]; // Annotation diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 7d2c8f92..b03aad07 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -390,8 +390,9 @@ bool Client::OnInputCommand(const Events::InputCommand & e) bool Client::OnPlayerDamage(const Events::PlayerDamage & e) { Packet packet(MessageType::OnPlayerDamage, m_SendPacketID); + packet.WritePrimitive(m_ClientIDToServerID.at(e.Inflictor.ID)); + packet.WritePrimitive(m_ClientIDToServerID.at(e.Victim.ID)); packet.WritePrimitive(e.Damage); - packet.WritePrimitive(m_ClientIDToServerID.at(e.Player.ID)); send(packet); return false; } diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 7ad1cc76..1f0b3bc7 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -299,8 +299,9 @@ void Server::parseOnInputCommand(Packet& packet) void Server::parseOnPlayerDamage(Packet & packet) { Events::PlayerDamage e; + e.Inflictor = EntityWrapper(m_World, packet.ReadPrimitive()); + e.Victim = EntityWrapper(m_World, packet.ReadPrimitive()); e.Damage = packet.ReadPrimitive(); - e.Player = EntityWrapper(m_World, packet.ReadPrimitive()); m_EventBroker->Publish(e); //LOG_DEBUG("Server::parseOnPlayerDamage: Command is %s. Value is %f. PlayerID is %i.", e.DamageAmount, e.PlayerDamagedID, e.TypeOfDamage.c_str()); } diff --git a/src/Game/Systems/HealthSystem.cpp b/src/Game/Systems/HealthSystem.cpp index bb02ea13..29d8790d 100644 --- a/src/Game/Systems/HealthSystem.cpp +++ b/src/Game/Systems/HealthSystem.cpp @@ -15,13 +15,13 @@ void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& comp bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e) { - ComponentWrapper cHealth = e.Player["Health"]; + ComponentWrapper cHealth = e.Victim["Health"]; double& health = cHealth["Health"]; health -= e.Damage; if (health <= 0.0) { Events::PlayerDeath ePlayerDeath; - ePlayerDeath.Player = e.Player; + ePlayerDeath.Player = e.Victim; m_EventBroker->Publish(ePlayerDeath); //Note: we will delete the entity in PlayerDeathSystem } diff --git a/src/Game/Systems/PlayerDeathSystem.cpp b/src/Game/Systems/PlayerDeathSystem.cpp index 29ed9832..78e20490 100644 --- a/src/Game/Systems/PlayerDeathSystem.cpp +++ b/src/Game/Systems/PlayerDeathSystem.cpp @@ -41,7 +41,9 @@ void PlayerDeathSystem::createDeathEffect(EntityWrapper player) playerEntityModel.Copy(deathEffectEW["Model"]); playerEntityAnimation.Copy(deathEffectEW["Animation"]); //freeze the animation - deathEffectEW["Animation"]["Speed"] = 0.0; + deathEffectEW["Animation"]["Speed1"] = 0.0; + deathEffectEW["Animation"]["Speed2"] = 0.0; + deathEffectEW["Animation"]["Speed3"] = 0.0; //copy the models position,orientation deathEffectEW["Transform"]["Position"] = (glm::vec3)player["Transform"]["Position"]; @@ -50,8 +52,10 @@ void PlayerDeathSystem::createDeathEffect(EntityWrapper player) //deathEffectEW["ExplosionEffect"]["ExplosionOrigin"] = glm::vec3(0, 0, 0); //camera (with lifetime) behind the player - auto cam = deathEffectEW.FirstChildByName("Camera"); - Events::SetCamera eSetCamera; - eSetCamera.CameraEntity = cam; - m_EventBroker->Publish(eSetCamera); + if (player == LocalPlayer) { + auto cam = deathEffectEW.FirstChildByName("Camera"); + Events::SetCamera eSetCamera; + eSetCamera.CameraEntity = cam; + m_EventBroker->Publish(eSetCamera); + } } diff --git a/src/Game/Systems/SoundSystem.cpp b/src/Game/Systems/SoundSystem.cpp index 10dc61f7..d6ac7dab 100644 --- a/src/Game/Systems/SoundSystem.cpp +++ b/src/Game/Systems/SoundSystem.cpp @@ -54,7 +54,7 @@ bool SoundSystem::OnInputCommand(const Events::InputCommand & e) } if (e.Command == "TakeDamage" && e.Value > 0) { Events::PlayerDamage ev; - ev.Player = LocalPlayer; + ev.Victim = LocalPlayer; ev.Damage = 1.0; m_EventBroker->Publish(ev); } diff --git a/src/Game/Systems/SpawnerSystem.cpp b/src/Game/Systems/SpawnerSystem.cpp index 99f5df93..b3c556f1 100644 --- a/src/Game/Systems/SpawnerSystem.cpp +++ b/src/Game/Systems/SpawnerSystem.cpp @@ -48,10 +48,12 @@ EntityWrapper SpawnerSystem::Spawn(EntityWrapper spawner, EntityWrapper parent / EntityFileParser parser(entityFile); EntityWrapper spawnedEntity(world, parser.MergeEntities(world, parent.ID)); - // 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)); + if (spawnPoint != 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)); + } return spawnedEntity; } diff --git a/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp b/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp index bb5a025f..724e1f2c 100644 --- a/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp +++ b/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp @@ -1,9 +1,9 @@ #include "Systems/Weapon/AssaultWeaponBehaviour.h" -AssaultWeaponBehaviour::AssaultWeaponBehaviour(SystemParams systemParams, Octree* collisionOctree, EntityWrapper weaponEntity) - : WeaponBehaviour(systemParams, collisionOctree, weaponEntity) +AssaultWeaponBehaviour::AssaultWeaponBehaviour(SystemParams systemParams, IRenderer* renderer, Octree* collisionOctree, EntityWrapper player) + : WeaponBehaviour(systemParams, renderer, collisionOctree, player) { - m_FirstPersonModel = m_Entity.FirstChildByName("Hands"); + m_FirstPersonModel = m_Player.FirstChildByName("Hands"); EVENT_SUBSCRIBE_MEMBER(m_EAnimationComplete, &AssaultWeaponBehaviour::OnAnimationComplete); } @@ -12,7 +12,6 @@ void AssaultWeaponBehaviour::Fire() m_TimeSinceLastFire = 0.0; m_Firing = true; fireRound(); - playShootAnimation(); } void AssaultWeaponBehaviour::CeaseFire() @@ -22,29 +21,48 @@ void AssaultWeaponBehaviour::CeaseFire() void AssaultWeaponBehaviour::Reload() { - ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"]; + if (m_Reloading) { + return; + } - int& magAmmo = cAssaultWeapon["MagazineAmmo"]; + ComponentWrapper& cAssaultWeapon = m_Player["AssaultWeapon"]; + int magAmmo = cAssaultWeapon["MagazineAmmo"]; int magSize = cAssaultWeapon["MagazineSize"]; - int& ammo = cAssaultWeapon["Ammo"]; + 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; + // Don't reload if we're completly out of ammo + if (ammo == 0) { + return; + } + + m_Reloading = true; + m_ReloadTimer = cAssaultWeapon["ReloadTime"]; + playReloadAnimation(); } void AssaultWeaponBehaviour::Update(double dt) { - if (m_Firing) { - m_TimeSinceLastFire += dt; + if (m_Reloading) { + m_ReloadTimer -= dt; + // Re-enable glow on reload impersonator half-way through the animation + if (m_ReloadTimer <= (double)m_Player["AssaultWeapon"]["ReloadTime"] / 2.0) { + if (m_ReloadImpersonator.Valid()) { + m_ReloadImpersonator["Model"]["GlowMap"] = true; + } + } + if (m_ReloadTimer <= 0) { + finishReload(); + } + } - ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"]; + if (m_Firing && !m_Reloading) { + m_TimeSinceLastFire += dt; + ComponentWrapper& cAssaultWeapon = m_Player["AssaultWeapon"]; if (m_TimeSinceLastFire >= 1.0 / ((double)cAssaultWeapon["RPM"] / 60.0)) { fireRound(); } @@ -53,6 +71,13 @@ void AssaultWeaponBehaviour::Update(double dt) if (!m_Firing && !m_Reloading) { playIdleAnimation(); } + + // Disable glow map on weapon if it's out of ammo + // Make real first person weapon model visible again + EntityWrapper firstPersonWeaponModel = m_Player.FirstChildByName("WeaponModel"); + if (firstPersonWeaponModel.Valid()) { + firstPersonWeaponModel["Model"]["GlowMap"] = hasAmmo(); + } } bool AssaultWeaponBehaviour::OnAnimationComplete(Events::AnimationComplete& e) @@ -70,9 +95,20 @@ bool AssaultWeaponBehaviour::OnAnimationComplete(Events::AnimationComplete& e) return true; } +bool AssaultWeaponBehaviour::hasAmmo() +{ + ComponentWrapper& cAssaultWeapon = m_Player["AssaultWeapon"]; + int& magAmmo = cAssaultWeapon["MagazineAmmo"]; + return magAmmo > 0; +} + void AssaultWeaponBehaviour::fireRound() { - ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"]; + if (m_Reloading) { + return; + } + + ComponentWrapper& cAssaultWeapon = m_Player["AssaultWeapon"]; int& magAmmo = cAssaultWeapon["MagazineAmmo"]; int ammo = cAssaultWeapon["Ammo"]; @@ -88,6 +124,11 @@ void AssaultWeaponBehaviour::fireRound() spawnTracer(); playSound(); viewPunch(); + playShootAnimation(); + bool hit = shoot(cAssaultWeapon["BaseDamage"]); + if (hit) { + showHitMarker(); + } m_TimeSinceLastFire = 0.0; } @@ -99,25 +140,32 @@ void AssaultWeaponBehaviour::spawnTracer() } EntityWrapper spawner; - if (m_Entity == LocalPlayer) { - spawner = m_Entity.FirstChildByName("WeaponMuzzle"); + if (m_Player == LocalPlayer) { + spawner = m_Player.FirstChildByName("WeaponMuzzle"); } else { - spawner = m_Entity.FirstChildByName("ThirdPersonWeaponMuzzle"); + spawner = m_Player.FirstChildByName("ThirdPersonWeaponMuzzle"); } if (!spawner.Valid()) { return; } - Events::SpawnerSpawn e; - e.Spawner = spawner; - m_EventBroker->Publish(e); + float distance = traceRayDistance(Transform::AbsolutePosition(spawner), Transform::AbsoluteOrientation(spawner) * glm::vec3(0, 0, -1)); + EntityWrapper ray = SpawnerSystem::Spawn(spawner); + ((glm::vec3&)ray["Transform"]["Scale"]).z = (distance / 100.f); } float AssaultWeaponBehaviour::traceRayDistance(glm::vec3 origin, glm::vec3 direction) { // TODO: Cast a ray and size tracer appropriately - return 100.f; + float distance; + glm::vec3 pos; + auto entity = Collision::EntityFirstHitByRay(Ray(origin, direction), m_CollisionOctree, distance, pos); + if (entity) { + return distance; + } else { + return 100.f; + } } void AssaultWeaponBehaviour::playSound() @@ -127,32 +175,52 @@ void AssaultWeaponBehaviour::playSound() } Events::PlaySoundOnEntity e; - e.EmitterID = m_Entity.ID; + e.EmitterID = m_Player.ID; e.FilePath = "Audio/laser/laser1.wav"; m_EventBroker->Publish(e); } void AssaultWeaponBehaviour::viewPunch() { - EntityWrapper playerCamera = m_Entity.FirstChildByName("Camera"); + EntityWrapper playerCamera = m_Player.FirstChildByName("Camera"); if (!playerCamera.Valid()) { return; } - float viewPunch = m_Entity["AssaultWeapon"]["ViewPunch"]; + float viewPunch = m_Player["AssaultWeapon"]["ViewPunch"]; ComponentWrapper cTransform = playerCamera["Transform"]; glm::vec3& orientation = cTransform["Orientation"]; orientation.x += viewPunch; } +void AssaultWeaponBehaviour::finishReload() +{ + ComponentWrapper& cAssaultWeapon = m_Player["AssaultWeapon"]; + int& magAmmo = cAssaultWeapon["MagazineAmmo"]; + int magSize = cAssaultWeapon["MagazineSize"]; + int& ammo = cAssaultWeapon["Ammo"]; + + // Throw away rounds in magazine to incentivise ammo sharing + int toLoad = glm::min(magSize, ammo); + magAmmo = toLoad; + ammo -= toLoad; + + // Make real first person weapon model visible again + EntityWrapper firstPersonWeaponModel = m_Player.FirstChildByName("WeaponModel"); + firstPersonWeaponModel["Model"]["Visible"] = true; + + m_Reloading = false; +} + void AssaultWeaponBehaviour::playShootAnimation() { - EntityWrapper firstPersonWeapon = m_Entity.FirstChildByName("Hands"); - ComponentWrapper cAnimation = firstPersonWeapon["Animation"]; - cAnimation["AnimationName1"] = "ShootRifle"; - cAnimation["Weight1"] = 1.0; - cAnimation["Time1"] = 0.0; - cAnimation["Speed1"] = 1.0; - cAnimation["Loop1"] = true; + ComponentWrapper cAnimation = m_FirstPersonModel["Animation"]; + if (cAnimation["AnimationName1"] != "ShootRifle") { + cAnimation["AnimationName1"] = "ShootRifle"; + cAnimation["Weight1"] = 1.0; + cAnimation["Time1"] = 0.0; + cAnimation["Speed1"] = 1.0; + cAnimation["Loop1"] = true; + } } void AssaultWeaponBehaviour::playIdleAnimation() @@ -168,11 +236,11 @@ void AssaultWeaponBehaviour::playIdleAnimation() std::string animationToPlay = "Idle"; double speedToSet = 1.0; - ComponentWrapper cPlayer = m_Entity["Player"]; + ComponentWrapper cPlayer = m_Player["Player"]; glm::vec3 movementDirection = cPlayer["CurrentWishDirection"]; if (glm::length2(movementDirection) > 0) { animationToPlay = "Run"; - ComponentWrapper cPhysics = m_Entity["Physics"]; + ComponentWrapper cPhysics = m_Player["Physics"]; speedToSet = glm::length((glm::vec3)cPhysics["Velocity"]) / (float)cPlayer["MovementSpeed"]; } @@ -188,3 +256,85 @@ void AssaultWeaponBehaviour::playIdleAnimation() } } +void AssaultWeaponBehaviour::playReloadAnimation() +{ + // Play animation + ComponentWrapper cAnimation = m_FirstPersonModel["Animation"]; + cAnimation["AnimationName1"] = "ReloadSwitch"; + cAnimation["Weight1"] = 1.0; + cAnimation["Time1"] = 0.0; + cAnimation["Speed1"] = 0.5; + cAnimation["Loop1"] = true; + + // Hide weapon model and spawn the exploding version + EntityWrapper firstPersonWeaponModel = m_Player.FirstChildByName("WeaponModel"); + EntityWrapper reloadSpawner = m_Player.FirstChildByName("FirstPersonReloadSpawner"); + m_ReloadImpersonator = SpawnerSystem::Spawn(reloadSpawner, reloadSpawner); + firstPersonWeaponModel["Model"].Copy(m_ReloadImpersonator["Model"]); + firstPersonWeaponModel["Model"]["Visible"] = false; +} + +bool AssaultWeaponBehaviour::shoot(double damage) +{ + // Only do shooting clientside + if (!IsClient) { + return false; + } + + // Only handle shooting for the local player + if (m_Player != LocalPlayer) { + return false; + } + + // Make sure the player isn't shooting from the grave + if (!m_Player.Valid()) { + return false; + } + + // Screen center, based on current resolution! + Rectangle screenResolution = m_Renderer->GetViewportSize(); + glm::vec2 centerScreen = glm::vec2(screenResolution.Width / 2, screenResolution.Height / 2); + + // Pick middle of screen + PickData pickData = m_Renderer->Pick(centerScreen); + if (pickData.Entity == EntityID_Invalid) { + return false; + } + + EntityWrapper victim(m_World, pickData.Entity); + + // Don't let us shoot ourselves in the foot + if (victim == LocalPlayer) { + return false; + } + + // Only care about players being hit + if (!victim.HasComponent("Player")) { + victim = victim.FirstParentWithComponent("Player"); + } + if (!victim.Valid()) { + return false; + } + + // Check for friendly fire + if ((ComponentInfo::EnumType)victim["Team"]["Team"] == (ComponentInfo::EnumType)m_Player["Team"]["Team"]) { + return false; + } + + // Deal damage! + Events::PlayerDamage ePlayerDamage; + ePlayerDamage.Victim = victim; + ePlayerDamage.Damage = damage; + m_EventBroker->Publish(ePlayerDamage); + + return true; +} + +void AssaultWeaponBehaviour::showHitMarker() +{ + // Show hit marker + EntityWrapper hitMarkerSpawner = m_Player.FirstChildByName("HitMarkerSpawner"); + if (hitMarkerSpawner.Valid()) { + SpawnerSystem::Spawn(hitMarkerSpawner, hitMarkerSpawner); + } +} diff --git a/src/Game/Systems/Weapon/WeaponSystem.cpp b/src/Game/Systems/Weapon/WeaponSystem.cpp index bdd27ea9..34d5fd43 100644 --- a/src/Game/Systems/Weapon/WeaponSystem.cpp +++ b/src/Game/Systems/Weapon/WeaponSystem.cpp @@ -8,7 +8,6 @@ WeaponSystem::WeaponSystem(SystemParams params, IRenderer* renderer, OctreeReload(); + } + } + return true; } @@ -69,7 +76,7 @@ void WeaponSystem::selectWeapon(EntityWrapper player, ComponentInfo::EnumType sl if (slot == 1) { // TODO: if class... if (m_ActiveWeapons.count(player) == 0) { - m_ActiveWeapons.insert(std::make_pair(player, std::make_shared(m_SystemParams, m_CollisionOctree, player))); + m_ActiveWeapons.insert(std::make_pair(player, std::make_shared(m_SystemParams, m_Renderer, m_CollisionOctree, player))); } else { //m_ActiveWeapons.erase(player); } @@ -87,52 +94,3 @@ bool WeaponSystem::OnPlayerSpawned(Events::PlayerSpawned& e) // TODO: Select the active one specified by player component return true; } - -bool WeaponSystem::OnShoot(Events::Shoot& eShoot) -{ - if (!eShoot.Player.Valid()) { - return false; - } - - // Only run further picking code for the local player! - if (eShoot.Player != LocalPlayer) { - return false; - } - - // Screen center, based on current resolution! - // TODO: check if player has enough ammo and if weapon has a cooldown or not - Rectangle screenResolution = m_Renderer->GetViewportSize(); - glm::vec2 centerScreen = glm::vec2(screenResolution.Width / 2, screenResolution.Height / 2); - - // TODO: check if player has enough ammo and if weapon has a cooldown or not - - // Pick middle of screen - PickData pickData = m_Renderer->Pick(centerScreen); - if (pickData.Entity == EntityID_Invalid) { - return false; - } - - EntityWrapper player(m_World, pickData.Entity); - - // Only care about players being hit - if (!player.HasComponent("Player")) { - player = player.FirstParentWithComponent("Player"); - } - if (!player.Valid()) { - return false; - } - - // Check for friendly fire - EntityWrapper shooter = eShoot.Player; - if ((ComponentInfo::EnumType)player["Team"]["Team"] == (ComponentInfo::EnumType)shooter["Team"]["Team"]) { - return false; - } - - // TODO: Weapon damage calculations etc - Events::PlayerDamage ePlayerDamage; - ePlayerDamage.Player = player; - ePlayerDamage.Damage = 100; - m_EventBroker->Publish(ePlayerDamage); - - return true; -} \ No newline at end of file diff --git a/src/Tests/HealthSystemTest.cpp b/src/Tests/HealthSystemTest.cpp index 36608f8f..8bf16024 100644 --- a/src/Tests/HealthSystemTest.cpp +++ b/src/Tests/HealthSystemTest.cpp @@ -71,7 +71,7 @@ GameHealthSystemTest::GameHealthSystemTest() //damage player with 50 Events::PlayerDamage e; e.Damage = 50.0f; - e.Player = EntityWrapper(m_World, player.EntityID); + e.Victim = EntityWrapper(m_World, player.EntityID); m_EventBroker->Publish(e); //heal some other player with 40 From 1bb1a1445ee23982189736389ed6edd6cbf094ed Mon Sep 17 00:00:00 2001 From: Teejoon Date: Thu, 11 Feb 2016 22:51:39 +0100 Subject: [PATCH 24/26] Commit assets --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index 105b22fc..4d36fdce 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 105b22fc67b68993db43deec3250084ed625d893 +Subproject commit 4d36fdced7007a594a56b7371bb26861876889aa From 44a73ef88376cf22665e4189069aa5d484ae383d Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Thu, 11 Feb 2016 23:44:20 +0100 Subject: [PATCH 25/26] fixup! Merge remote-tracking branch 'origin/master' into WeaponSystem --- include/Game/Systems/DamageIndicatorSystem.h | 4 ++-- src/Game/Systems/DamageIndicatorSystem.cpp | 18 +++++++++++------- .../Systems/Weapon/AssaultWeaponBehaviour.cpp | 1 + src/Game/Systems/Weapon/WeaponSystem.cpp | 4 +--- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/include/Game/Systems/DamageIndicatorSystem.h b/include/Game/Systems/DamageIndicatorSystem.h index e70a69a9..053b196b 100644 --- a/include/Game/Systems/DamageIndicatorSystem.h +++ b/include/Game/Systems/DamageIndicatorSystem.h @@ -21,8 +21,8 @@ public: DamageIndicatorSystem(SystemParams params); private: - EventRelay m_DamageTakenFromPlayer; - bool OnPlayerDamageTaken(Events::PlayerDamage& e); + EventRelay m_EPlayerDamage; + bool OnPlayerDamage(Events::PlayerDamage& e); EventRelay m_ESetCamera; bool OnSetCamera(const Events::SetCamera& e); diff --git a/src/Game/Systems/DamageIndicatorSystem.cpp b/src/Game/Systems/DamageIndicatorSystem.cpp index 93385e48..a29309b5 100644 --- a/src/Game/Systems/DamageIndicatorSystem.cpp +++ b/src/Game/Systems/DamageIndicatorSystem.cpp @@ -3,7 +3,7 @@ DamageIndicatorSystem::DamageIndicatorSystem(SystemParams params) : System(params) { - EVENT_SUBSCRIBE_MEMBER(m_DamageTakenFromPlayer, &DamageIndicatorSystem::OnPlayerDamageTaken); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &DamageIndicatorSystem::OnPlayerDamage); //current camera EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &DamageIndicatorSystem::OnSetCamera); @@ -12,23 +12,27 @@ DamageIndicatorSystem::DamageIndicatorSystem(SystemParams params) auto entityFile = ResourceManager::Load("Schema/Entities/DamageIndicator.xml"); } -bool DamageIndicatorSystem::OnPlayerDamageTaken(Events::PlayerDamage& e) +bool DamageIndicatorSystem::OnPlayerDamage(Events::PlayerDamage& e) { - if (m_CurrentCamera == -1) { + if (m_CurrentCamera == EntityID_Invalid) { + return false; + } + + if (e.Victim != LocalPlayer) { return false; } //grab players direction - auto playerOrientation = glm::quat((glm::vec3)e.Player["Transform"]["Orientation"]); + auto playerOrientation = glm::quat((glm::vec3)e.Victim["Transform"]["Orientation"]); //get the position vectors, but ignore the y-height - auto enemyPosition = (glm::vec3) e.PlayerShooter["Transform"]["Position"]; - auto playerPosition = (glm::vec3) e.Player["Transform"]["Position"]; + auto enemyPosition = (glm::vec3)e.Inflictor["Transform"]["Position"]; + auto playerPosition = (glm::vec3)e.Victim["Transform"]["Position"]; enemyPosition.y = 0.0f; playerPosition.y = 0.0f; //calculate the enemy to player vector - auto enemyPlayerVector = glm::normalize((glm::vec3) playerPosition - enemyPosition); + auto enemyPlayerVector = glm::normalize(playerPosition - enemyPosition); //get angle from players current rotation, this angle is how much you rotate around the y-axis auto playerAngle = glm::angle(playerOrientation); diff --git a/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp b/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp index 724e1f2c..54c3a590 100644 --- a/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp +++ b/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp @@ -323,6 +323,7 @@ bool AssaultWeaponBehaviour::shoot(double damage) // Deal damage! Events::PlayerDamage ePlayerDamage; + ePlayerDamage.Inflictor = m_Player; ePlayerDamage.Victim = victim; ePlayerDamage.Damage = damage; m_EventBroker->Publish(ePlayerDamage); diff --git a/src/Game/Systems/Weapon/WeaponSystem.cpp b/src/Game/Systems/Weapon/WeaponSystem.cpp index 4a25b811..3a49ae90 100644 --- a/src/Game/Systems/Weapon/WeaponSystem.cpp +++ b/src/Game/Systems/Weapon/WeaponSystem.cpp @@ -93,6 +93,4 @@ bool WeaponSystem::OnPlayerSpawned(Events::PlayerSpawned& e) // Select primary weapon on player spawn // TODO: Select the active one specified by player component return true; -} - - ePlayerDamage.PlayerShooter = eShoot.Player; \ No newline at end of file +} \ No newline at end of file From b761439c843bb85ab189f9432b5ac1881f78683c Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Thu, 11 Feb 2016 23:45:30 +0100 Subject: [PATCH 26/26] Added config flag Debug.OutOfBodyExperience that allows you to spawn and view a player from a third person perspective, without the active camera being changed. --- include/Engine/Rendering/RenderSystem.h | 4 +++ resources/DefaultConfig.ini | 2 ++ src/Engine/Rendering/RenderSystem.cpp | 40 +++++++++++++++---------- src/Game/Systems/PlayerSpawnSystem.cpp | 3 +- tools/deploy.bat | 2 ++ 5 files changed, 34 insertions(+), 17 deletions(-) diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index d73d8680..7580d654 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -18,6 +18,7 @@ #include "../Core/EPlayerSpawned.h" #include "../Core/Octree.h" #include "../Collision/EntityAABB.h" +#include "../Core/ConfigFile.h" class RenderSystem : public ImpureSystem { @@ -48,6 +49,9 @@ private: void fillDirectionalLights(std::list>& jobs, World* world); void fillLight(std::list>& jobs); void fillSprites(std::list>& jobs, World* world); + + bool isEntityVisible(EntityWrapper& entity); + bool isChildOfACamera(EntityWrapper entity); bool isChildOfCurrentCamera(EntityWrapper entity); }; diff --git a/resources/DefaultConfig.ini b/resources/DefaultConfig.ini index 12ec06c8..6911632f 100644 --- a/resources/DefaultConfig.ini +++ b/resources/DefaultConfig.ini @@ -4,6 +4,8 @@ LoadMap= ; if true -> Pool allocation is not used when calling Allocate/Free, just use regular dynamic allocation. ; if false -> Use pool allocation. DisableMemoryPool=false +EditorEnabled=false +OutOfBodyExperience=false [Editor] CameraSpeed=3 diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index 6600bc4f..7beb85db 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -47,16 +47,8 @@ void RenderSystem::fillSprites(std::list>& jobs, Worl 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))) { + if (!isEntityVisible(entity)) { continue; } @@ -85,6 +77,23 @@ void RenderSystem::fillSprites(std::list>& jobs, Worl } } +bool RenderSystem::isEntityVisible(EntityWrapper& entity) +{ + + // Only render children of a camera if that camera is currently active + if (isChildOfACamera(entity) && !isChildOfCurrentCamera(entity)) { + return false; + } + + // Hide things parented to local player if they have the HiddenFromLocalPlayer component + bool outOfBodyExperience = ResourceManager::Load("Config.ini")->Get("Debug.OutOfBodyExperience", false); + if (entity.HasComponent("HiddenForLocalPlayer") && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) && !outOfBodyExperience) { + return false; + } + + return true; +} + bool RenderSystem::isChildOfACamera(EntityWrapper entity) { return entity.FirstParentWithComponent("Camera").Valid(); @@ -112,13 +121,7 @@ void RenderSystem::fillModels(RenderScene::Queues &Jobs) continue; } - // 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.FirstParentWithComponent("HiddenForLocalPlayer").Valid()) && (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer))) { + if (!isEntityVisible(entity)) { continue; } @@ -299,6 +302,11 @@ void RenderSystem::fillText(std::list>& jobs, World* continue; } + EntityWrapper entity(world, textComponent.EntityID); + if (!isEntityVisible(entity)) { + continue; + } + Font* font; try { font = ResourceManager::Load(resource); diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index 507ed0f5..444fc08f 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -88,7 +88,8 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e) // Set the camera to the correct entity EntityWrapper cameraEntity = e.Player.FirstChildByName("Camera"); - if (cameraEntity.Valid()) { + bool outOfBodyExperience = ResourceManager::Load("Config.ini")->Get("Debug.OutOfBodyExperience", false); + if (cameraEntity.Valid() && !outOfBodyExperience) { Events::SetCamera e; e.CameraEntity = cameraEntity; m_EventBroker->Publish(e); diff --git a/tools/deploy.bat b/tools/deploy.bat index 29dc9e62..cd7a44bc 100755 --- a/tools/deploy.bat +++ b/tools/deploy.bat @@ -22,7 +22,9 @@ MKLINK "%DeployLocation%\Schema\" "resources\Schema" /J RMDIR /S /Q "%DeployLocation%\Shaders" MKLINK "%DeployLocation%\Shaders\" "resources\Shaders" /J :: Configuration files +DEL "%DeployLocation%\DefaultConfig.ini" MKLINK "%DeployLocation%\DefaultConfig.ini" "resources\DefaultConfig.ini" /H +DEL "%DeployLocation%\DefaultInput.ini" MKLINK "%DeployLocation%\DefaultInput.ini" "resources\DefaultInput.ini" /H :: Platform specific binaries