From c707e4956148d160bb748c86b48b44d826bcd63a Mon Sep 17 00:00:00 2001 From: CatChow0 Date: Wed, 15 Jan 2025 18:33:02 +0100 Subject: [PATCH] Physic rebuild start --- enginecustom/applicationclass.cpp | 234 +++++++++++++++++------------- enginecustom/applicationclass.h | 21 ++- enginecustom/imguiManager.cpp | 5 + enginecustom/object.cpp | 4 +- enginecustom/object.h | 14 +- enginecustom/physics.cpp | 26 ++-- 6 files changed, 188 insertions(+), 116 deletions(-) diff --git a/enginecustom/applicationclass.cpp b/enginecustom/applicationclass.cpp index 087b92f..7692732 100644 --- a/enginecustom/applicationclass.cpp +++ b/enginecustom/applicationclass.cpp @@ -32,6 +32,13 @@ ApplicationClass::ApplicationClass() : m_ShouldQuit(false) ApplicationClass::~ApplicationClass() { + m_ShouldQuit = true; + + // wait for the physics thread to finish + while (m_Physics) + { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } } @@ -400,6 +407,11 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) return false; } + m_Physics = new Physics; + + std::thread physicsThread(&ApplicationClass::PhysicsThreadFunction, this); + physicsThread.detach(); + } catch (const std::exception& e) @@ -409,7 +421,7 @@ bool ApplicationClass::Initialize(int screenWidth, int screenHeight, HWND hwnd) } Logger::Get().Log("Application class initialized", __FILE__, __LINE__, Logger::LogLevel::Initialize); - m_Physics = new Physics; + return true; } @@ -637,7 +649,7 @@ void ApplicationClass::Shutdown() bool ApplicationClass::Frame(InputClass* Input) { int mouseX, mouseY, currentMouseX, currentMouseY; - bool result, leftMouseDown, rightMouseDown, keyLeft, keyRight, keyUp, keyDown, buttonQ, buttonD, buttonZ, buttonS, buttonA, buttonE, scrollUp, scrollDown; + bool result, leftMouseDown, rightMouseDown, buttonQ, buttonD, buttonZ, buttonS, buttonA, buttonE, scrollUp, scrollDown; float rotationY, rotationX, positionX, positionY, positionZ; static float textureTranslation = 0.0f; @@ -756,104 +768,11 @@ bool ApplicationClass::Frame(InputClass* Input) { return false; } - //// Update the x position variable each frame. - //x -= 0.0174532925f * 0.6f; - //y -= 0.0174532925f * 0.2f; - - //// Update the z position variable each frame. - //z -= 0.0174532925f * 0.2f; - - keyLeft = Input->IsLeftArrowPressed(); - keyRight = Input->IsRightArrowPressed(); - keyUp = Input->IsUpArrowPressed(); - keyDown = Input->IsDownArrowPressed(); - - for (auto& object : m_object) - { - if (object != nullptr) // Check if the object is not null - { - // Reset acceleration for the new frame - object->SetAcceleration(XMVectorZero()); - - object->SetGrounded(false); - - for (auto& chunk : m_terrainChunk) - { - if (m_Physics->IsColliding(object, chunk)) - { - - // Stop vertical movement, like gravity - object->SetVelocity(XMVectorSetY(object->GetVelocity(), 0.0f)); - object->SetAcceleration(XMVectorSetY(object->GetAcceleration(), 0.0f)); - - //// Stop movement in any direction - //object->SetVelocity(XMVectorZero()); - //object->SetAcceleration(XMVectorZero()); - object->SetGrounded(true); - } - } - - for (auto& object2 : m_object) - { - if (object->GetId() != object2->GetId() && object2 != nullptr) - { - if (m_Physics->IsColliding(object, object2)) - { - // Stop movement in any direction - object->SetVelocity(XMVectorZero()); - object->SetAcceleration(XMVectorZero()); - } - } - - } - - // Apply forces - float forceX = 0, forceY = 0, forceZ = 0, forceW = 0; - - if (keyLeft) - { - forceX = -10.0f; - } - if (keyRight) - { - forceX = 10.0f; - } - if (keyUp) - { - forceY = 40.0f; - } - if (keyDown && !object->IsGrounded()) - { - forceY = -40.0f; - } - - XMVECTOR force = XMVectorSet(forceX, forceY, forceZ, forceW); - m_Physics->AddForce(object, force); - - // Update velocity based on acceleration - object->AddVelocity(frameTime); - - // Update position based on velocity - XMVECTOR position = object->GetPosition(); - position = position + object->GetVelocity() * frameTime; - object->SetPosition(position); - - m_Physics->ApplyGravity(object, 1.0f); - - // Check if the object has fallen below a certain position - if (XMVectorGetY(object->GetPosition()) < -30.0f) - { - XMVECTOR currentPosition = object->GetPosition(); // Obtain the current position of the object - object->SetPosition(XMVectorSetY(currentPosition, 50.0f)); // Define the new position of the object - } - - object->m_previousPosition = object->GetPosition(); - } - } - - - + m_Inputs.m_KeyLeft = Input->IsLeftArrowPressed(); + m_Inputs.m_KeyRight = Input->IsRightArrowPressed(); + m_Inputs.m_KeyUp = Input->IsUpArrowPressed(); + m_Inputs.m_KeyDown = Input->IsDownArrowPressed(); // Render the scene to a render texture. result = RenderSceneToTexture(rotation); @@ -1543,6 +1462,7 @@ void ApplicationClass::AddKobject(WCHAR* filepath) newObject->SetTranslateMatrix(XMMatrixTranslation(0.0f, 50.0f, 0.0f)); newObject->SetName(filename); newObject->SetId(m_ObjectId); + newObject->SetType(ObjectType::Cube); m_ObjectId++; @@ -1957,4 +1877,118 @@ void ApplicationClass::ConstructFrustum() m_Camera->GetViewMatrix(viewMatrix); m_FrustumCulling.ConstructFrustum(SCREEN_DEPTH, projectionMatrix, viewMatrix); -} \ No newline at end of file +} + +bool ApplicationClass::RenderPhysics(bool keyLeft, bool keyRight, bool keyUp, bool keyDown, float deltaTime) { + + for (auto& object : m_object) + { + if (object == nullptr) + { + Logger::Get().Log("Object is null", __FILE__, __LINE__, Logger::LogLevel::Error); + return false; + } + + // Reset acceleration for the new frame + object->SetAcceleration(XMVectorZero()); + object->SetGrounded(false); + + for (auto& chunk : m_terrainChunk) + { + if (!m_Physics->IsColliding(object, chunk)) + { + continue; + } + + // Stop vertical movement, like gravity + object->SetVelocity(XMVectorSetY(object->GetVelocity(), 0.0f)); + object->SetAcceleration(XMVectorSetY(object->GetAcceleration(), 0.0f)); + object->SetGrounded(true); + } + + for (auto& object2 : m_object) + { + if (object->GetId() == object2->GetId()) + { + continue; + } + + if (!m_Physics->IsColliding(object, object2)) + { + continue; + } + + // Stop movement in any direction + object->SetVelocity(XMVectorZero()); + object->SetAcceleration(XMVectorZero()); + } + + // Apply forces + float forceX = 0, forceY = 0, forceZ = 0, forceW = 0; + + if (keyLeft) + { + forceX = -10.0f; + } + if (keyRight) + { + forceX = 10.0f; + } + if (keyUp) + { + forceY = 40.0f; + } + if (keyDown && !object->IsGrounded()) + { + forceY = -40.0f; + } + + XMVECTOR force = XMVectorSet(forceX, forceY, forceZ, forceW); + m_Physics->AddForce(object, force); + + // Update velocity based on acceleration + object->AddVelocity(deltaTime); + + // Update position based on velocity + XMVECTOR position = object->GetPosition(); + position = position + object->GetVelocity() * deltaTime; + object->SetPosition(position); + + m_Physics->ApplyGravity(object, deltaTime); + + // Check if the object has fallen below a certain position + if (XMVectorGetY(object->GetPosition()) < -30.0f) + { + XMVECTOR currentPosition = object->GetPosition(); // Obtain the current position of the object + object->SetPosition(XMVectorSetY(currentPosition, 50.0f)); // Define the new position of the object + } + + object->m_previousPosition = object->GetPosition(); + } + + return true; +} + + +void ApplicationClass::PhysicsThreadFunction() +{ + auto lastTime = std::chrono::high_resolution_clock::now(); + + while (!m_ShouldQuit) + { + auto currentTime = std::chrono::high_resolution_clock::now(); + std::chrono::duration elapsedTime = currentTime - lastTime; + float deltaTime = elapsedTime.count(); + lastTime = currentTime; + + bool result = RenderPhysics(m_Inputs.m_KeyLeft, m_Inputs.m_KeyRight, m_Inputs.m_KeyUp, m_Inputs.m_KeyDown, deltaTime); + if (!result) + { + Logger::Get().Log("Could not render the physics scene", __FILE__, __LINE__, Logger::LogLevel::Error); + return; + } + + // Attendre 20 millisecondes (50 fois par seconde) + std::this_thread::sleep_for(std::chrono::milliseconds(20)); + } +} diff --git a/enginecustom/applicationclass.h b/enginecustom/applicationclass.h index 956d03a..6f02332 100644 --- a/enginecustom/applicationclass.h +++ b/enginecustom/applicationclass.h @@ -33,6 +33,8 @@ #include #include // Pour _com_error +#include +#include ///////////// @@ -42,6 +44,13 @@ const bool FULL_SCREEN = false; const float SCREEN_DEPTH = 1000.0f; const float SCREEN_NEAR = 0.3f; +struct Input +{ + bool m_KeyLeft = false; + bool m_KeyRight = false; + bool m_KeyUp = false; + bool m_KeyDown = false; +}; //////////////////////////////////////////////////////////////////////////////// // Class name: ApplicationClass @@ -50,13 +59,13 @@ class ApplicationClass { public: ApplicationClass(); - ApplicationClass(const ApplicationClass&); ~ApplicationClass(); D3DClass* GetDirect3D(); bool Initialize(int, int, HWND); void Shutdown(); bool Frame(InputClass*); + void PhysicsThreadFunction(); int GetScreenWidth() const; void SetScreenWidth(int screenWidth); @@ -121,7 +130,7 @@ public: private: bool Render(float, float, float, float, float); - bool RenderPhysics(float x, float y, float z); + bool RenderPhysics(bool keyLeft, bool keyRight, bool keyUp, bool keyDown, float deltaTime); bool UpdateMouseStrings(int, int, bool); bool UpdateFps(); bool UpdateRenderCountString(int); @@ -146,6 +155,8 @@ private : HWND m_hwnd; bool m_windowed; + int m_PhysicTickRate = 50; // physics execute 50 times per second + // ------------------------------------- // // ------------- RENDERING ------------- // // ------------------------------------- // @@ -227,6 +238,12 @@ private : Frustum m_FrustumCulling; int m_renderCount; float m_FrustumCullingTolerance = 5.f; + + // ------------------------------------------------- // + // -------------------- Input ---------------------- // + // ------------------------------------------------- // + + Input m_Inputs; }; #endif \ No newline at end of file diff --git a/enginecustom/imguiManager.cpp b/enginecustom/imguiManager.cpp index 4a94b88..a88dd4f 100644 --- a/enginecustom/imguiManager.cpp +++ b/enginecustom/imguiManager.cpp @@ -254,6 +254,11 @@ void imguiManager::WidgetObjectWindow(ApplicationClass* app) object->SetActiveShader(Object::SPECULAR_MAPPING); } + ImGui::Separator(); + + // Physics + std::string physicsLabel = "Physics##" + std::to_string(index); + ImGui::Separator(); diff --git a/enginecustom/object.cpp b/enginecustom/object.cpp index 9417cd9..6e3ae37 100644 --- a/enginecustom/object.cpp +++ b/enginecustom/object.cpp @@ -176,9 +176,9 @@ void Object::SetVelocity(XMVECTOR velocity) m_velocity = velocity; } -void Object::AddVelocity(float frameTime) +void Object::AddVelocity(float deltaTime) { - m_velocity += m_acceleration * frameTime; + m_velocity += m_acceleration * deltaTime; } XMVECTOR Object::GetVelocity() const diff --git a/enginecustom/object.h b/enginecustom/object.h index 6abbc30..e342360 100644 --- a/enginecustom/object.h +++ b/enginecustom/object.h @@ -3,6 +3,13 @@ #include #include +enum class ObjectType +{ + Sphere, + Cube, + Unknown +}; + class Object : public ModelClass { public: @@ -30,7 +37,7 @@ public: XMVECTOR GetScale(); void SetVelocity(XMVECTOR); - void AddVelocity(float); + void AddVelocity(float deltaTime); XMVECTOR GetVelocity() const; void SetAcceleration(XMVECTOR); XMVECTOR GetAcceleration() const; @@ -54,6 +61,8 @@ public: void SetName(std::string name); int SetId(int id); int GetId() const; + void SetType(ObjectType type) { m_type = type; }; + ObjectType GetType() const { return m_type; }; bool LoadTexture(ID3D11Device* device, ID3D11DeviceContext* deviceContext, const std::wstring& filename); @@ -88,9 +97,10 @@ private: XMVECTOR m_acceleration; float m_mass; bool m_isGrounded; - bool m_isPhysicsEnabled; + bool m_isPhysicsEnabled = false; std::string m_name; + ObjectType m_type = ObjectType::Unknown; ShaderType m_activeShader = LIGHTING; diff --git a/enginecustom/physics.cpp b/enginecustom/physics.cpp index 585c6ce..4c3fffe 100644 --- a/enginecustom/physics.cpp +++ b/enginecustom/physics.cpp @@ -79,21 +79,26 @@ void Physics::AddForce(Object* object, XMVECTOR force) bool Physics::IsColliding(Object* object1, Object* object2) { + ObjectType type1 = object1->GetType(); + ObjectType type2 = object2->GetType(); - std::string type1 = object1->GetName(); - std::string type2 = object2->GetName(); - - if (type1 == "sphere" && type2 == "sphere") - { - return SpheresOverlap(object1, object2); + if (type1 == ObjectType::Unknown || type2 == ObjectType::Unknown) + { + return false; } - if (type1 == "cube" && type2 == "sphere" || (type1 == "sphere" && type2 == "cube")) + + if (type1 == ObjectType::Sphere && type2 == ObjectType::Sphere) { - if (type1 == "cube") + return SpheresOverlap(object1, object2); + } + if ((type1 == ObjectType::Cube && type2 == ObjectType::Sphere) || + (type1 == ObjectType::Sphere && type2 == ObjectType::Cube)) + { + if (type1 == ObjectType::Cube) { return SphereCubeOverlap(object1, object2); - } - else if (type1 == "sphere") + } + else if (type1 == ObjectType::Sphere) { return SphereCubeOverlap(object2, object1); } @@ -106,6 +111,7 @@ bool Physics::IsColliding(Object* object1, Object* object2) return false; } + ///////////////////////////////////////// // AABB method for collision detection // /////////////////////////////////////////