wip: draw physics thread ups
This commit is contained in:
@ -29,19 +29,17 @@ constexpr float ROT_SPEED = 1.0;
|
|||||||
constexpr float CAMERA_SMOOTH_SPEED = 15.0;
|
constexpr float CAMERA_SMOOTH_SPEED = 15.0;
|
||||||
|
|
||||||
// Physics Engine
|
// Physics Engine
|
||||||
constexpr float SIM_SPEED = 1.0; // How large each update should be
|
constexpr float TARGET_UPS = 90; // How often to update physics
|
||||||
constexpr float TIMESTEP = 1.0 / 90; // Do 90 physics updates per second
|
constexpr float TIMESTEP = 1.0 / TARGET_UPS; // Update interval in seconds
|
||||||
constexpr float MASS = 1.0; // Mass spring system
|
constexpr float SIM_SPEED = 4.0; // How large each update should be
|
||||||
constexpr float SPRING_CONSTANT = 5.0; // Mass spring system
|
constexpr float MASS = 1.0; // Mass spring system
|
||||||
constexpr float DAMPENING_CONSTANT = 1.0; // Mass spring system
|
constexpr float SPRING_CONSTANT = 5.0; // Mass spring system
|
||||||
constexpr float REST_LENGTH = 2.0; // Mass spring system
|
constexpr float DAMPENING_CONSTANT = 1.0; // Mass spring system
|
||||||
constexpr float VERLET_DAMPENING = 0.05; // [0, 1]
|
constexpr float REST_LENGTH = 2.0; // Mass spring system
|
||||||
constexpr float BH_FORCE = 2.0; // BH: [1.0, 3.0]
|
constexpr float VERLET_DAMPENING = 0.05; // [0, 1]
|
||||||
constexpr float THETA = 1.0; // Barnes-Hut [0.5, 1.0]
|
constexpr float BH_FORCE = 2.0; // Barnes-Hut [1.0, 3.0]
|
||||||
constexpr float SOFTENING = 0.01; // Barnes-Hut [0.01, 1.0]
|
constexpr float THETA = 0.9; // Barnes-Hut [0.5, 1.0]
|
||||||
constexpr float GRID_FORCE = 0.02; // Grid: [0.0, ~0.05]
|
constexpr float SOFTENING = 0.01; // Barnes-Hut [0.01, 1.0]
|
||||||
constexpr float REPULSION_RANGE = 5.0 * REST_LENGTH; // Grid
|
|
||||||
constexpr int REPULSION_GRID_REFRESH = 5; // Grid rebuild freq
|
|
||||||
|
|
||||||
// Graph Drawing
|
// Graph Drawing
|
||||||
constexpr float VERTEX_SIZE = 0.5;
|
constexpr float VERTEX_SIZE = 0.5;
|
||||||
|
|||||||
@ -122,6 +122,7 @@ class ThreadedPhysics {
|
|||||||
TracyLockable(std::mutex, data_mtx);
|
TracyLockable(std::mutex, data_mtx);
|
||||||
std::condition_variable_any data_ready_cnd;
|
std::condition_variable_any data_ready_cnd;
|
||||||
std::condition_variable_any data_consumed_cnd;
|
std::condition_variable_any data_consumed_cnd;
|
||||||
|
unsigned int ups = 0;
|
||||||
bool data_ready = false;
|
bool data_ready = false;
|
||||||
bool data_consumed = true;
|
bool data_consumed = true;
|
||||||
std::vector<Vector3> masses; // Read by renderer
|
std::vector<Vector3> masses; // Read by renderer
|
||||||
|
|||||||
@ -77,7 +77,7 @@ public:
|
|||||||
const std::vector<std::pair<std::size_t, std::size_t>> &springs)
|
const std::vector<std::pair<std::size_t, std::size_t>> &springs)
|
||||||
-> void;
|
-> void;
|
||||||
|
|
||||||
auto DrawTextures() -> void;
|
auto DrawTextures(float ups) -> void;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -44,6 +44,7 @@ auto main(int argc, char *argv[]) -> int {
|
|||||||
OrbitCamera3D camera;
|
OrbitCamera3D camera;
|
||||||
Renderer renderer(camera, state, input);
|
Renderer renderer(camera, state, input);
|
||||||
|
|
||||||
|
unsigned int ups;
|
||||||
std::vector<Vector3> masses; // Read from physics
|
std::vector<Vector3> masses; // Read from physics
|
||||||
std::vector<std::pair<std::size_t, std::size_t>> springs; // Read from physics
|
std::vector<std::pair<std::size_t, std::size_t>> springs; // Read from physics
|
||||||
|
|
||||||
@ -61,6 +62,8 @@ auto main(int argc, char *argv[]) -> int {
|
|||||||
{
|
{
|
||||||
std::unique_lock<LockableBase(std::mutex)> lock(physics.state.data_mtx);
|
std::unique_lock<LockableBase(std::mutex)> lock(physics.state.data_mtx);
|
||||||
|
|
||||||
|
ups = physics.state.ups;
|
||||||
|
|
||||||
// Only copy data if any has been produced
|
// Only copy data if any has been produced
|
||||||
if (physics.state.data_ready) {
|
if (physics.state.data_ready) {
|
||||||
masses = physics.state.masses;
|
masses = physics.state.masses;
|
||||||
@ -88,7 +91,7 @@ auto main(int argc, char *argv[]) -> int {
|
|||||||
renderer.DrawMassSprings(masses, springs);
|
renderer.DrawMassSprings(masses, springs);
|
||||||
renderer.DrawKlotski();
|
renderer.DrawKlotski();
|
||||||
renderer.DrawMenu(masses, springs);
|
renderer.DrawMenu(masses, springs);
|
||||||
renderer.DrawTextures();
|
renderer.DrawTextures(ups);
|
||||||
FrameMarkEnd("MainThread");
|
FrameMarkEnd("MainThread");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,8 +5,10 @@
|
|||||||
#include <BS_thread_pool.hpp>
|
#include <BS_thread_pool.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
|
#include <chrono>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <ratio>
|
||||||
#include <raylib.h>
|
#include <raylib.h>
|
||||||
#include <raymath.h>
|
#include <raymath.h>
|
||||||
#include <tracy/Tracy.hpp>
|
#include <tracy/Tracy.hpp>
|
||||||
@ -190,8 +192,21 @@ auto ThreadedPhysics::PhysicsThread(ThreadedPhysics::PhysicsState &state)
|
|||||||
[&](const struct ClearGraph &cg) { mass_springs.Clear(); },
|
[&](const struct ClearGraph &cg) { mass_springs.Clear(); },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::chrono::time_point last = std::chrono::high_resolution_clock::now();
|
||||||
|
std::chrono::duration<double> accumulator(0);
|
||||||
|
std::chrono::duration<double> update_accumulator(0);
|
||||||
|
unsigned int updates = 0;
|
||||||
|
|
||||||
while (state.running.load()) {
|
while (state.running.load()) {
|
||||||
FrameMarkStart("PhysicsThread");
|
FrameMarkStart("PhysicsThread");
|
||||||
|
|
||||||
|
// Time tracking
|
||||||
|
std::chrono::time_point now = std::chrono::high_resolution_clock::now();
|
||||||
|
std::chrono::duration<double> deltatime = now - last;
|
||||||
|
accumulator += deltatime;
|
||||||
|
update_accumulator += deltatime;
|
||||||
|
last = now;
|
||||||
|
|
||||||
// Handle queued commands
|
// Handle queued commands
|
||||||
{
|
{
|
||||||
std::lock_guard<LockableBase(std::mutex)> lock(state.command_mtx);
|
std::lock_guard<LockableBase(std::mutex)> lock(state.command_mtx);
|
||||||
@ -208,11 +223,15 @@ auto ThreadedPhysics::PhysicsThread(ThreadedPhysics::PhysicsState &state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Physics update
|
// Physics update
|
||||||
// TODO: Respect thread-local deltatime + calculate UPS
|
if (accumulator.count() > TIMESTEP) {
|
||||||
mass_springs.ClearForces();
|
mass_springs.ClearForces();
|
||||||
mass_springs.CalculateSpringForces();
|
mass_springs.CalculateSpringForces();
|
||||||
mass_springs.CalculateRepulsionForces();
|
mass_springs.CalculateRepulsionForces();
|
||||||
mass_springs.VerletUpdate(TIMESTEP * SIM_SPEED);
|
mass_springs.VerletUpdate(TIMESTEP * SIM_SPEED);
|
||||||
|
|
||||||
|
++updates;
|
||||||
|
accumulator -= std::chrono::duration<double>(TIMESTEP);
|
||||||
|
}
|
||||||
|
|
||||||
// Publish the positions for the renderer (copy)
|
// Publish the positions for the renderer (copy)
|
||||||
FrameMarkStart("PhysicsThreadProduceLock");
|
FrameMarkStart("PhysicsThreadProduceLock");
|
||||||
@ -225,6 +244,13 @@ auto ThreadedPhysics::PhysicsThread(ThreadedPhysics::PhysicsState &state)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (update_accumulator.count() > 1.0) {
|
||||||
|
// Update each second
|
||||||
|
state.ups = updates;
|
||||||
|
updates = 0;
|
||||||
|
update_accumulator = std::chrono::duration<double>(0);
|
||||||
|
}
|
||||||
|
|
||||||
state.masses.clear();
|
state.masses.clear();
|
||||||
state.masses.reserve(mass_springs.masses.size());
|
state.masses.reserve(mass_springs.masses.size());
|
||||||
for (const auto &mass : mass_springs.masses) {
|
for (const auto &mass : mass_springs.masses) {
|
||||||
|
|||||||
@ -316,7 +316,7 @@ auto Renderer::DrawMenu(
|
|||||||
EndTextureMode();
|
EndTextureMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Renderer::DrawTextures() -> void {
|
auto Renderer::DrawTextures(float ups) -> void {
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
DrawTextureRec(menu_target.texture,
|
DrawTextureRec(menu_target.texture,
|
||||||
Rectangle(0, 0, menu_target.texture.width,
|
Rectangle(0, 0, menu_target.texture.width,
|
||||||
@ -330,6 +330,9 @@ auto Renderer::DrawTextures() -> void {
|
|||||||
Rectangle(0, 0, render_target.texture.width,
|
Rectangle(0, 0, render_target.texture.width,
|
||||||
-1 * render_target.texture.height),
|
-1 * render_target.texture.height),
|
||||||
Vector2(GetScreenWidth() / 2.0, MENU_HEIGHT), WHITE);
|
Vector2(GetScreenWidth() / 2.0, MENU_HEIGHT), WHITE);
|
||||||
|
|
||||||
DrawFPS(GetScreenWidth() / 2 + 10, MENU_HEIGHT + 10);
|
DrawFPS(GetScreenWidth() / 2 + 10, MENU_HEIGHT + 10);
|
||||||
|
DrawText(TextFormat("%.0f UPS", ups), GetScreenWidth() / 2 + 120,
|
||||||
|
MENU_HEIGHT + 10, 20, ORANGE);
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user