implement klotski graph closure solving + improve camera controls (panning)
This commit is contained in:
@ -3,23 +3,32 @@
|
||||
|
||||
#include <raylib.h>
|
||||
|
||||
constexpr int WIDTH = 800;
|
||||
constexpr int HEIGHT = 800;
|
||||
// Window
|
||||
constexpr int WIDTH = 1000;
|
||||
constexpr int HEIGHT = 1000;
|
||||
|
||||
constexpr float VERTEX_SIZE = 0.1;
|
||||
// Camera Controls
|
||||
constexpr float SIM_SPEED = 4.0;
|
||||
constexpr float CAMERA_DISTANCE = 4.0;
|
||||
constexpr float MIN_CAMERA_DISTANCE = 2.0;
|
||||
constexpr float MAX_CAMERA_DISTANCE = 50.0;
|
||||
constexpr float ZOOM_SPEED = 1.0;
|
||||
constexpr float PAN_SPEED = 1.0;
|
||||
constexpr float ROT_SPEED = 1.0;
|
||||
|
||||
// Physics Engine
|
||||
constexpr float SPRING_CONSTANT = 1.5;
|
||||
constexpr float DAMPENING_CONSTANT = 0.8;
|
||||
constexpr float REST_LENGTH = 1.0;
|
||||
constexpr float REPULSION_FORCE = 0.05;
|
||||
constexpr float VERLET_DAMPENING = 0.01; // [0, 1]
|
||||
|
||||
// Graph Drawing
|
||||
constexpr float VERTEX_SIZE = 0.05;
|
||||
constexpr Color VERTEX_COLOR = GREEN;
|
||||
constexpr Color EDGE_COLOR = DARKGREEN;
|
||||
|
||||
constexpr float SIM_SPEED = 4.0;
|
||||
constexpr float ROTATION_SPEED = 1.0;
|
||||
constexpr float CAMERA_DISTANCE = 2.2;
|
||||
constexpr float CULLING_TOLERANCE = 0.1; // percentage
|
||||
|
||||
constexpr float DEFAULT_SPRING_CONSTANT = 1.5;
|
||||
constexpr float DEFAULT_DAMPENING_CONSTANT = 0.1;
|
||||
constexpr float DEFAULT_REST_LENGTH = 0.5;
|
||||
constexpr float DEFAULT_REPULSION_FORCE = 0.01;
|
||||
|
||||
// Klotski Drawing
|
||||
constexpr int BOARD_PADDING = 5;
|
||||
constexpr int BLOCK_PADDING = 5;
|
||||
constexpr Color BLOCK_COLOR = DARKGREEN;
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
// #define DBG_PRINT
|
||||
@ -109,17 +110,17 @@ public:
|
||||
~Block() {}
|
||||
|
||||
public:
|
||||
auto Hash() -> int;
|
||||
auto Hash() const -> int;
|
||||
|
||||
static auto Invalid() -> Block const;
|
||||
static auto Invalid() -> Block;
|
||||
|
||||
auto IsValid() -> bool;
|
||||
auto IsValid() const -> bool;
|
||||
|
||||
auto ToString() -> std::string;
|
||||
auto ToString() const -> std::string;
|
||||
|
||||
auto Covers(int xx, int yy) -> bool;
|
||||
auto Covers(int xx, int yy) const -> bool;
|
||||
|
||||
auto Collides(const Block &other) -> bool;
|
||||
auto Collides(const Block &other) const -> bool;
|
||||
};
|
||||
|
||||
// A state is represented by a string "WxH:blocks", where W is the board width,
|
||||
@ -130,8 +131,8 @@ public:
|
||||
// block's pivot being its top-left corner.
|
||||
class State {
|
||||
public:
|
||||
int width;
|
||||
int height;
|
||||
const int width;
|
||||
const int height;
|
||||
std::string state;
|
||||
|
||||
// https://en.cppreference.com/w/cpp/iterator/input_iterator.html
|
||||
@ -214,24 +215,32 @@ public:
|
||||
|
||||
bool operator!=(const State &other) const { return !(*this == other); }
|
||||
|
||||
BlockIterator begin() { return BlockIterator(*this); }
|
||||
BlockIterator begin() const { return BlockIterator(*this); }
|
||||
|
||||
BlockIterator end() { return BlockIterator(*this, width * height); }
|
||||
BlockIterator end() const { return BlockIterator(*this, width * height); }
|
||||
|
||||
~State() {}
|
||||
|
||||
public:
|
||||
auto Hash() -> int;
|
||||
auto Hash() const -> int;
|
||||
|
||||
auto AddBlock(Block block) -> bool;
|
||||
|
||||
auto GetBlock(int x, int y) -> Block;
|
||||
auto GetBlock(int x, int y) const -> Block;
|
||||
|
||||
auto RemoveBlock(int x, int y) -> bool;
|
||||
|
||||
auto MoveBlockAt(int x, int y, Direction dir) -> bool;
|
||||
|
||||
auto GetNextStates() -> std::vector<State>;
|
||||
auto GetNextStates() const -> std::vector<State>;
|
||||
|
||||
auto Closure() const
|
||||
-> std::pair<std::unordered_set<std::string>,
|
||||
std::vector<std::pair<std::string, std::string>>>;
|
||||
};
|
||||
|
||||
template <> struct std::hash<State> {
|
||||
std::size_t operator()(const State &s) const noexcept { return s.Hash(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,21 +1,19 @@
|
||||
#ifndef __MASS_SPRINGS_HPP_
|
||||
#define __MASS_SPRINGS_HPP_
|
||||
|
||||
#include <cstddef>
|
||||
#include <raylib.h>
|
||||
#include <raymath.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
class Mass {
|
||||
public:
|
||||
float mass;
|
||||
const float mass;
|
||||
Vector3 position;
|
||||
Vector3 previous_position; // for verlet integration
|
||||
Vector3 velocity;
|
||||
Vector3 force;
|
||||
bool fixed;
|
||||
const bool fixed;
|
||||
|
||||
public:
|
||||
Mass(float mass, Vector3 position, bool fixed)
|
||||
@ -48,15 +46,13 @@ public:
|
||||
auto VerletUpdate(const float delta_time) -> void;
|
||||
};
|
||||
|
||||
using MassList = std::vector<Mass>;
|
||||
|
||||
class Spring {
|
||||
public:
|
||||
Mass &massA;
|
||||
Mass &massB;
|
||||
float spring_constant;
|
||||
float dampening_constant;
|
||||
float rest_length;
|
||||
const float spring_constant;
|
||||
const float dampening_constant;
|
||||
const float rest_length;
|
||||
|
||||
public:
|
||||
Spring(Mass &massA, Mass &massB, float spring_constant,
|
||||
@ -83,15 +79,13 @@ public:
|
||||
~Spring() {}
|
||||
|
||||
public:
|
||||
auto CalculateSpringForce() -> void;
|
||||
auto CalculateSpringForce() const -> void;
|
||||
};
|
||||
|
||||
using SpringList = std::vector<Spring>;
|
||||
|
||||
class MassSpringSystem {
|
||||
public:
|
||||
std::unordered_map<std::string, Mass> masses;
|
||||
SpringList springs;
|
||||
std::unordered_map<std::string, Spring> springs;
|
||||
|
||||
public:
|
||||
MassSpringSystem() {};
|
||||
@ -104,8 +98,8 @@ public:
|
||||
~MassSpringSystem() {};
|
||||
|
||||
public:
|
||||
auto AddMass(float mass, Vector3 position, bool fixed, std::string state)
|
||||
-> void;
|
||||
auto AddMass(float mass, Vector3 position, bool fixed,
|
||||
const std::string &state) -> void;
|
||||
|
||||
auto GetMass(const std::string &state) -> Mass &;
|
||||
|
||||
@ -121,9 +115,9 @@ public:
|
||||
|
||||
auto CalculateRepulsionForces() -> void;
|
||||
|
||||
auto EulerUpdate(const float delta_time) -> void;
|
||||
auto EulerUpdate(float delta_time) -> void;
|
||||
|
||||
auto VerletUpdate(const float delta_time) -> void;
|
||||
auto VerletUpdate(float delta_time) -> void;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -20,11 +20,13 @@ private:
|
||||
float angle_y;
|
||||
Vector2 last_mouse;
|
||||
bool dragging;
|
||||
bool panning;
|
||||
|
||||
public:
|
||||
OrbitCamera3D(Vector3 target, float distance)
|
||||
: camera({0}), target(target), distance(distance), angle_x(0.0),
|
||||
angle_y(0.3), last_mouse(Vector2Zero()), dragging(false) {
|
||||
angle_y(0.3), last_mouse(Vector2Zero()), dragging(false),
|
||||
panning(false) {
|
||||
camera.position = Vector3(0, 0, -1.0 * distance);
|
||||
camera.target = target;
|
||||
camera.up = Vector3(0, 1.0, 0);
|
||||
@ -40,8 +42,8 @@ public:
|
||||
|
||||
class Renderer {
|
||||
private:
|
||||
int width;
|
||||
int height;
|
||||
const int width;
|
||||
const int height;
|
||||
OrbitCamera3D camera;
|
||||
RenderTexture render_target;
|
||||
RenderTexture klotski_target;
|
||||
@ -69,8 +71,8 @@ public:
|
||||
|
||||
auto DrawMassSprings(const MassSpringSystem &masssprings) -> void;
|
||||
|
||||
auto DrawKlotski(State &state, int hov_x, int hov_y, int sel_x, int sel_y)
|
||||
-> void;
|
||||
auto DrawKlotski(const State &state, int hov_x, int hov_y, int sel_x,
|
||||
int sel_y) -> void;
|
||||
|
||||
auto DrawTextures() -> void;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user