From 7ba0e4ea9d8b2e5319feaad3a8a977cba92c3f90 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Fri, 4 Mar 2016 08:35:02 +0100 Subject: [PATCH] Run, Strafe and jump animations now playing --- .../Editor/EditorCameraInputController.h | 4 +- .../Engine/Input/FirstPersonInputController.h | 96 ++++++++++++- include/Engine/Rendering/BlendTree.h | 1 + .../Engine/Rendering/EAutoAnimationBlend.h | 2 + resources/Schema/Entities/Player.xml | 13 +- src/Engine/Editor/EditorSystem.cpp | 2 +- src/Engine/Rendering/AnimationSystem.cpp | 2 +- src/Engine/Rendering/BlendTree.cpp | 16 +++ src/Game/Systems/PlayerDeathSystem.cpp | 4 - src/Game/Systems/PlayerMovementSystem.cpp | 136 +++++++++++++++++- .../Systems/Weapon/AssaultWeaponBehaviour.cpp | 2 +- 11 files changed, 253 insertions(+), 25 deletions(-) diff --git a/include/Engine/Editor/EditorCameraInputController.h b/include/Engine/Editor/EditorCameraInputController.h index 6cb31d99..257e3424 100644 --- a/include/Engine/Editor/EditorCameraInputController.h +++ b/include/Engine/Editor/EditorCameraInputController.h @@ -12,8 +12,8 @@ template class EditorCameraInputController : public FirstPersonInputController { public: - EditorCameraInputController(EventBroker* eventBroker, unsigned int playerID) - : FirstPersonInputController(eventBroker, playerID) + EditorCameraInputController(EventBroker* eventBroker, unsigned int playerID, EntityWrapper playerEntity) + : FirstPersonInputController(eventBroker, playerID, playerEntity) { EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorCameraInputController::OnMousePress); EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &EditorCameraInputController::OnMouseRelease); diff --git a/include/Engine/Input/FirstPersonInputController.h b/include/Engine/Input/FirstPersonInputController.h index ed9469bd..2c7013e4 100644 --- a/include/Engine/Input/FirstPersonInputController.h +++ b/include/Engine/Input/FirstPersonInputController.h @@ -6,12 +6,13 @@ #include "../Core/ELockMouse.h" #include "../Game/Events/EDashAbility.h" #include "InputHandler.h" +#include "Rendering/EAutoAnimationBlend.h" template class FirstPersonInputController : public InputController { public: - FirstPersonInputController(EventBroker* eventBroker, int playerID); + FirstPersonInputController(EventBroker* eventBroker, int playerID, EntityWrapper playerEntity); virtual const glm::vec3 Movement() const { return m_Movement; } virtual const glm::vec3 Rotation() const { return m_Rotation; } @@ -34,6 +35,8 @@ public: protected: const int m_PlayerID; + EntityWrapper m_PlayerEntity; + bool m_MouseLocked = false; glm::vec3 m_Rotation; glm::vec3 m_Movement; @@ -65,9 +68,10 @@ protected: }; template -FirstPersonInputController::FirstPersonInputController(EventBroker* eventBroker, int playerID) +FirstPersonInputController::FirstPersonInputController(EventBroker* eventBroker, int playerID, EntityWrapper playerEntity) : InputController(eventBroker) , m_PlayerID(playerID) + , m_PlayerEntity(playerEntity) { EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse); EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse); @@ -118,13 +122,75 @@ bool FirstPersonInputController::OnCommand(const Events::InputComm if (e.Command == "Forward") { float val = glm::clamp(e.Value, -1.f, 1.f); m_Movement.z = -val; + + if (m_PlayerEntity.Valid()) { + EntityWrapper playerModel = m_PlayerEntity.FirstChildByName("PlayerModel"); + if (playerModel.Valid()) { + if (val > 0) { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.1; + aeb.NodeName = "Run"; + aeb.RootNode = playerModel; + aeb.Start = true; + m_EventBroker->Publish(aeb); + } else if (val < 0) { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.1; + aeb.NodeName = "Run"; + aeb.RootNode = playerModel; + aeb.Start = true; + aeb.Reverse = true; + m_EventBroker->Publish(aeb); + } else { + + } + } + } } if (e.Command == "Right") { float val = glm::clamp(e.Value, -1.f, 1.f); m_Movement.x = val; + + if (m_PlayerEntity.Valid()) { + EntityWrapper playerModel = m_PlayerEntity.FirstChildByName("PlayerModel"); + + if (playerModel.Valid()) { + if (val > 0) { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.1; + aeb.NodeName = "Right"; + aeb.RootNode = playerModel; + aeb.Start = true; + m_EventBroker->Publish(aeb); + } else if (val < 0) { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.1; + aeb.NodeName = "Left"; + aeb.RootNode = playerModel; + aeb.Start = true; + m_EventBroker->Publish(aeb); + } else { + + + } + } + } + } if (glm::length2(m_Movement) > 0) { m_Movement = glm::normalize(m_Movement); + } else { + if (m_PlayerEntity.Valid()) { + EntityWrapper playerModel = m_PlayerEntity.FirstChildByName("PlayerModel"); + + if (playerModel.Valid()) { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.1; + aeb.NodeName = "Idle"; + aeb.RootNode = playerModel; + m_EventBroker->Publish(aeb); + } + } } } @@ -159,6 +225,32 @@ bool FirstPersonInputController::OnCommand(const Events::InputComm if (e.Command == "Crouch") { m_Crouching = e.Value > 0; + + if (m_PlayerEntity.Valid()) { + EntityWrapper playerModel = m_PlayerEntity.FirstChildByName("PlayerModel"); + if (playerModel.Valid()) { + if (e.Value == 0.f) { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.3; + aeb.NodeName = "StandMovement"; + aeb.RootNode = playerModel; + aeb.Start = true; + aeb.Restart = true; + aeb.SingleLevelBlend = true; + m_EventBroker->Publish(aeb); + } else if(e.Value == 1.0f) { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.3; + aeb.NodeName = "CrouchMovement"; + aeb.RootNode = playerModel; + aeb.Start = true; + aeb.Restart = true; + aeb.SingleLevelBlend = true; + m_EventBroker->Publish(aeb); + } + } + } + } if (e.Command == "SpecialAbility") { diff --git a/include/Engine/Rendering/BlendTree.h b/include/Engine/Rendering/BlendTree.h index aa06f1e6..02f4a348 100644 --- a/include/Engine/Rendering/BlendTree.h +++ b/include/Engine/Rendering/BlendTree.h @@ -62,6 +62,7 @@ public: double progress; bool Start; bool SingleBlend; + double Weight; std::unordered_map StartWeights; }; diff --git a/include/Engine/Rendering/EAutoAnimationBlend.h b/include/Engine/Rendering/EAutoAnimationBlend.h index ebd29848..29d3d612 100644 --- a/include/Engine/Rendering/EAutoAnimationBlend.h +++ b/include/Engine/Rendering/EAutoAnimationBlend.h @@ -19,6 +19,8 @@ struct AutoAnimationBlend : Event bool Restart = false; bool SingleLevelBlend = false; + double Weight = -1.0; + EntityWrapper AnimationEntity = EntityWrapper::Invalid; }; diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index d34dba32..4ff512ac 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -631,7 +631,6 @@ Models/Characters/Assault/AssaultBlue.mesh - false @@ -719,12 +718,12 @@ ReloadSwitchBlend - MovementBlend + FinalMovementBlend - + StandCrouchBlend @@ -987,7 +986,7 @@ DashForwardF - 1 + 2 false @@ -999,7 +998,7 @@ DashBackwardF - 1 + 2 false @@ -1023,7 +1022,7 @@ DashLeftF - 1 + 3 false @@ -1035,7 +1034,7 @@ DashRightF - 1 + 3 false diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 62ddba88..f9cdde0b 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -19,7 +19,7 @@ EditorSystem::EditorSystem(SystemParams params, IRenderer* renderer, RenderFrame m_ActualCamera = m_EditorCamera; m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Transform"); m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Camera"); - m_EditorCameraInputController = new EditorCameraInputController(m_EventBroker, -1); + m_EditorCameraInputController = new EditorCameraInputController(m_EventBroker, -1, EntityWrapper::Invalid); m_EditorGUI = new EditorGUI(m_World, m_EventBroker); m_EditorGUI->SetEntitySelectedCallback(std::bind(&EditorSystem::OnEntitySelected, this, std::placeholders::_1)); diff --git a/src/Engine/Rendering/AnimationSystem.cpp b/src/Engine/Rendering/AnimationSystem.cpp index 5bac27f9..005778e7 100644 --- a/src/Engine/Rendering/AnimationSystem.cpp +++ b/src/Engine/Rendering/AnimationSystem.cpp @@ -196,7 +196,7 @@ bool AnimationSystem::OnAutoAnimationBlend(Events::AutoAnimationBlend& e) abj.BlendInfo.progress = 0.0; abj.BlendInfo.Start = e.Start; abj.BlendInfo.SingleBlend = e.SingleLevelBlend; - + abj.BlendInfo.Weight = e.Weight; EntityWrapper nodeEntity = subTreeRoot.FirstChildByName(e.NodeName); // more than one if (nodeEntity.Valid()) { diff --git a/src/Engine/Rendering/BlendTree.cpp b/src/Engine/Rendering/BlendTree.cpp index 9b6679ea..29bbe7e6 100644 --- a/src/Engine/Rendering/BlendTree.cpp +++ b/src/Engine/Rendering/BlendTree.cpp @@ -207,6 +207,22 @@ BlendTree::AutoBlendInfo BlendTree::AutoBlendStep(AutoBlendInfo blendInfo) { std::vector goalNodes = FindNodesByName(blendInfo.NodeName); + if(blendInfo.Weight >= 0 && blendInfo.Weight <= 1.0) { + for (auto it = goalNodes.begin(); it != goalNodes.end(); it++) { + EntityWrapper entity = (*it)->Entity; + + if (entity.Valid()) { + if (entity.HasComponent("Blend")) { + (double&)entity["Blend"]["Weight"] = blendInfo.Weight; + } + } + } + + return blendInfo; + } + + + if (blendInfo.Start) { for (auto it = goalNodes.begin(); it != goalNodes.end(); it++) { EntityWrapper entity = (*it)->Entity; diff --git a/src/Game/Systems/PlayerDeathSystem.cpp b/src/Game/Systems/PlayerDeathSystem.cpp index cbf0927f..b9a42ffc 100644 --- a/src/Game/Systems/PlayerDeathSystem.cpp +++ b/src/Game/Systems/PlayerDeathSystem.cpp @@ -45,10 +45,6 @@ void PlayerDeathSystem::createDeathEffect(EntityWrapper player) //copy the data from player to explosioneffectmodel playerEntityModel.Copy(deathEffectEW["Model"]); playerEntityAnimation.Copy(deathEffectEW["Animation"]); - //freeze the animation - 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"]; diff --git a/src/Game/Systems/PlayerMovementSystem.cpp b/src/Game/Systems/PlayerMovementSystem.cpp index d67e77bd..8fddbe96 100644 --- a/src/Game/Systems/PlayerMovementSystem.cpp +++ b/src/Game/Systems/PlayerMovementSystem.cpp @@ -42,11 +42,25 @@ void PlayerMovementSystem::updateMovementControllers(double dt) cameraOrientation.x = glm::clamp(cameraOrientation.x, -glm::half_pi(), glm::half_pi()); // Set third person model aim pitch EntityWrapper playerModel = player.FirstChildByName("PlayerModel"); + + //Third-person aim if (playerModel.Valid()) { - //ComponentWrapper cAnimationOffset = playerModel["AnimationOffset"]; - //float pitch = cameraOrientation.x + 0.2f; - //double time = (pitch + glm::half_pi()) / glm::pi(); - //cAnimationOffset["Time"] = time; + EntityWrapper aimPrimaryEntity = playerModel.FirstChildByName("AimPrimary"); + if(aimPrimaryEntity.Valid()){ + if(aimPrimaryEntity.HasComponent("Animation")) { + float pitch = cameraOrientation.x + 0.2f; + double time = (pitch + glm::half_pi()) / glm::pi(); + (double&)aimPrimaryEntity["Animation"]["Time"] = time; + } + } + EntityWrapper aimSecondaryEntity = playerModel.FirstChildByName("AimSecondary"); + if (aimSecondaryEntity.Valid()) { + if (aimSecondaryEntity.HasComponent("Animation")) { + float pitch = cameraOrientation.x + 0.2f; + double time = (pitch + glm::half_pi()) / glm::pi(); + (double&)aimSecondaryEntity["Animation"]["Time"] = time; + } + } } } @@ -140,10 +154,64 @@ void PlayerMovementSystem::updateMovementControllers(double dt) if (isOnGround) { (bool)cPhysics["IsOnGround"] = false; velocity.y = player["Player"]["JumpSpeed"]; + + + if (player.Valid()) { + EntityWrapper playerModel = player.FirstChildByName("PlayerModel"); + if (playerModel.Valid()) { + { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.15; + aeb.NodeName = "Jump"; + aeb.RootNode = playerModel; + aeb.Start = true; + aeb.Restart = true; + m_EventBroker->Publish(aeb); + } + { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.25; + aeb.NodeName = "StandCrouchBlend"; + aeb.RootNode = playerModel; + aeb.Start = true; + aeb.Restart = false; + aeb.AnimationEntity = playerModel.FirstChildByName("Jump"); + m_EventBroker->Publish(aeb); + } + } + } + + } else if (player.HasComponent("DoubleJump") && !controller->DoubleJumping()) { //Enter here if player can double jump and is doing so. (bool)cPhysics["IsOnGround"] = false; velocity.y = player["DoubleJump"]["DoubleJumpSpeed"]; + + if (player.Valid()) { + EntityWrapper playerModel = player.FirstChildByName("PlayerModel"); + if (playerModel.Valid()) { + { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.15; + aeb.NodeName = "Jump"; + aeb.RootNode = playerModel; + aeb.Start = true; + aeb.Restart = true; + m_EventBroker->Publish(aeb); + } + { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.25; + aeb.NodeName = "StandCrouchBlend"; + aeb.RootNode = playerModel; + aeb.Start = true; + aeb.Restart = false; + aeb.AnimationEntity = playerModel.FirstChildByName("Jump"); + m_EventBroker->Publish(aeb); + } + } + } + // If IsServer and network is off this will not work if (IsClient) { //put a hexagon at the players feet @@ -234,7 +302,7 @@ void PlayerMovementSystem::playerStep(double dt) bool PlayerMovementSystem::OnPlayerSpawned(Events::PlayerSpawned& e) { // When a player spawns, create an input controller for them - m_PlayerInputControllers[e.Player] = new FirstPersonInputController(m_EventBroker, e.PlayerID); + m_PlayerInputControllers[e.Player] = new FirstPersonInputController(m_EventBroker, e.PlayerID, e.Player); if (e.PlayerID == -1) { // Keep track of the local player m_LocalPlayer = e.Player; @@ -267,18 +335,72 @@ void PlayerMovementSystem::spawnHexagon(EntityWrapper target) bool PlayerMovementSystem::OnDashAbility(Events::DashAbility & e) { EntityWrapper player(m_World, e.Player); - if (!player.Valid() || !IsClient || player.ID == LocalPlayer.ID) { + if (!player.Valid() || !IsClient){// || player.ID == LocalPlayer.ID) { return false; } auto entityFile = ResourceManager::Load("Schema/Entities/DashEffect.xml"); EntityWrapper dashEffect = entityFile->MergeInto(m_World); - auto playerModel = player.FirstChildByName("PlayerModel"); + EntityWrapper playerModel = player.FirstChildByName("PlayerModel"); + +/* auto playerEntityModel = playerModel["Model"]; + + + if (player.HasComponent("Physics")) { + glm::vec3 velocity = (glm::vec3)player["Physics"]["Velocity"]; + + glm::vec2 direction = glm::vec2(velocity.x, velocity.z); + + std::string DashName = ""; + if (glm::abs(direction.x) > glm::abs(direction.y)) { + if(glm::sign(direction.x) > 0) { + DashName = "DashRight"; + } else { + DashName = "DashLeft"; + } + } else { + if (glm::sign(direction.y) > 0) { + DashName = "DashForward"; + } else { + DashName = "DashBackward"; + } + } + + { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.1; + aeb.NodeName = DashName; + aeb.RootNode = playerModel; + aeb.Restart = true; + aeb.Start = true; + m_EventBroker->Publish(aeb); + } + { + Events::AutoAnimationBlend aeb; + aeb.Duration = 0.3; + aeb.NodeName = "StandCrouchBlend"; + aeb.RootNode = playerModel; + aeb.Delay = 0.3; + aeb.Start = true; + aeb.Restart = false; + aeb.AnimationEntity = playerModel.FirstChildByName(DashName); + m_EventBroker->Publish(aeb); + } + } + */ + +/* auto playerEntityAnimation = playerModel["Animation"]; + playerEntityModel.Copy(dashEffect["Model"]); playerEntityAnimation.Copy(dashEffect["Animation"]); dashEffect["ExplosionEffect"]["EndColor"] = (glm::vec4)playerEntityModel["Color"]; ((glm::vec4&)dashEffect["ExplosionEffect"]["EndColor"]).w = 0.f; +*/ + + + + return true; } diff --git a/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp b/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp index 3918e9b8..55f6bb56 100644 --- a/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp +++ b/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp @@ -103,7 +103,7 @@ void AssaultWeaponBehaviour::OnReload(ComponentWrapper cWeapon, WeaponInfo& wi) // Play animation EntityWrapper modelEntity = wi.FirstPersonEntity.Parent().Parent(); if (modelEntity.Valid()) { - EntityWrapper blendTree = modelEntity.FirstChildByName("AssaultWeaponBlendTree"); + EntityWrapper blendTree = modelEntity.FirstChildByName("BlendTreeAssaultWeapon"); EntityWrapper reloadBlend = blendTree.FirstChildByName("Reload"); Events::AutoAnimationBlend eFireBlend;