Physic rebuild start

This commit is contained in:
CatChow0 2025-01-15 18:33:02 +01:00
parent 58cafd7682
commit c707e49561
6 changed files with 188 additions and 116 deletions

View File

@ -32,6 +32,13 @@ ApplicationClass::ApplicationClass() : m_ShouldQuit(false)
ApplicationClass::~ApplicationClass() 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; return false;
} }
m_Physics = new Physics;
std::thread physicsThread(&ApplicationClass::PhysicsThreadFunction, this);
physicsThread.detach();
} }
catch (const std::exception& e) 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); Logger::Get().Log("Application class initialized", __FILE__, __LINE__, Logger::LogLevel::Initialize);
m_Physics = new Physics;
return true; return true;
} }
@ -637,7 +649,7 @@ void ApplicationClass::Shutdown()
bool ApplicationClass::Frame(InputClass* Input) bool ApplicationClass::Frame(InputClass* Input)
{ {
int mouseX, mouseY, currentMouseX, currentMouseY; 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; float rotationY, rotationX, positionX, positionY, positionZ;
static float textureTranslation = 0.0f; static float textureTranslation = 0.0f;
@ -756,104 +768,11 @@ bool ApplicationClass::Frame(InputClass* Input)
{ {
return false; return false;
} }
//// Update the x position variable each frame.
//x -= 0.0174532925f * 0.6f;
//y -= 0.0174532925f * 0.2f; m_Inputs.m_KeyLeft = Input->IsLeftArrowPressed();
m_Inputs.m_KeyRight = Input->IsRightArrowPressed();
//// Update the z position variable each frame. m_Inputs.m_KeyUp = Input->IsUpArrowPressed();
//z -= 0.0174532925f * 0.2f; m_Inputs.m_KeyDown = Input->IsDownArrowPressed();
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();
}
}
// Render the scene to a render texture. // Render the scene to a render texture.
result = RenderSceneToTexture(rotation); result = RenderSceneToTexture(rotation);
@ -1543,6 +1462,7 @@ void ApplicationClass::AddKobject(WCHAR* filepath)
newObject->SetTranslateMatrix(XMMatrixTranslation(0.0f, 50.0f, 0.0f)); newObject->SetTranslateMatrix(XMMatrixTranslation(0.0f, 50.0f, 0.0f));
newObject->SetName(filename); newObject->SetName(filename);
newObject->SetId(m_ObjectId); newObject->SetId(m_ObjectId);
newObject->SetType(ObjectType::Cube);
m_ObjectId++; m_ObjectId++;
@ -1957,4 +1877,118 @@ void ApplicationClass::ConstructFrustum()
m_Camera->GetViewMatrix(viewMatrix); m_Camera->GetViewMatrix(viewMatrix);
m_FrustumCulling.ConstructFrustum(SCREEN_DEPTH, projectionMatrix, viewMatrix); m_FrustumCulling.ConstructFrustum(SCREEN_DEPTH, projectionMatrix, viewMatrix);
} }
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<float> 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));
}
}

View File

@ -33,6 +33,8 @@
#include <WICTextureLoader.h> #include <WICTextureLoader.h>
#include <comdef.h> // Pour _com_error #include <comdef.h> // Pour _com_error
#include <thread>
#include <chrono>
///////////// /////////////
@ -42,6 +44,13 @@ const bool FULL_SCREEN = false;
const float SCREEN_DEPTH = 1000.0f; const float SCREEN_DEPTH = 1000.0f;
const float SCREEN_NEAR = 0.3f; 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 // Class name: ApplicationClass
@ -50,13 +59,13 @@ class ApplicationClass
{ {
public: public:
ApplicationClass(); ApplicationClass();
ApplicationClass(const ApplicationClass&);
~ApplicationClass(); ~ApplicationClass();
D3DClass* GetDirect3D(); D3DClass* GetDirect3D();
bool Initialize(int, int, HWND); bool Initialize(int, int, HWND);
void Shutdown(); void Shutdown();
bool Frame(InputClass*); bool Frame(InputClass*);
void PhysicsThreadFunction();
int GetScreenWidth() const; int GetScreenWidth() const;
void SetScreenWidth(int screenWidth); void SetScreenWidth(int screenWidth);
@ -121,7 +130,7 @@ public:
private: private:
bool Render(float, float, float, float, float); 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 UpdateMouseStrings(int, int, bool);
bool UpdateFps(); bool UpdateFps();
bool UpdateRenderCountString(int); bool UpdateRenderCountString(int);
@ -146,6 +155,8 @@ private :
HWND m_hwnd; HWND m_hwnd;
bool m_windowed; bool m_windowed;
int m_PhysicTickRate = 50; // physics execute 50 times per second
// ------------------------------------- // // ------------------------------------- //
// ------------- RENDERING ------------- // // ------------- RENDERING ------------- //
// ------------------------------------- // // ------------------------------------- //
@ -227,6 +238,12 @@ private :
Frustum m_FrustumCulling; Frustum m_FrustumCulling;
int m_renderCount; int m_renderCount;
float m_FrustumCullingTolerance = 5.f; float m_FrustumCullingTolerance = 5.f;
// ------------------------------------------------- //
// -------------------- Input ---------------------- //
// ------------------------------------------------- //
Input m_Inputs;
}; };
#endif #endif

View File

@ -254,6 +254,11 @@ void imguiManager::WidgetObjectWindow(ApplicationClass* app)
object->SetActiveShader(Object::SPECULAR_MAPPING); object->SetActiveShader(Object::SPECULAR_MAPPING);
} }
ImGui::Separator();
// Physics
std::string physicsLabel = "Physics##" + std::to_string(index);
ImGui::Separator(); ImGui::Separator();

View File

@ -176,9 +176,9 @@ void Object::SetVelocity(XMVECTOR velocity)
m_velocity = 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 XMVECTOR Object::GetVelocity() const

View File

@ -3,6 +3,13 @@
#include <WICTextureLoader.h> #include <WICTextureLoader.h>
#include <SimpleMath.h> #include <SimpleMath.h>
enum class ObjectType
{
Sphere,
Cube,
Unknown
};
class Object : public ModelClass class Object : public ModelClass
{ {
public: public:
@ -30,7 +37,7 @@ public:
XMVECTOR GetScale(); XMVECTOR GetScale();
void SetVelocity(XMVECTOR); void SetVelocity(XMVECTOR);
void AddVelocity(float); void AddVelocity(float deltaTime);
XMVECTOR GetVelocity() const; XMVECTOR GetVelocity() const;
void SetAcceleration(XMVECTOR); void SetAcceleration(XMVECTOR);
XMVECTOR GetAcceleration() const; XMVECTOR GetAcceleration() const;
@ -54,6 +61,8 @@ public:
void SetName(std::string name); void SetName(std::string name);
int SetId(int id); int SetId(int id);
int GetId() const; 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); bool LoadTexture(ID3D11Device* device, ID3D11DeviceContext* deviceContext, const std::wstring& filename);
@ -88,9 +97,10 @@ private:
XMVECTOR m_acceleration; XMVECTOR m_acceleration;
float m_mass; float m_mass;
bool m_isGrounded; bool m_isGrounded;
bool m_isPhysicsEnabled; bool m_isPhysicsEnabled = false;
std::string m_name; std::string m_name;
ObjectType m_type = ObjectType::Unknown;
ShaderType m_activeShader = LIGHTING; ShaderType m_activeShader = LIGHTING;

View File

@ -79,21 +79,26 @@ void Physics::AddForce(Object* object, XMVECTOR force)
bool Physics::IsColliding(Object* object1, Object* object2) bool Physics::IsColliding(Object* object1, Object* object2)
{ {
ObjectType type1 = object1->GetType();
ObjectType type2 = object2->GetType();
std::string type1 = object1->GetName(); if (type1 == ObjectType::Unknown || type2 == ObjectType::Unknown)
std::string type2 = object2->GetName(); {
return false;
if (type1 == "sphere" && type2 == "sphere")
{
return SpheresOverlap(object1, object2);
} }
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); return SphereCubeOverlap(object1, object2);
} }
else if (type1 == "sphere") else if (type1 == ObjectType::Sphere)
{ {
return SphereCubeOverlap(object2, object1); return SphereCubeOverlap(object2, object1);
} }
@ -106,6 +111,7 @@ bool Physics::IsColliding(Object* object1, Object* object2)
return false; return false;
} }
///////////////////////////////////////// /////////////////////////////////////////
// AABB method for collision detection // // AABB method for collision detection //
///////////////////////////////////////// /////////////////////////////////////////