-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
61 changed files
with
1,225 additions
and
1,351 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,5 +3,6 @@ lib/*/ | |
imgui.ini | ||
compile_commands.json | ||
.DS_Store | ||
src/web/sandbox.* | ||
src/web/asteroids.* | ||
src/tests | ||
.cache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,76 +0,0 @@ | ||
# C++ Simple physics engine | ||
|
||
Implements a simple physics engine in C++ based on [Verlet integration](https://en.wikipedia.org/wiki/Verlet_integration) and [Verlet constraints](https://en.wikipedia.org/wiki/Verlet_integration#Verlet_constraints). | ||
|
||
<center> | ||
<p float="left" align="center"> | ||
<img src=".github/screenshots/screenshot01.png" style="width: 48%"/> | ||
<img src=".github/screenshots/screenshot02.png" style="width: 48%"/> | ||
</p> | ||
</center> | ||
|
||
<p align="center"> | ||
<a href="https://leandrosq.github.io/cpp-physics-sandbox/">Live demo here</a> | ||
</p> | ||
|
||
## About | ||
|
||
You can check the WEB version [here](https://leandrosq.github.io/cpp-physics-sandbox/). It is a port using WASM generated by Emscripten using WebGL on the browser. | ||
|
||
* Restricted only to circles | ||
* Supports gravity | ||
* Supports collisions | ||
* Implements a Quadtree for collision detection | ||
* Supports constraints | ||
* Implements both a circle and a rectangle world constraint | ||
* Supports user interaction | ||
* Dragging | ||
* Spawning | ||
* Explode | ||
|
||
## Controls | ||
|
||
### Desktop | ||
|
||
> <img src=".github/images/Mouse_Left_Key_Dark.png" align="center" height="32"> `Left click` to spawn circles | ||
> <img src=".github/images/Mouse_Right_Key_Dark.png" align="center" height="32"> `Right click` to drag circles | ||
> <img src=".github/images/Mouse_Middle_Key_Dark.png" align="center" height="32"> `Middle click` to explode circles | ||
> <img src=".github/images/Space_Key_Dark.png" align="center" height="32"> `Space bar` to flip the Gravity vector | ||
> <img src=".github/images/Z_Key_Dark.png" align="center" height="32"> `Z` to toggle Gravity ON/OFF | ||
> <img src=".github/images/Arrow_Up_Key_Dark.png" align="center" height="32"> `Up arrow` to increase the Gravity force | ||
> <img src=".github/images/Arrow_Down_Key_Dark.png" align="center" height="32"> `Down arrow` to decrease the Gravity force | ||
> <img src=".github/images/Arrow_Left_Key_Dark.png" align="center" height="32"> `Left arrow` to decrease the Gravity angle | ||
> <img src=".github/images/Arrow_Right_Key_Dark.png" align="center" height="32"> `Right arrow` to increase the Gravity angle | ||
> <img src=".github/images/Esc_Key_Dark.png" align="center" height="32"> `ESC` to exit | ||
<p float="left" align="center"> | ||
<span>Other controls included on the GUI can be used with the mouse as demonstrated below.</span> | ||
<img src=".github/screenshots/screenshot03.png" style="width: 48%"/> | ||
</p> | ||
|
||
## Project | ||
|
||
### Resources | ||
|
||
| Name | Description | | ||
| -- | -- | | ||
| [ClangD](https://clangd.llvm.org/) | Language Server for C++ | | ||
| [CMake](https://cmake.org/) | Cross-platform open-source make system | | ||
| [Clang-tidy](https://clang.llvm.org/extra/clang-tidy/) | A clang-based C++ “linter” tool | | ||
| [Clang-format](https://clang.llvm.org/docs/ClangFormat.html) | A tool to format C/C++/Obj-C code | | ||
| [Emscripten](https://emscripten.org/) | Used for the web port, generating the WASM binaries. | | ||
| [Raylib](https://www.raylib.com/) | A simple and easy-to-use library to enjoy videogames programming | | ||
| [Dear ImGui](https://www.github.com/ocornut/imgui) | Bloat-free Immediate Mode Graphical User interface for C++ with minimal dependencies | | ||
| [Dear ImGui Raylib](https:://github.com/RobLoach/raylib-imgui) | Dear ImGui bindings for Raylib | | ||
| [NES CSS](https://nostalgic-css.github.io/NES.css/) | NES.css is NES-style (8bit-like) CSS Framework. | | ||
| Github Actions | Used for CI/CD | | ||
| Github Pages | Used for hosting the web version | | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,4 +11,4 @@ else | |
exit 1 | ||
fi | ||
|
||
cp ./build/web/sandbox.* ./src/web | ||
cp ./build/web/asteroids.* ./src/web |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#include "dummy-list.hpp" | ||
#include "../models/asteroid.hpp" | ||
|
||
void DummyList::clear() { | ||
asteroids.clear(); | ||
} | ||
|
||
bool DummyList::isEmpty() { | ||
return asteroids.empty(); | ||
} | ||
|
||
uint32_t DummyList::size() { | ||
return asteroids.size(); | ||
} | ||
|
||
uint16_t DummyList::getCellIndex(raylib::Vector2 position) { | ||
return 0; | ||
} | ||
|
||
raylib::Vector2 DummyList::getCellPosition(uint16_t index) { | ||
return raylib::Vector2::Zero(); | ||
} | ||
|
||
void DummyList::resize(uint16_t rows, uint16_t cols) { | ||
// Do nothing | ||
} | ||
|
||
void DummyList::insert(std::shared_ptr<Asteroid> asteroid) { | ||
asteroids.push_back(asteroid); | ||
} | ||
|
||
void DummyList::remove(std::shared_ptr<Asteroid> asteroid) { | ||
asteroids.erase(std::remove(asteroids.begin(), asteroids.end(), asteroid), asteroids.end()); | ||
} | ||
|
||
std::vector<std::shared_ptr<Asteroid>> DummyList::retrieve(raylib::Vector2 position, uint16_t radius) { | ||
return asteroids; | ||
} | ||
|
||
std::vector<std::shared_ptr<Asteroid>> DummyList::all() { | ||
return asteroids; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#pragma once | ||
|
||
#include "../precomp.hpp" | ||
#include "icontainer.hpp" | ||
|
||
class Asteroid; | ||
|
||
class DummyList : public IContainer { | ||
private: | ||
std::vector<std::shared_ptr<Asteroid>> asteroids; | ||
|
||
public: | ||
DummyList() = default; | ||
~DummyList() = default; | ||
|
||
void clear() override; | ||
bool isEmpty() override; | ||
uint32_t size() override; | ||
uint16_t getCellIndex(raylib::Vector2 position) override; | ||
raylib::Vector2 getCellPosition(uint16_t index) override; | ||
void resize(uint16_t rows, uint16_t cols) override; | ||
void insert(std::shared_ptr<Asteroid> asteroid) override; | ||
void remove(std::shared_ptr<Asteroid> asteroid) override; | ||
std::vector<std::shared_ptr<Asteroid>> retrieve(raylib::Vector2 position, uint16_t radius) override; | ||
std::vector<std::shared_ptr<Asteroid>> all() override; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#pragma once | ||
|
||
#include "../precomp.hpp" | ||
|
||
class Asteroid; | ||
|
||
class IContainer { | ||
public: | ||
virtual void clear() = 0; | ||
virtual bool isEmpty() = 0; | ||
virtual uint32_t size() = 0; | ||
virtual uint16_t getCellIndex(raylib::Vector2 position) = 0; | ||
virtual raylib::Vector2 getCellPosition(uint16_t index) = 0; | ||
virtual void resize(uint16_t rows, uint16_t cols) = 0; | ||
virtual void insert(std::shared_ptr<Asteroid> asteroid) = 0; | ||
virtual void remove(std::shared_ptr<Asteroid> asteroid) = 0; | ||
virtual std::vector<std::shared_ptr<Asteroid>> retrieve(raylib::Vector2 position, uint16_t radius) = 0; | ||
virtual std::vector<std::shared_ptr<Asteroid>> all() = 0; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
#include "spatial-hash-grid.hpp" | ||
#include "../settings.hpp" | ||
#include "../models/asteroid.hpp" | ||
|
||
void SpatialHashGrid::clear() { | ||
for (auto &cell : cells) { | ||
cell.asteroids.resize(0); | ||
} | ||
count = 0; | ||
} | ||
|
||
bool SpatialHashGrid::isEmpty() { | ||
return cells.empty() || count <= 0; | ||
} | ||
|
||
uint32_t SpatialHashGrid::size() { | ||
return count; | ||
} | ||
|
||
uint16_t SpatialHashGrid::getCellIndex(raylib::Vector2 position) { | ||
uint16_t index = (uint16_t)(position.y / cellSize) * cols + (uint16_t)(position.x / cellSize); | ||
if (index < 0) index = 0; | ||
if (index >= cells.size()) index = cells.size() - 1; | ||
return index; | ||
} | ||
|
||
raylib::Vector2 SpatialHashGrid::getCellPosition(uint16_t index) { | ||
return raylib::Vector2((index % cols) * cellSize, ((float)index / cols) * cellSize); | ||
} | ||
|
||
void SpatialHashGrid::resize(uint16_t rows, uint16_t cols) { | ||
const auto backup = all(); | ||
cells.clear(); | ||
count = 0; | ||
cells.resize(rows * cols); | ||
|
||
this->rows = rows; | ||
this->cols = cols; | ||
|
||
cellSize = std::min(ceilf(HEIGHT / (float)rows), ceilf(WIDTH / (float)cols)); | ||
|
||
for (auto &asteroid : backup) { | ||
insert(asteroid); | ||
} | ||
} | ||
|
||
void SpatialHashGrid::insert(std::shared_ptr<Asteroid> asteroid) { | ||
auto index = getCellIndex(asteroid->position); | ||
asteroid->index = index; | ||
asteroid->color = cells[index].color; | ||
cells[index].asteroids.push_back(asteroid); | ||
count++; | ||
} | ||
|
||
void SpatialHashGrid::remove(std::shared_ptr<Asteroid> asteroid) { | ||
auto index = getCellIndex(asteroid->position); | ||
asteroid->index = -1; | ||
cells[index].asteroids.remove(asteroid); | ||
count--; | ||
} | ||
|
||
void SpatialHashGrid::update() { | ||
for (auto &cell : cells) { | ||
auto it = cell.asteroids.begin(); | ||
while (it != cell.asteroids.end()) { | ||
uint16_t index = getCellIndex(it->get()->position); | ||
if (index != it->get()->index) { | ||
it->get()->index = index; | ||
it->get()->color = cell.color; | ||
cells[index].asteroids.push_back(*it); | ||
it = cells[it->get()->index].asteroids.erase(it); | ||
} else { | ||
it++; | ||
} | ||
} | ||
} | ||
} | ||
|
||
std::vector<std::shared_ptr<Asteroid>> SpatialHashGrid::retrieve(raylib::Vector2 position, uint16_t radius) { | ||
// Get the adjacent cells based on the radius | ||
uint16_t startRow = std::max(0, (int)(position.y - radius) / cellSize); | ||
uint16_t endRow = std::min(rows - 1, (int)(position.y + radius) / cellSize); | ||
uint16_t startCol = std::max(0, (int)(position.x - radius) / cellSize); | ||
uint16_t endCol = std::min(cols - 1, (int)(position.x + radius) / cellSize); | ||
|
||
std::vector<std::shared_ptr<Asteroid>> result; | ||
for (uint16_t row = startRow; row <= endRow; row++) { | ||
for (uint16_t col = startCol; col <= endCol; col++) { | ||
uint16_t index = row * cols + col; | ||
for (auto &asteroid : cells[index].asteroids) { | ||
if (position.Distance(asteroid->position) <= radius) { | ||
result.push_back(asteroid); | ||
} | ||
} | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
|
||
std::vector<std::shared_ptr<Asteroid>> SpatialHashGrid::all() { | ||
std::vector<std::shared_ptr<Asteroid>> result; | ||
for (auto &cell : cells) { | ||
result.insert(result.end(), cell.asteroids.begin(), cell.asteroids.end()); | ||
} | ||
return result; | ||
} | ||
|
||
void SpatialHashGrid::render() { | ||
for (uint16_t row = 0; row < rows; row++) { | ||
for (uint16_t col = 0; col < cols; col++) { | ||
uint16_t index = row * cols + col; | ||
DrawRectangleLines(col * cellSize, row * cellSize, cellSize, cellSize, cells[index].color); | ||
DrawText(TextFormat("%d", index), col * cellSize + 5, row * cellSize + 5, 10, WHITE); | ||
} | ||
} | ||
} |
Oops, something went wrong.