From 71b9b1023ac183d16d16f4f571bcbcd16ec815f2 Mon Sep 17 00:00:00 2001 From: Benualdo Date: Sun, 29 Sep 2024 15:06:27 +0200 Subject: [PATCH] Player can grab weapons on the ground --- Engine.xml | 14 +- README.md | 5 +- data/Meshes/Baseball/Bat.fbx | Bin 53040 -> 62988 bytes data/Prefabs/Bat.prefab | 30 +++- doc/img/SolutionPlatformName2.png | Bin 12397 -> 15232 bytes .../Character/Player/PlayerBehaviour.h | 1 + .../Character/Player/PlayerBehaviour.hpp | 73 ++++++++-- .../src/Behaviour/Item/Ball/BallBehaviour.hpp | 1 + .../game/src/Behaviour/Item/ItemBehaviour.cpp | 15 ++ .../game/src/Behaviour/Item/ItemBehaviour.h | 11 +- .../Behaviour/Item/Weapon/WeaponBehaviour.h | 17 +++ .../Behaviour/Item/Weapon/WeaponBehaviour.hpp | 57 ++++++++ projects/game/src/Game.cpp | 6 + projects/game/src/Game.h | 2 + projects/game/src/Game.vcxproj.vcxproj | 2 + .../game/src/Game.vcxproj.vcxproj.filters | 9 ++ projects/game/src/Game_consts.h | 3 +- src/core/File/Buffer.inl | 3 + src/core/IInput.h | 4 +- src/core/Math/Math.cpp | 4 + src/core/Math/Math.h | 27 ++-- src/core/Math/Math.inl | 60 ++++++++ src/core/Object/ObjectHandle.h | 1 + src/core/Object/ObjectHandle.hpp | 14 ++ src/core/core.vcxproj | 1 + src/core/core.vcxproj.filters | 3 + .../ImGui/Menu/Scene/ImGuiSceneMenu.hpp | 2 +- src/editor/ImGui/Window/ImGuiWindow.cpp | 137 ++++++++++++++++-- src/editor/ImGui/Window/Input/ImGuiInput.hpp | 2 +- .../Animation/AttachToNodeComponent.cpp | 69 ++++++--- .../Animation/AttachToNodeComponent.h | 19 ++- src/engine/Engine.vcxproj.filters | 1 + src/engine/IAttachToNodeComponent.h | 16 ++ src/engine/Input/win32/Input_win32.h | 4 +- src/engine/Input/win32/Input_win32.hpp | 4 +- src/engine/engine.vcxproj | 1 + src/renderer/Instance/Mesh/MeshInstance.hpp | 2 +- 37 files changed, 528 insertions(+), 92 deletions(-) create mode 100644 projects/game/src/Behaviour/Item/Weapon/WeaponBehaviour.h create mode 100644 projects/game/src/Behaviour/Item/Weapon/WeaponBehaviour.hpp create mode 100644 src/core/Math/Math.inl create mode 100644 src/engine/IAttachToNodeComponent.h diff --git a/Engine.xml b/Engine.xml index f604775f1..305a39307 100644 --- a/Engine.xml +++ b/Engine.xml @@ -1,20 +1,20 @@ - - - + + + - + - + - + - + diff --git a/README.md b/README.md index d8bc21828..f05c0321b 100644 --- a/README.md +++ b/README.md @@ -106,11 +106,12 @@ You will also need if you want to build the ARM64EC versions: ![Screenshot](doc/img/vsbuild.png) -You can change the Solution Platform in Visual Studio's command line to toggle between the DirectX12 and the Vulkan renderers. +Use the 'Configuration' combo to select the target and graphics API you want to use: + +![Screenshot](doc/img/SolutionPlatformName2.png) Also don't forget to set the *working directory* to **$(SolutionDir)**. -![Screenshot](doc/img/SolutionPlatformName2.png) ## SDKs diff --git a/data/Meshes/Baseball/Bat.fbx b/data/Meshes/Baseball/Bat.fbx index 1e93bcd102336a28582569f984cedfee4ac0b954..2a05964f98cba31d5889cc192fc791761ebeafde 100644 GIT binary patch delta 40008 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 VYEGd1_BzQHA}CxzPHlYf{{W@y6E^?= delta 33498 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 - + - + @@ -42,7 +42,7 @@ - + @@ -62,17 +62,35 @@ - + - + + + + + + + + + + + + + + + + + + + - + diff --git a/doc/img/SolutionPlatformName2.png b/doc/img/SolutionPlatformName2.png index 9e9d2654b5d816a23729a330139e72473ff8fad4..e56186c1b3b88a52bb8467bd3a9c4f6cb0b65447 100644 GIT binary patch literal 15232 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 literal 12397 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 G!2bZUUJkeb diff --git a/projects/game/src/Behaviour/Character/Player/PlayerBehaviour.h b/projects/game/src/Behaviour/Character/Player/PlayerBehaviour.h index 51a6747ca..cc472fb46 100644 --- a/projects/game/src/Behaviour/Character/Player/PlayerBehaviour.h +++ b/projects/game/src/Behaviour/Character/Player/PlayerBehaviour.h @@ -23,4 +23,5 @@ class PlayerBehaviour final : public CharacterBehaviour vg::core::u8 m_controllerIndex = 0; vg::core::float4 m_customColor = vg::core::float4(1, 1, 1, 1); vg::core::ObjectHandle m_UI; + ItemBehaviour * m_rightHandItem = nullptr; }; diff --git a/projects/game/src/Behaviour/Character/Player/PlayerBehaviour.hpp b/projects/game/src/Behaviour/Character/Player/PlayerBehaviour.hpp index 0dee9cbb8..2dab2c4b2 100644 --- a/projects/game/src/Behaviour/Character/Player/PlayerBehaviour.hpp +++ b/projects/game/src/Behaviour/Character/Player/PlayerBehaviour.hpp @@ -2,9 +2,11 @@ #include "PlayerBehaviour.h" #include "Game.h" #include "Behaviour/Item/Ball/BallBehaviour.h" +#include "Behaviour/Item/Weapon/WeaponBehaviour.h" #include "engine/ICharacterControllerComponent.h" #include "engine/IUITextComponent.h" #include "engine/IPhysicsBodyComponent.h" +#include "engine/IPhysicsShapeComponent.h" #include "engine/ISoundComponent.h" #include "editor/Editor_Consts.h" #include "core/GameObject/GameObject.h" @@ -80,7 +82,8 @@ void PlayerBehaviour::FixedUpdate(const Context & _context) if (_context.m_world->IsPlaying() && !_context.m_world->IsPaused()) // TODO: Use context intead? { IInput & input = Game::Input(); - IAnimationComponent * animationComponent = GetGameObject()->GetComponentT(); + IGameObject * playerGO = GetGameObject(); + IAnimationComponent * animationComponent = playerGO->GetComponentT(); switch (m_state) { @@ -108,7 +111,7 @@ void PlayerBehaviour::FixedUpdate(const Context & _context) float3 translation = float3(0, 0, 0); const float joyDeadZone = 0.15f; - float runAmount = input.GetRightTrigger(joyID); + float runAmount = input.GetJoyRightTrigger(joyID); if (runAmount > joyDeadZone) runAmount = lerp(0.0f, 1.0f, saturate(runAmount - joyDeadZone) / (1.0f - joyDeadZone)); else @@ -143,7 +146,7 @@ void PlayerBehaviour::FixedUpdate(const Context & _context) m_state = CharacterState::Idle; } - vg::engine::ICharacterControllerComponent * charaController = GetGameObject()->GetComponentT(); + vg::engine::ICharacterControllerComponent * charaController = playerGO->GetComponentT(); bool jump = false; if (input.IsJoyButtonJustPressed(joyID, JoyButton::A)) @@ -165,30 +168,80 @@ void PlayerBehaviour::FixedUpdate(const Context & _context) if (input.IsJoyButtonJustPressed(joyID, JoyButton::X)) { - // kick + const float3 playerPos = playerGO->GetGlobalMatrix()[3].xyz; + + const float pickupDist = 1.0f; + + // Kick close balls auto & balls = Game::get()->getBalls(); for (uint i = 0; i < balls.size(); ++i) { - auto & ball = balls[i]; + auto * ballBehaviour = balls[i]; + auto * ballGO = ballBehaviour->GetGameObject(); - float3 delta = ball->GetGameObject()->GetGlobalMatrix()[3].xyz - this->GetGameObject()->GetGlobalMatrix()[3].xyz; + float3 delta = ballGO->GetGlobalMatrix()[3].xyz - playerPos; float dist = length(delta); - if (dist < 1) + if (dist < pickupDist) { float3 dir = normalize(delta); - - if (auto * physicsBody = ball->GetGameObject()->GetComponentT()) + ballBehaviour->SetOwner(ballGO); + if (auto * physicsBody = ballGO->GetComponentT()) { //VG_INFO("[Player] Kick ball %u (dist = %.2f, dir = %.2f, %.2f, %.2f)", i, dist, dir.x, dir.y, dir.z); float kickStrength = lerp(250.0f, 400.0f, runAmount); physicsBody->AddImpulse(dir * kickStrength); // Play sound - if (auto * soundComponent = ball->GetGameObject()->GetComponentT()) + if (auto * soundComponent = ballGO->GetComponentT()) soundComponent->Play(0); } } } + + // Pick closest weapon + auto & weapons = Game::get()->getWeapons(); + float closestDist = pickupDist+1; + IGameObject * closestWeaponGO = nullptr; + WeaponBehaviour * closestWeaponBehaviour = nullptr; + for (uint i = 0; i < weapons.size(); ++i) + { + auto * weaponBehaviour = weapons[i]; + IGameObject * weaponGO = weaponBehaviour->GetGameObject(); + float3 delta = weaponGO->GetGlobalMatrix()[3].xyz - playerPos; + float dist = length(delta); + if (dist < closestDist && dist < pickupDist && !weaponBehaviour->CanPick()) + { + closestDist = dist; + closestWeaponBehaviour = weaponBehaviour; + closestWeaponGO = closestWeaponBehaviour->GetGameObject(); + } + } + + if (closestWeaponBehaviour) + { + closestWeaponBehaviour->SetOwner(playerGO); + m_rightHandItem = closestWeaponBehaviour; + + if (auto * physicsShapeComponent = closestWeaponGO->GetComponentT()) + physicsShapeComponent->SetComponentFlags(vg::core::ComponentFlags::Enabled, false); + + } + } + + if (input.GetJoyLeftTrigger(joyID) > joyDeadZone) + { + if (nullptr != m_rightHandItem) + { + // drop + m_rightHandItem->SetOwner(nullptr); + + m_rightHandItem->GetGameObject()->SetGlobalMatrix(this->GetGameObject()->GetGlobalMatrix()); + + if (auto * physicsShapeComponent = m_rightHandItem->GetGameObject()->GetComponentT()) + physicsShapeComponent->SetComponentFlags(vg::core::ComponentFlags::Enabled, true); + + m_rightHandItem = nullptr; + } } if (charaController) diff --git a/projects/game/src/Behaviour/Item/Ball/BallBehaviour.hpp b/projects/game/src/Behaviour/Item/Ball/BallBehaviour.hpp index 95a885b20..a9987ea4a 100644 --- a/projects/game/src/Behaviour/Item/Ball/BallBehaviour.hpp +++ b/projects/game/src/Behaviour/Item/Ball/BallBehaviour.hpp @@ -46,6 +46,7 @@ void BallBehaviour::OnCollisionEnter(vg::core::IGameObject * _other) if (player->isActive()) { m_lastOwnerCharacter = player; + SetOwner(player->GetGameObject()); GetGameObject()->SetColor(player->getCustomColor()); } } diff --git a/projects/game/src/Behaviour/Item/ItemBehaviour.cpp b/projects/game/src/Behaviour/Item/ItemBehaviour.cpp index fcababefe..9aafb7801 100644 --- a/projects/game/src/Behaviour/Item/ItemBehaviour.cpp +++ b/projects/game/src/Behaviour/Item/ItemBehaviour.cpp @@ -2,6 +2,7 @@ #include "ItemBehaviour.h" #include "Ball/BallBehaviour.hpp" +#include "Weapon/WeaponBehaviour.hpp" VG_REGISTER_ABSTRACT_CLASS(ItemBehaviour, "ItemBehaviour"); @@ -24,6 +25,8 @@ bool ItemBehaviour::registerProperties(IClassDesc & _desc) { super::registerProperties(_desc); + registerPropertyEx(ItemBehaviour, m_owner, "Owner", vg::core::PropertyFlags::NotSaved); + return true; } @@ -39,4 +42,16 @@ void ItemBehaviour::OnStop() { Game::get()->removeItem(m_itemType, this); super::OnStop(); +} + +//-------------------------------------------------------------------------------------- +void ItemBehaviour::SetOwner(vg::core::IGameObject * _object) +{ + m_owner.set(_object); +} + +//-------------------------------------------------------------------------------------- +bool ItemBehaviour::CanPick() const +{ + return nullptr != m_owner.getObject(); } \ No newline at end of file diff --git a/projects/game/src/Behaviour/Item/ItemBehaviour.h b/projects/game/src/Behaviour/Item/ItemBehaviour.h index 74bf70ec6..377543107 100644 --- a/projects/game/src/Behaviour/Item/ItemBehaviour.h +++ b/projects/game/src/Behaviour/Item/ItemBehaviour.h @@ -1,5 +1,6 @@ #pragma once #include "game_consts.h" +#include "core/Object/ObjectHandle.h" #include "core/Component/Behaviour/Behaviour.h" class ItemBehaviour : public vg::core::Behaviour @@ -10,9 +11,13 @@ class ItemBehaviour : public vg::core::Behaviour ItemBehaviour(const vg::core::string & _name, vg::core::IObject * _parent, ItemType _itemType); ~ItemBehaviour(); - void OnPlay() override; - void OnStop() override; + void OnPlay() override; + void OnStop() override; + + virtual void SetOwner(vg::core::IGameObject * _object); + virtual bool CanPick() const; private: - ItemType m_itemType; + ItemType m_itemType; + vg::core::ObjectHandle m_owner; }; diff --git a/projects/game/src/Behaviour/Item/Weapon/WeaponBehaviour.h b/projects/game/src/Behaviour/Item/Weapon/WeaponBehaviour.h new file mode 100644 index 000000000..492d2e7b0 --- /dev/null +++ b/projects/game/src/Behaviour/Item/Weapon/WeaponBehaviour.h @@ -0,0 +1,17 @@ +#pragma once +#include "Behaviour/Item/ItemBehaviour.h" + +class CharacterBehaviour; + +class WeaponBehaviour final : public ItemBehaviour +{ +public: + VG_CLASS_DECL(WeaponBehaviour, ItemBehaviour); + + WeaponBehaviour(const vg::core::string & _name, vg::core::IObject * _parent); + ~WeaponBehaviour(); + + void OnPlay() final override; + void Update(const Context & _context) override; + void SetOwner(vg::core::IGameObject * _object) final override; +}; diff --git a/projects/game/src/Behaviour/Item/Weapon/WeaponBehaviour.hpp b/projects/game/src/Behaviour/Item/Weapon/WeaponBehaviour.hpp new file mode 100644 index 000000000..295ad442a --- /dev/null +++ b/projects/game/src/Behaviour/Item/Weapon/WeaponBehaviour.hpp @@ -0,0 +1,57 @@ +#include "WeaponBehaviour.h" +#include "editor/Editor_Consts.h" +#include "Game.h" +#include "Behaviour/Character/Player/PlayerBehaviour.h" +#include "engine/IAttachToNodeComponent.h" + +using namespace vg::core; +using namespace vg::engine; + +VG_REGISTER_COMPONENT_CLASS(WeaponBehaviour, "Weapon", "Game", "A weapon the player can pick", vg::editor::style::icon::Script, 0); + +//-------------------------------------------------------------------------------------- +WeaponBehaviour::WeaponBehaviour(const string & _name, IObject * _parent) : + super(_name, _parent, ItemType::Weapon) +{ + +} + +//-------------------------------------------------------------------------------------- +WeaponBehaviour::~WeaponBehaviour() +{ + +} + +//-------------------------------------------------------------------------------------- +bool WeaponBehaviour::registerProperties(IClassDesc & _desc) +{ + super::registerProperties(_desc); + + return true; +} + +//-------------------------------------------------------------------------------------- +void WeaponBehaviour::OnPlay() +{ + super::OnPlay(); +} + +//-------------------------------------------------------------------------------------- +void WeaponBehaviour::Update(const Context & _context) +{ + +} + +//-------------------------------------------------------------------------------------- +void WeaponBehaviour::SetOwner(vg::core::IGameObject * _object) +{ + super::SetOwner(_object); + + if (auto * attachToNode = GetGameObject()->GetComponentT()) + { + attachToNode->SetUseTarget(true); + attachToNode->SetTarget(_object); + } +} + + diff --git a/projects/game/src/Game.cpp b/projects/game/src/Game.cpp index 41d3da009..e719d17a7 100644 --- a/projects/game/src/Game.cpp +++ b/projects/game/src/Game.cpp @@ -160,4 +160,10 @@ void Game::removeItem(ItemType _type, ItemBehaviour * _item) const vg::core::vector & Game::getBalls() const { return reinterpret_cast &>(m_items[vg::core::asInteger(ItemType::Ball)]); +} + +//-------------------------------------------------------------------------------------- +const vg::core::vector & Game::getWeapons() const +{ + return reinterpret_cast &>(m_items[vg::core::asInteger(ItemType::Weapon)]); } \ No newline at end of file diff --git a/projects/game/src/Game.h b/projects/game/src/Game.h index 07c244862..085194fea 100644 --- a/projects/game/src/Game.h +++ b/projects/game/src/Game.h @@ -20,6 +20,7 @@ class EnemyBehaviour; class ItemBehaviour; class BallBehaviour; +class WeaponBehaviour; class Game : public vg::IGame, public vg::core::Singleton { @@ -52,6 +53,7 @@ class Game : public vg::IGame, public vg::core::Singleton const vg::core::vector & getItem (ItemType _type) const { return m_items[vg::core::asInteger(_type)]; } const vg::core::vector & getBalls () const; + const vg::core::vector & getWeapons () const; private: static vg::engine::IEngine * s_engine; diff --git a/projects/game/src/Game.vcxproj.vcxproj b/projects/game/src/Game.vcxproj.vcxproj index 5e1315fbc..1c3709dba 100644 --- a/projects/game/src/Game.vcxproj.vcxproj +++ b/projects/game/src/Game.vcxproj.vcxproj @@ -52,6 +52,8 @@ + + diff --git a/projects/game/src/Game.vcxproj.vcxproj.filters b/projects/game/src/Game.vcxproj.vcxproj.filters index 06d0c0de7..f1dff8753 100644 --- a/projects/game/src/Game.vcxproj.vcxproj.filters +++ b/projects/game/src/Game.vcxproj.vcxproj.filters @@ -50,6 +50,12 @@ Behaviour\Item\Ball + + Behaviour\Item\Weapon + + + Behaviour\Item\Weapon + @@ -76,6 +82,9 @@ {fb89c9e6-7259-4e92-b4b9-cc07c445a601} + + {1301a258-7b69-47a0-9e4a-1cdf0b98dd4a} + diff --git a/projects/game/src/Game_consts.h b/projects/game/src/Game_consts.h index 92eb80fe1..79ed9a7ce 100644 --- a/projects/game/src/Game_consts.h +++ b/projects/game/src/Game_consts.h @@ -16,5 +16,6 @@ vg_enum(CharacterState, vg::core::u8, ); vg_enum(ItemType, vg::core::u8, - Ball = 0 + Ball = 0, + Weapon ); \ No newline at end of file diff --git a/src/core/File/Buffer.inl b/src/core/File/Buffer.inl index 6dd80f4d9..396cdcd69 100644 --- a/src/core/File/Buffer.inl +++ b/src/core/File/Buffer.inl @@ -205,6 +205,9 @@ namespace vg::core::io //-------------------------------------------------------------------------------------- inline bool Buffer::restore(void * _data, core::size_t _size, bool & _modified) { + if (_size == 0) + return true; + if (m_read < m_data.size()) { if (memcmp(_data, &m_data[m_read], _size)) diff --git a/src/core/IInput.h b/src/core/IInput.h index 99b05dbff..416de5ade 100644 --- a/src/core/IInput.h +++ b/src/core/IInput.h @@ -54,8 +54,8 @@ namespace vg::core virtual core::uint GetJoyCount () const = 0; virtual core::float2 GetJoyLeftStickDir (JoyID _id) const = 0; virtual core::float2 GetJoyRightStickDir (JoyID _id) const = 0; - virtual float GetLeftTrigger (core::JoyID _id) const = 0; - virtual float GetRightTrigger (core::JoyID _id) const = 0; + virtual float GetJoyLeftTrigger (core::JoyID _id) const = 0; + virtual float GetJoyRightTrigger (core::JoyID _id) const = 0; virtual bool IsJoyButtonPressed (JoyID _id, JoyButton _button) const = 0; virtual bool IsJoyButtonJustPressed (JoyID _id, JoyButton _button) const = 0; virtual bool IsJoyButtonJustReleased (JoyID _id, JoyButton _button) const = 0; diff --git a/src/core/Math/Math.cpp b/src/core/Math/Math.cpp index 489e763b5..2b3947101 100644 --- a/src/core/Math/Math.cpp +++ b/src/core/Math/Math.cpp @@ -1,6 +1,10 @@ #include "core/Precomp.h" #include "Math.h" +#if !VG_ENABLE_INLINE +#include "Math.inl" +#endif + namespace vg::core { //-------------------------------------------------------------------------------------- diff --git a/src/core/Math/Math.h b/src/core/Math/Math.h index cbc342f54..ba2f78ff5 100644 --- a/src/core/Math/Math.h +++ b/src/core/Math/Math.h @@ -35,22 +35,13 @@ namespace vg::core } //-------------------------------------------------------------------------------------- - inline float4x4 TRS(const float3 & _translation, const quaternion _rotation, const float3 _scale) - { - quaternion q = _rotation; - - float xx = q.x * q.x, xy = q.x * q.y, xz = q.x * q.z, xw = q.x * q.w; - float yy = q.y * q.y, yz = q.y * q.z, yw = q.y * q.w; - float zz = q.z * q.z, zw = q.z * q.w; - float sx = 2.0f * _scale.x, sy = 2.0f * _scale.y, sz = 2.0f * _scale.z; + VG_INLINE void Float4x4ToTRS(const float4x4 & _mat44, float3 & _translation, float3 & _rotation, float3 & _scale); + + //-------------------------------------------------------------------------------------- + VG_INLINE float4x4 TRSToFloat4x4(const float3 & _translation, const float3 & _rotation, const float3 & _scale); - return float4x4( - sx * (-yy - zz + 0.5f), sy * (-zw + xy), sz * (+xz + yw), _translation.x, - sx * (+xy + zw), sy * (-xx - zz + 0.5f), sz * (-xw + yz), _translation.y, - sx * (-yw + xz), sy * (+xw + yz), sz * (-xx - yy + 0.5f), _translation.z, - 0, 0, 0, 1 - ); - } + //-------------------------------------------------------------------------------------- + VG_INLINE float4x4 TRSToFloat4x4(const float3 & _translation, const quaternion _rotation, const float3 _scale); //-------------------------------------------------------------------------------------- inline float4x4 getMatrixWithoutScale(const float4x4 & _matrix) @@ -234,4 +225,8 @@ namespace vg::core core::size_t hash = core::hash()(_this.x) ^ core::hash()(_this.y) ^ 0xff51afd7ed558ccd ^ core::hash()(_this.z) ^ 0xc4ceb9fe1a85ec53L ^ core::hash()(_this.w) ^ 0xed558cc4ceb9fe1L; return hash; } -} \ No newline at end of file +} + +#if VG_ENABLE_INLINE +#include "Math.inl" +#endif \ No newline at end of file diff --git a/src/core/Math/Math.inl b/src/core/Math/Math.inl new file mode 100644 index 000000000..0f5ecf8f1 --- /dev/null +++ b/src/core/Math/Math.inl @@ -0,0 +1,60 @@ +namespace vg::core +{ + //-------------------------------------------------------------------------------------- + // Extract translation, rotation (in degrees) and scale from a float4x4 matrix + //-------------------------------------------------------------------------------------- + VG_INLINE void Float4x4ToTRS(const float4x4 & _mat44, float3 & _translation, float3 & _rotation, float3 & _scale) + { + _scale.x = length(_mat44[0].xyz); + _scale.y = length(_mat44[1].xyz); + _scale.z = length(_mat44[2].xyz); + + float3 I = _mat44[0].xyz / _scale.x; + float3 J = _mat44[1].xyz / _scale.y; + float3 K = _mat44[2].xyz / _scale.z; + + _rotation = (float3)(180.0f / PI) * atan2(float3(J.z, -I.z, I.y), float3(K.z, sqrtf(J.z * J.z + K.z * K.z), I.x)); + + _translation = _mat44[3].xyz; + } + + //-------------------------------------------------------------------------------------- + VG_INLINE float4x4 TRSToFloat4x4(const float3 & _translation, const float3 & _rotation, const float3 & _scale) + { + const float3 rotationInRadians = (PI / 180.0f) * _rotation; + + float4x4 rot[3]; + rot[0] = float4x4::rotation_x(rotationInRadians.x); + rot[1] = float4x4::rotation_y(rotationInRadians.y); + rot[2] = float4x4::rotation_z(rotationInRadians.z); + + float4x4 mat = mul(rot[2], mul(rot[1], rot[0])); + + const float3 scale = select(abs(_scale) < FLT_EPSILON, (float3)0.001f * sign(_scale), _scale); + + mat[0] = mat[0] * scale.x; + mat[1] = mat[1] * scale.y; + mat[2] = mat[2] * scale.z; + mat[3] = float4(_translation.xyz, 1.0f); + + return mat; + } + + //-------------------------------------------------------------------------------------- + VG_INLINE float4x4 TRSToFloat4x4(const float3 & _translation, const quaternion _rotation, const float3 _scale) + { + quaternion q = _rotation; + + float xx = q.x * q.x, xy = q.x * q.y, xz = q.x * q.z, xw = q.x * q.w; + float yy = q.y * q.y, yz = q.y * q.z, yw = q.y * q.w; + float zz = q.z * q.z, zw = q.z * q.w; + float sx = 2.0f * _scale.x, sy = 2.0f * _scale.y, sz = 2.0f * _scale.z; + + return float4x4( + sx * (-yy - zz + 0.5f), sy * (-zw + xy), sz * (+xz + yw), _translation.x, + sx * (+xy + zw), sy * (-xx - zz + 0.5f), sz * (-xw + yz), _translation.y, + sx * (-yw + xz), sy * (+xw + yz), sz * (-xx - yy + 0.5f), _translation.z, + 0, 0, 0, 1 + ); + } +} \ No newline at end of file diff --git a/src/core/Object/ObjectHandle.h b/src/core/Object/ObjectHandle.h index 53bbedfce..06216e609 100644 --- a/src/core/Object/ObjectHandle.h +++ b/src/core/Object/ObjectHandle.h @@ -15,6 +15,7 @@ namespace vg::core UID getUID () const; const UID * getUIDPtr () const; + void set (core::IObject * _object); IObject * getObject () const; template T* get() const diff --git a/src/core/Object/ObjectHandle.hpp b/src/core/Object/ObjectHandle.hpp index b0b4cea04..2ac50d705 100644 --- a/src/core/Object/ObjectHandle.hpp +++ b/src/core/Object/ObjectHandle.hpp @@ -32,6 +32,20 @@ namespace vg::core return &m_uid; } + //-------------------------------------------------------------------------------------- + void ObjectHandle::set(core::IObject * _object) + { + if (_object) + { + VG_ASSERT(_object->GetUID(false)); + setUID(_object->GetUID()); + } + else + { + setUID(0x0); + } + } + //-------------------------------------------------------------------------------------- IObject * ObjectHandle::getObject() const { diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj index 2d4f87fd0..c6db50f04 100644 --- a/src/core/core.vcxproj +++ b/src/core/core.vcxproj @@ -203,6 +203,7 @@ + diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters index cc4ba203b..5c0168853 100644 --- a/src/core/core.vcxproj.filters +++ b/src/core/core.vcxproj.filters @@ -540,5 +540,8 @@ Misc\AABB + + Math + \ No newline at end of file diff --git a/src/editor/ImGui/Menu/Scene/ImGuiSceneMenu.hpp b/src/editor/ImGui/Menu/Scene/ImGuiSceneMenu.hpp index 93a708edf..ebaccbb49 100644 --- a/src/editor/ImGui/Menu/Scene/ImGuiSceneMenu.hpp +++ b/src/editor/ImGui/Menu/Scene/ImGuiSceneMenu.hpp @@ -58,7 +58,7 @@ namespace vg::editor if (ImGui::MenuItem("Save As")) { m_selected = SceneMenuOption::Save; - m_popup = fmt::sprintf("Save %s As ...", asString(m_sceneType)); + m_popup = fmt::sprintf("Save %s \"%s\" As ...", asString(m_sceneType), scene->GetName().c_str()); saveFileDialog = true; } diff --git a/src/editor/ImGui/Window/ImGuiWindow.cpp b/src/editor/ImGui/Window/ImGuiWindow.cpp index dc8da8c71..cdeb23ecd 100644 --- a/src/editor/ImGui/Window/ImGuiWindow.cpp +++ b/src/editor/ImGui/Window/ImGuiWindow.cpp @@ -2616,6 +2616,51 @@ namespace vg::editor return changed; } + void QuaternionToEuler(const quaternion & q, float & pitch, float & yaw, float & roll) + { + // Convert quaternion to Euler angles (pitch, yaw, roll) + float sinr_cosp = 2.0f * (q.w * q.x + q.y * q.z); + float cosr_cosp = 1.0f - 2.0f * (q.x * q.x + q.y * q.y); + roll = atan2(sinr_cosp, cosr_cosp); + + float sinp = 2.0f * (q.w * q.y - q.z * q.x); + if (fabs(sinp) >= 1) + pitch = copysign(PI / 2, sinp); // Use 90 degrees if out of range + else + pitch = asin(sinp); + + float siny_cosp = 2.0f * (q.w * q.z + q.x * q.y); + float cosy_cosp = 1.0f - 2.0f * (q.y * q.y + q.z * q.z); + yaw = atan2(siny_cosp, cosy_cosp); + } + + quaternion EulerToQuaternion(float pitch, float yaw, float roll) + { + float cy = cos(yaw * 0.5f); + float sy = sin(yaw * 0.5f); + float cr = cos(roll * 0.5f); + float sr = sin(roll * 0.5f); + float cp = cos(pitch * 0.5f); + float sp = sin(pitch * 0.5f); + + quaternion q; + q.w = cy * cr * cp + sy * sr * sp; + q.x = cy * sr * cp - sy * cr * sp; + q.y = cy * cr * sp + sy * sr * cp; + q.z = sy * cr * cp - cy * sr * sp; + + return q; + } + + float ClampEulerAngle(float angle) + { + if (angle > 180.0f) + return angle - 360.0f; + if (angle < -180.0f) + return angle + 360.0f; + return angle; + } + //-------------------------------------------------------------------------------------- bool ImGuiWindow::editFloat4x4(core::IObject * _object, const core::IProperty * _prop, PropertyContext & _propContext) { @@ -2636,6 +2681,25 @@ namespace vg::editor const string LabelK = flatten ? fmt::sprintf("%s.K", displayName) : "K"; const string LabelT = flatten ? fmt::sprintf("%s.T", displayName) : "T"; + //static bool useTRS = false; + // + //if (ImGui::BeginCombo("Mode", useTRS? "TRS" : "float4x4")) + //{ + // bool is_selected = useTRS; + // if (ImGui::Selectable("TRS", is_selected)) + // useTRS = true; + // if (is_selected) + // ImGui::SetItemDefaultFocus(); + // + // is_selected = !useTRS; + // if (ImGui::Selectable("float4x4", is_selected)) + // useTRS = false; + // if (is_selected) + // ImGui::SetItemDefaultFocus(); + // + // ImGui::EndCombo(); // End combo + //} + if (flatten || ImGui::TreeNode(getObjectLabel(displayName, _propContext.m_originalProp).c_str())) { bool edited = false; @@ -2644,26 +2708,67 @@ namespace vg::editor if (_propContext.m_readOnly) ImGui::BeginDisabled(); - edited |= ImGui::DragFloat4(getPropertyLabel("I").c_str(), (float *)&temp[0], getDragSpeedFloat(_prop), -style::range::maxFloat, style::range::maxFloat, g_editFloatFormat) && !_propContext.m_readOnly; - if (EditingState::Unknown == editingState) - editingState = undoRedoBeforeEdit(edited, _propContext, _object, _prop, (float *)&temp[0], pFloat, InteractionType::Continuous); - drawPropertyLabel(_propContext, LabelI.c_str(), "Represents the x-axis in the transformed space"); + //if (useTRS) + { + const string TLabel = flatten ? fmt::sprintf("%s.T", displayName) : "T"; + const string RLabel = flatten ? fmt::sprintf("%s.R", displayName) : "R"; + const string SLabel = flatten ? fmt::sprintf("%s.S", displayName) : "S"; + + float translation[3]; + float rotation[3]; + float scale[3]; + ImGuizmo::DecomposeMatrixToComponents((float *)&temp[0], (float *)&translation, (float *)&rotation, (float *)&scale); + + edited |= ImGui::DragFloat3(getPropertyLabel("T").c_str(), (float *)&translation, getDragSpeedFloat(_prop) * 90.0f/8.0f, -style::range::maxFloat, style::range::maxFloat, g_editFloatFormat) && !_propContext.m_readOnly; + if (EditingState::Unknown == editingState) + editingState = undoRedoBeforeEdit(edited, _propContext, _object, _prop, (float *)&temp[0], pFloat, InteractionType::Continuous); + drawPropertyLabel(_propContext, TLabel.c_str(), "Represents the translation part of the matrix"); + + float prevRot[3] = { rotation[0], rotation[1], rotation[2] }; + + edited |= ImGui::DragFloat3(getPropertyLabel("R").c_str(), (float *)&rotation, getDragSpeedFloat(_prop) * 90.0f / 8.0f, -style::range::maxFloat, style::range::maxFloat, g_editFloatFormat) && !_propContext.m_readOnly; + + if (EditingState::Unknown == editingState) + editingState = undoRedoBeforeEdit(edited, _propContext, _object, _prop, (float *)&temp[0], pFloat, InteractionType::Continuous); + drawPropertyLabel(_propContext, RLabel.c_str(), "Represents the rotation part of the matrix"); - edited |= ImGui::DragFloat4(getPropertyLabel("J").c_str(), (float *)&temp[4], getDragSpeedFloat(_prop), -style::range::maxFloat, style::range::maxFloat, g_editFloatFormat) && !_propContext.m_readOnly; - if (EditingState::Unknown == editingState) - editingState = undoRedoBeforeEdit(edited, _propContext, _object, _prop, (float *)&temp[0], pFloat, InteractionType::Continuous); - drawPropertyLabel(_propContext, LabelJ.c_str(), "Represents the y-axis in the transformed space"); + edited |= ImGui::DragFloat3(getPropertyLabel("S").c_str(), (float *)&scale, getDragSpeedFloat(_prop) * 90.0f / 8.0f, -style::range::maxFloat, style::range::maxFloat, g_editFloatFormat) && !_propContext.m_readOnly; + if (EditingState::Unknown == editingState) + editingState = undoRedoBeforeEdit(edited, _propContext, _object, _prop, (float *)&temp[0], pFloat, InteractionType::Continuous); + drawPropertyLabel(_propContext, SLabel.c_str(), "Represents the scale part of the matrix"); - edited |= ImGui::DragFloat4(getPropertyLabel("K").c_str(), (float *)&temp[8], getDragSpeedFloat(_prop), -style::range::maxFloat, style::range::maxFloat, g_editFloatFormat) && !_propContext.m_readOnly; - if (EditingState::Unknown == editingState) - editingState = undoRedoBeforeEdit(edited, _propContext, _object, _prop, (float *)&temp[0], pFloat, InteractionType::Continuous); - drawPropertyLabel(_propContext, LabelK.c_str(), "Represents the z-axis in the transformed space"); + if (edited) + ImGuizmo::RecomposeMatrixFromComponents((float *)&translation, (float *)&rotation, (float *)&scale, (float *)&temp[0]); + } + + ImGui::Spacing(); - edited |= ImGui::DragFloat4(getPropertyLabel("T").c_str(), (float *)&temp[12], getDragSpeedFloat(_prop), -style::range::maxFloat, style::range::maxFloat, g_editFloatFormat) && !_propContext.m_readOnly; - if (EditingState::Unknown == editingState) - editingState = undoRedoBeforeEdit(edited, _propContext, _object, _prop, (float *)&temp[0], pFloat, InteractionType::Continuous); - drawPropertyLabel(_propContext, LabelT.c_str(), "Represents the translation component"); + //else + if (ImGui::TreeNode(getObjectLabel("(float4x4) " + (string)displayName, _propContext.m_originalProp).c_str())) + { + edited |= ImGui::DragFloat4(getPropertyLabel("I").c_str(), (float *)&temp[0], getDragSpeedFloat(_prop), -style::range::maxFloat, style::range::maxFloat, g_editFloatFormat) && !_propContext.m_readOnly; + if (EditingState::Unknown == editingState) + editingState = undoRedoBeforeEdit(edited, _propContext, _object, _prop, (float *)&temp[0], pFloat, InteractionType::Continuous); + drawPropertyLabel(_propContext, LabelI.c_str(), "Represents the x-axis in the transformed space"); + + edited |= ImGui::DragFloat4(getPropertyLabel("J").c_str(), (float *)&temp[4], getDragSpeedFloat(_prop), -style::range::maxFloat, style::range::maxFloat, g_editFloatFormat) && !_propContext.m_readOnly; + if (EditingState::Unknown == editingState) + editingState = undoRedoBeforeEdit(edited, _propContext, _object, _prop, (float *)&temp[0], pFloat, InteractionType::Continuous); + drawPropertyLabel(_propContext, LabelJ.c_str(), "Represents the y-axis in the transformed space"); + + edited |= ImGui::DragFloat4(getPropertyLabel("K").c_str(), (float *)&temp[8], getDragSpeedFloat(_prop), -style::range::maxFloat, style::range::maxFloat, g_editFloatFormat) && !_propContext.m_readOnly; + if (EditingState::Unknown == editingState) + editingState = undoRedoBeforeEdit(edited, _propContext, _object, _prop, (float *)&temp[0], pFloat, InteractionType::Continuous); + drawPropertyLabel(_propContext, LabelK.c_str(), "Represents the z-axis in the transformed space"); + + edited |= ImGui::DragFloat4(getPropertyLabel("T").c_str(), (float *)&temp[12], getDragSpeedFloat(_prop), -style::range::maxFloat, style::range::maxFloat, g_editFloatFormat) && !_propContext.m_readOnly; + if (EditingState::Unknown == editingState) + editingState = undoRedoBeforeEdit(edited, _propContext, _object, _prop, (float *)&temp[0], pFloat, InteractionType::Continuous); + drawPropertyLabel(_propContext, LabelT.c_str(), "Represents the translation component"); + ImGui::TreePop(); + } + if (_propContext.m_readOnly) ImGui::EndDisabled(); diff --git a/src/editor/ImGui/Window/Input/ImGuiInput.hpp b/src/editor/ImGui/Window/Input/ImGuiInput.hpp index cc0df0be6..bd75c572f 100644 --- a/src/editor/ImGui/Window/Input/ImGuiInput.hpp +++ b/src/editor/ImGui/Window/Input/ImGuiInput.hpp @@ -143,7 +143,7 @@ namespace vg::editor const float2 & joyRightDir = input->GetJoyRightStickDir(id); Text("(%.2f, %.2f)", (float)joyRightDir.x, (float)joyRightDir.y); - Text("(%.2f, %.2f)", input->GetLeftTrigger(id), input->GetRightTrigger(id)); + Text("(%.2f, %.2f)", input->GetJoyLeftTrigger(id), input->GetJoyRightTrigger(id)); for (uint b = 0; b < enumCount(); ++b) { diff --git a/src/engine/Component/Animation/AttachToNodeComponent.cpp b/src/engine/Component/Animation/AttachToNodeComponent.cpp index 1c81fd236..ad490dffb 100644 --- a/src/engine/Component/Animation/AttachToNodeComponent.cpp +++ b/src/engine/Component/Animation/AttachToNodeComponent.cpp @@ -23,6 +23,10 @@ namespace vg::engine registerProperty(AttachToNodeComponent, m_boneName, "Bone"); setPropertyDescription(AttachToNodeComponent, m_boneName, "The bone to follow. Bone names can be found under \"MeshComponent>Skeleton>Nodes\"."); + //registerOptionalPropertyEx(AttachToNodeComponent, m_useTransform, m_transform, "Transform", PropertyFlags::Flatten); + registerPropertyEx(AttachToNodeComponent, m_transform, "Transform", PropertyFlags::Flatten); + setPropertyDescription(AttachToNodeComponent, m_transform, "An additional transform to apply after attaching to node."); + return true; } @@ -49,32 +53,40 @@ namespace vg::engine } //-------------------------------------------------------------------------------------- - void AttachToNodeComponent::OnEnable() + void AttachToNodeComponent::OnPlay() { - super::OnEnable(); + super::OnPlay(); updateCache(); } //-------------------------------------------------------------------------------------- - void AttachToNodeComponent::OnDisable() + void AttachToNodeComponent::OnStop() { - - super::OnDisable(); + clearCache(); + super::OnStop(); } //-------------------------------------------------------------------------------------- void AttachToNodeComponent::Update(const Context & _context) { - // TODO: this might be slow if the node is never found but need it because MeshInstance might not be immediately available - if (!m_skeleton) - updateCache(); - - if (m_skeleton) + if (_context.m_playing && !_context.m_paused) { - if (m_nodeIndex < (int)m_skeleton->GetNodeCount()) + // TODO: this might be slow if the node is never found but need it because MeshInstance might not be immediately available + if (!m_skeleton) + updateCache(); + + if (m_skeleton) { - float4x4 mWorld = transpose(m_skeleton->GetNodeWorldMatrix(m_nodeIndex)); - getGameObject()->SetLocalMatrix(mWorld); + if (m_nodeIndex < (int)m_skeleton->GetNodeCount()) + { + float4x4 mBone = transpose(m_skeleton->GetNodeWorldMatrix(m_nodeIndex)); + float4x4 mGlobal = mul(mBone, m_gameObject->GetGlobalMatrix()); + + //if (m_useTransform) + mGlobal = mul(m_transform, mGlobal); + + getGameObject()->SetGlobalMatrix(mGlobal); + } } } } @@ -88,6 +100,27 @@ namespace vg::engine updateCache(); } + //-------------------------------------------------------------------------------------- + void AttachToNodeComponent::SetUseTarget(bool _useTarget) + { + m_useTarget = _useTarget; + } + + //-------------------------------------------------------------------------------------- + void AttachToNodeComponent::SetTarget(core::IGameObject * _target) + { + m_target.setUID(_target ? _target->GetUID() : 0x0); + + if (!_target) + clearCache(); + } + + //-------------------------------------------------------------------------------------- + void AttachToNodeComponent::SetBoneName(const core::string & _boneName) + { + m_boneName = _boneName; + } + //-------------------------------------------------------------------------------------- bool AttachToNodeComponent::updateCache() { @@ -98,9 +131,9 @@ namespace vg::engine if (m_useTarget) { - if (const GameObject * go = m_target.get()) + if (gameObject = m_target.get()) { - if (const MeshComponent * mc = go->GetComponentT()) + if (const MeshComponent * mc = gameObject->GetComponentT()) { if (const renderer::IMeshInstance * mi = mc->getMeshInstance()) { @@ -112,9 +145,9 @@ namespace vg::engine } else { - if (const GameObject * go = getGameObject()) + if (gameObject = getGameObject()) { - if (const MeshComponent * mc = go->GetComponentInParentsT()) + if (const MeshComponent * mc = gameObject->GetComponentInParentsT()) { if (const renderer::IMeshInstance * mi = mc->getMeshInstance()) { @@ -127,6 +160,7 @@ namespace vg::engine if (nullptr != skeleton) { + m_gameObject = gameObject; m_skeleton = skeleton; m_nodeIndex = skeleton->FindNodeIndex(m_boneName); return true; @@ -139,6 +173,7 @@ namespace vg::engine void AttachToNodeComponent::clearCache() { m_skeleton = nullptr; + m_gameObject = nullptr; m_nodeIndex = -1; } } diff --git a/src/engine/Component/Animation/AttachToNodeComponent.h b/src/engine/Component/Animation/AttachToNodeComponent.h index 1edc6ca8d..8b1b7af3f 100644 --- a/src/engine/Component/Animation/AttachToNodeComponent.h +++ b/src/engine/Component/Animation/AttachToNodeComponent.h @@ -1,6 +1,6 @@ #pragma once -#include "core/Component/Component.h" +#include "engine/IAttachToNodeComponent.h" #include "core/Object/ObjectHandle.h" namespace vg::renderer @@ -13,20 +13,25 @@ namespace vg::engine { class MeshComponent; - class AttachToNodeComponent final : public core::Component + class AttachToNodeComponent final : public IAttachToNodeComponent { public: - VG_CLASS_DECL(AttachToNodeComponent, core::Component); + VG_CLASS_DECL(AttachToNodeComponent, IAttachToNodeComponent); AttachToNodeComponent(const core::string & _name, IObject * _parent); ~AttachToNodeComponent(); void OnLoad () final override; - void OnEnable () final override; - void OnDisable () final override; + void OnPlay () final override; + void OnStop () final override; + void Update (const Context & _context) final override; void SetPropertyValue (const core::IProperty & _prop, void * _previousValue, void * _newValue) final override; + void SetUseTarget (bool _useTarget) final override; + void SetTarget (core::IGameObject * _target) final override; + void SetBoneName (const core::string & _boneName) final override; + bool updateCache (); void clearCache (); @@ -34,6 +39,10 @@ namespace vg::engine bool m_useTarget = false; core::ObjectHandle m_target; core::string m_boneName; + //bool m_useTransform = false; + core::float4x4 m_transform = core::float4x4::identity(); + + const core::IGameObject * m_gameObject = nullptr; const renderer::ISkeleton * m_skeleton; renderer::NodeIndex m_nodeIndex; }; diff --git a/src/engine/Engine.vcxproj.filters b/src/engine/Engine.vcxproj.filters index 8bec3d3af..2390d6cbd 100644 --- a/src/engine/Engine.vcxproj.filters +++ b/src/engine/Engine.vcxproj.filters @@ -346,6 +346,7 @@ Component\Audio\Sound + diff --git a/src/engine/IAttachToNodeComponent.h b/src/engine/IAttachToNodeComponent.h new file mode 100644 index 000000000..038331695 --- /dev/null +++ b/src/engine/IAttachToNodeComponent.h @@ -0,0 +1,16 @@ +#pragma once + +#include "core/Component/Component.h" + +namespace vg::engine +{ + class IAttachToNodeComponent : public core::Component + { + public: + VG_CLASS_DECL_ABSTRACT(IAttachToNodeComponent, core::Component); + + virtual void SetUseTarget(bool _useTarget) = 0; + virtual void SetTarget(core::IGameObject * _target) = 0; + virtual void SetBoneName(const core::string & _boneName) = 0; + }; +} \ No newline at end of file diff --git a/src/engine/Input/win32/Input_win32.h b/src/engine/Input/win32/Input_win32.h index 16acbaf5a..093edf2c5 100644 --- a/src/engine/Input/win32/Input_win32.h +++ b/src/engine/Input/win32/Input_win32.h @@ -55,8 +55,8 @@ namespace vg::engine::win32 core::uint GetJoyCount () const override; core::float2 GetJoyLeftStickDir (core::JoyID _id) const final override; core::float2 GetJoyRightStickDir (core::JoyID _id) const final override; - float GetLeftTrigger (core::JoyID _id) const final override; - float GetRightTrigger (core::JoyID _id) const final override; + float GetJoyLeftTrigger (core::JoyID _id) const final override; + float GetJoyRightTrigger (core::JoyID _id) const final override; bool IsJoyButtonPressed (core::JoyID _id, core::JoyButton _button) const final override; bool IsJoyButtonJustPressed (core::JoyID _id, core::JoyButton _button) const final override; bool IsJoyButtonJustReleased (core::JoyID _id, core::JoyButton _button) const final override; diff --git a/src/engine/Input/win32/Input_win32.hpp b/src/engine/Input/win32/Input_win32.hpp index 14e89babe..a91180d37 100644 --- a/src/engine/Input/win32/Input_win32.hpp +++ b/src/engine/Input/win32/Input_win32.hpp @@ -627,13 +627,13 @@ namespace vg::engine::win32 } //-------------------------------------------------------------------------------------- - float Input::GetLeftTrigger(core::JoyID _id) const + float Input::GetJoyLeftTrigger(core::JoyID _id) const { return m_joystickData[_id].m_leftTrigger; } //-------------------------------------------------------------------------------------- - float Input::GetRightTrigger(core::JoyID _id) const + float Input::GetJoyRightTrigger(core::JoyID _id) const { return m_joystickData[_id].m_rightTrigger; } diff --git a/src/engine/engine.vcxproj b/src/engine/engine.vcxproj index f435a4793..6d21c3c51 100644 --- a/src/engine/engine.vcxproj +++ b/src/engine/engine.vcxproj @@ -75,6 +75,7 @@ + diff --git a/src/renderer/Instance/Mesh/MeshInstance.hpp b/src/renderer/Instance/Mesh/MeshInstance.hpp index bed608fd6..19ee89038 100644 --- a/src/renderer/Instance/Mesh/MeshInstance.hpp +++ b/src/renderer/Instance/Mesh/MeshInstance.hpp @@ -472,7 +472,7 @@ namespace vg::renderer } // Update skeleton node - skeletonNode.node_to_parent = TRS(pos, rot, scale); + skeletonNode.node_to_parent = TRSToFloat4x4(pos, rot, scale); if (-1 != skeletonNode.parent_index) skeletonNode.node_to_world = mul(skeletonNodes[skeletonNode.parent_index].node_to_world, skeletonNode.node_to_parent);