Stash for ergo (not rly working)
This commit is contained in:
parent
496cc2ae8c
commit
7711daaeb5
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
.cache/
|
||||
build/
|
||||
compile_commands.json
|
||||
build-vs/
|
67
.vscode/settings.json
vendored
67
.vscode/settings.json
vendored
@ -1,5 +1,70 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"xiosbase": "cpp"
|
||||
"xiosbase": "cpp",
|
||||
"iostream": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"cctype": "cpp",
|
||||
"charconv": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"exception": "cpp",
|
||||
"format": "cpp",
|
||||
"functional": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"ios": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"istream": "cpp",
|
||||
"iterator": "cpp",
|
||||
"limits": "cpp",
|
||||
"list": "cpp",
|
||||
"locale": "cpp",
|
||||
"map": "cpp",
|
||||
"memory": "cpp",
|
||||
"new": "cpp",
|
||||
"optional": "cpp",
|
||||
"ostream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"string": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"utility": "cpp",
|
||||
"vector": "cpp",
|
||||
"xfacet": "cpp",
|
||||
"xhash": "cpp",
|
||||
"xlocale": "cpp",
|
||||
"xlocbuf": "cpp",
|
||||
"xlocinfo": "cpp",
|
||||
"xlocmes": "cpp",
|
||||
"xlocmon": "cpp",
|
||||
"xlocnum": "cpp",
|
||||
"xloctime": "cpp",
|
||||
"xmemory": "cpp",
|
||||
"xstring": "cpp",
|
||||
"xtr1common": "cpp",
|
||||
"xtree": "cpp",
|
||||
"xutility": "cpp"
|
||||
},
|
||||
"editor.formatOnSave": true,
|
||||
"C_Cpp.clang_format_style": "{BasedOnStyle: LLVM, BraceWrapping: {AfterControlStatement: false, AfterFunction: false, AfterEnum: true, AfterStruct: true}, AllowShortEnumsOnASingleLine: false}",
|
||||
"editor.tabSize": 4,
|
||||
"editor.insertSpaces": true,
|
||||
"[cpp]": {
|
||||
"editor.tabSize": 4,
|
||||
"editor.insertSpaces": true
|
||||
}
|
||||
}
|
@ -21,7 +21,7 @@ FetchContent_Declare(
|
||||
)
|
||||
FetchContent_MakeAvailable(imgui)
|
||||
|
||||
add_library(ImGui SHARED
|
||||
add_library(ImGui STATIC
|
||||
${imgui_SOURCE_DIR}/imgui.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_demo.cpp
|
||||
${imgui_SOURCE_DIR}/imgui_draw.cpp
|
||||
|
27
RubixSimulation.hpp
Normal file
27
RubixSimulation.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
|
||||
class RubixSimulation {
|
||||
public:
|
||||
virtual bool Init() = 0;
|
||||
virtual void Run() = 0;
|
||||
};
|
||||
|
||||
class RubixSimulationRunner {
|
||||
public:
|
||||
void SetSimulation(RubixSimulation *simulation) { sim = simulation; }
|
||||
void StartSimulation() {
|
||||
if (sim == nullptr) {
|
||||
std::cout << "No simulation has been set\n";
|
||||
return;
|
||||
}
|
||||
if (!sim->Init()) {
|
||||
std::cout << "There was an error creating simulation\n";
|
||||
}
|
||||
sim->Run();
|
||||
}
|
||||
|
||||
private:
|
||||
RubixSimulation *sim = nullptr;
|
||||
};
|
458
Sims/OOPCube.hpp
Normal file
458
Sims/OOPCube.hpp
Normal file
@ -0,0 +1,458 @@
|
||||
#pragma once
|
||||
|
||||
#include "../RubixSimulation.hpp"
|
||||
#include <raylib.h>
|
||||
#include <raymath.h>
|
||||
#include <rlgl.h>
|
||||
|
||||
namespace OOPCube {
|
||||
|
||||
struct VecTriangle {
|
||||
Vector3 pointOne;
|
||||
Vector3 pointTwo;
|
||||
Vector3 pointThree;
|
||||
};
|
||||
|
||||
struct Plane3D {
|
||||
VecTriangle one;
|
||||
VecTriangle two;
|
||||
Color color;
|
||||
};
|
||||
|
||||
struct CubeFace {
|
||||
Plane3D tiles[9]; // 3x3 tiles
|
||||
};
|
||||
|
||||
struct CubeRotation {
|
||||
bool rotating;
|
||||
float angle;
|
||||
Vector3 axis;
|
||||
CubeFace *face;
|
||||
};
|
||||
|
||||
struct RubixCubeFaces {
|
||||
CubeFace front;
|
||||
CubeFace right;
|
||||
CubeFace back;
|
||||
CubeFace left;
|
||||
CubeFace top;
|
||||
CubeFace bottom;
|
||||
};
|
||||
|
||||
class RubixCube {
|
||||
public:
|
||||
RubixCube() {
|
||||
float cubeSize = 3.0f;
|
||||
float faceOffset = cubeSize / 2.0f;
|
||||
|
||||
faces.front = CreateCubeFace({0.0f, 0.0f, -faceOffset}, {0.0f, 0.0f, 1.0f},
|
||||
cubeSize, GREEN);
|
||||
faces.back = CreateCubeFace({0.0f, 0.0f, faceOffset}, {0.0f, 0.0f, -1.0f},
|
||||
cubeSize, BLUE);
|
||||
faces.left = CreateCubeFace({-faceOffset, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f},
|
||||
cubeSize, ORANGE);
|
||||
faces.right = CreateCubeFace({faceOffset, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f},
|
||||
cubeSize, RED);
|
||||
faces.top = CreateCubeFace({0.0f, faceOffset, 0.0f}, {0.0f, -1.0f, 0.0f},
|
||||
cubeSize, YELLOW);
|
||||
faces.bottom = CreateCubeFace({0.0f, -faceOffset, 0.0f}, {0.0f, 1.0f, 0.0f},
|
||||
cubeSize, WHITE);
|
||||
}
|
||||
|
||||
void Draw(bool highlightFace = false, CubeFace *highlightedFace = nullptr) {
|
||||
if (highlightFace && highlightedFace != nullptr) {
|
||||
HighlightFace(highlightedFace);
|
||||
}
|
||||
DrawFace(&faces.front);
|
||||
DrawFace(&faces.back);
|
||||
DrawFace(&faces.left);
|
||||
DrawFace(&faces.right);
|
||||
DrawFace(&faces.top);
|
||||
DrawFace(&faces.bottom);
|
||||
}
|
||||
|
||||
void RotateFace(CubeFace *face, float angle, Vector3 axis) {
|
||||
CubeFace *neighbors[4]; // Holds adjacent faces
|
||||
GetFaceNeighbors(face, neighbors); // Get adjacent faces
|
||||
RotateLayer(face, angle, axis, neighbors); // Rotate both face and neighbors
|
||||
UpdateCubeState(face, neighbors,
|
||||
angle > 0); // Update the state after rotation
|
||||
}
|
||||
|
||||
CubeFace *GetFaceUnderMouse(Camera camera) {
|
||||
Ray mouseRay = GetMouseRay(GetMousePosition(), camera);
|
||||
CubeFace *face = nullptr;
|
||||
|
||||
if (CheckRayIntersectionWithFace(mouseRay, faces.front)) {
|
||||
face = &faces.front;
|
||||
} else if (CheckRayIntersectionWithFace(mouseRay, faces.back)) {
|
||||
face = &faces.back;
|
||||
} else if (CheckRayIntersectionWithFace(mouseRay, faces.left)) {
|
||||
face = &faces.left;
|
||||
} else if (CheckRayIntersectionWithFace(mouseRay, faces.right)) {
|
||||
face = &faces.right;
|
||||
} else if (CheckRayIntersectionWithFace(mouseRay, faces.top)) {
|
||||
face = &faces.top;
|
||||
} else if (CheckRayIntersectionWithFace(mouseRay, faces.bottom)) {
|
||||
face = &faces.bottom;
|
||||
}
|
||||
|
||||
return face;
|
||||
}
|
||||
|
||||
private:
|
||||
RubixCubeFaces faces;
|
||||
|
||||
void GetFaceNeighbors(CubeFace *face, CubeFace **neighbors) {
|
||||
// Map the neighbors of each face (order: top, right, bottom, left)
|
||||
if (face == &faces.front) {
|
||||
neighbors[0] = &faces.top;
|
||||
neighbors[1] = &faces.right;
|
||||
neighbors[2] = &faces.bottom;
|
||||
neighbors[3] = &faces.left;
|
||||
} else if (face == &faces.back) {
|
||||
neighbors[0] = &faces.top;
|
||||
neighbors[1] = &faces.left;
|
||||
neighbors[2] = &faces.bottom;
|
||||
neighbors[3] = &faces.right;
|
||||
} else if (face == &faces.left) {
|
||||
neighbors[0] = &faces.top;
|
||||
neighbors[1] = &faces.front;
|
||||
neighbors[2] = &faces.bottom;
|
||||
neighbors[3] = &faces.back;
|
||||
} else if (face == &faces.right) {
|
||||
neighbors[0] = &faces.top;
|
||||
neighbors[1] = &faces.back;
|
||||
neighbors[2] = &faces.bottom;
|
||||
neighbors[3] = &faces.front;
|
||||
} else if (face == &faces.top) {
|
||||
neighbors[0] = &faces.back;
|
||||
neighbors[1] = &faces.right;
|
||||
neighbors[2] = &faces.front;
|
||||
neighbors[3] = &faces.left;
|
||||
} else if (face == &faces.bottom) {
|
||||
neighbors[0] = &faces.front;
|
||||
neighbors[1] = &faces.right;
|
||||
neighbors[2] = &faces.back;
|
||||
neighbors[3] = &faces.left;
|
||||
}
|
||||
}
|
||||
|
||||
void RotateLayer(CubeFace *face, float angle, Vector3 axis,
|
||||
CubeFace **neighbors) {
|
||||
// Rotate the face itself
|
||||
RotateCubeFace(face, MatrixRotate(axis, angle));
|
||||
// Apply rotation to the neighboring rows/columns
|
||||
RotateNeighbors(face, angle, neighbors);
|
||||
}
|
||||
|
||||
void RotateNeighbors(CubeFace *rotatingFace, float angle,
|
||||
CubeFace **neighbors) {
|
||||
// Clockwise or counterclockwise based on angle
|
||||
bool clockwise = angle > 0.0f;
|
||||
|
||||
// Determine the layer based on the rotating face.
|
||||
// If front/back, rotate the middle horizontal row; otherwise, rotate the
|
||||
// vertical columns.
|
||||
if (rotatingFace == &faces.front || rotatingFace == &faces.back) {
|
||||
// Rotating the front or back face (affects top, right, bottom, and left
|
||||
// face)
|
||||
UpdateCubeState(rotatingFace, neighbors, clockwise);
|
||||
} else if (rotatingFace == &faces.left || rotatingFace == &faces.right) {
|
||||
// Rotating left or right face (affects top, front, bottom, and back face)
|
||||
UpdateCubeState(rotatingFace, neighbors, clockwise);
|
||||
} else if (rotatingFace == &faces.top || rotatingFace == &faces.bottom) {
|
||||
// Rotating top or bottom face (affects front, right, back, and left face)
|
||||
UpdateCubeState(rotatingFace, neighbors, clockwise);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateCubeState(CubeFace *face, CubeFace **neighbors, bool clockwise) {
|
||||
// Swapping tiles based on clockwise or counterclockwise rotation
|
||||
|
||||
if (face == &faces.front || face == &faces.back) {
|
||||
// Swap rows for front or back face rotation
|
||||
if (clockwise) {
|
||||
// Rotate clockwise: top->right, right->bottom, bottom->left, left->top
|
||||
SwapRows(neighbors[0], neighbors[1], neighbors[2], neighbors[3], 2,
|
||||
true);
|
||||
} else {
|
||||
// Rotate counter-clockwise: top->left, left->bottom, bottom->right,
|
||||
// right->top
|
||||
SwapRows(neighbors[0], neighbors[3], neighbors[2], neighbors[1], 2,
|
||||
false);
|
||||
}
|
||||
} else if (face == &faces.left || face == &faces.right) {
|
||||
// Swap columns for left or right face rotation
|
||||
if (clockwise) {
|
||||
// Rotate clockwise: top->front, front->bottom, bottom->back, back->top
|
||||
SwapColumns(neighbors[0], neighbors[1], neighbors[2], neighbors[3], 0,
|
||||
true);
|
||||
} else {
|
||||
// Rotate counter-clockwise: top->back, back->bottom, bottom->front,
|
||||
// front->top
|
||||
SwapColumns(neighbors[0], neighbors[3], neighbors[2], neighbors[1], 0,
|
||||
false);
|
||||
}
|
||||
} else if (face == &faces.top || face == &faces.bottom) {
|
||||
// Swap rows for top or bottom face rotation
|
||||
if (clockwise) {
|
||||
// Rotate clockwise: front->right, right->back, back->left, left->front
|
||||
SwapRows(neighbors[0], neighbors[1], neighbors[2], neighbors[3], 0,
|
||||
true);
|
||||
} else {
|
||||
// Rotate counter-clockwise: front->left, left->back, back->right,
|
||||
// right->front
|
||||
SwapRows(neighbors[0], neighbors[3], neighbors[2], neighbors[1], 0,
|
||||
false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to swap rows (used when rotating top/bottom or front/back)
|
||||
void SwapRows(CubeFace *top, CubeFace *right, CubeFace *bottom,
|
||||
CubeFace *left, int rowIndex, bool clockwise) {
|
||||
Plane3D tempRow[3];
|
||||
|
||||
// Store top row temporarily
|
||||
for (int i = 0; i < 3; i++) {
|
||||
tempRow[i] = top->tiles[rowIndex * 3 + i];
|
||||
}
|
||||
|
||||
// Swap rows based on direction
|
||||
if (clockwise) {
|
||||
// Top -> Right -> Bottom -> Left -> Top
|
||||
for (int i = 0; i < 3; i++) {
|
||||
top->tiles[rowIndex * 3 + i] = left->tiles[rowIndex * 3 + i];
|
||||
left->tiles[rowIndex * 3 + i] = bottom->tiles[rowIndex * 3 + i];
|
||||
bottom->tiles[rowIndex * 3 + i] = right->tiles[rowIndex * 3 + i];
|
||||
right->tiles[rowIndex * 3 + i] = tempRow[i];
|
||||
}
|
||||
} else {
|
||||
// Top -> Left -> Bottom -> Right -> Top
|
||||
for (int i = 0; i < 3; i++) {
|
||||
top->tiles[rowIndex * 3 + i] = right->tiles[rowIndex * 3 + i];
|
||||
right->tiles[rowIndex * 3 + i] = bottom->tiles[rowIndex * 3 + i];
|
||||
bottom->tiles[rowIndex * 3 + i] = left->tiles[rowIndex * 3 + i];
|
||||
left->tiles[rowIndex * 3 + i] = tempRow[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SwapColumns(CubeFace *top, CubeFace *front, CubeFace *bottom,
|
||||
CubeFace *back, int colIndex, bool clockwise) {
|
||||
Plane3D tempCol[3];
|
||||
|
||||
// Store top column temporarily
|
||||
for (int i = 0; i < 3; i++) {
|
||||
tempCol[i] = top->tiles[i * 3 + colIndex];
|
||||
}
|
||||
|
||||
// Swap columns based on direction
|
||||
if (clockwise) {
|
||||
// Top -> Front -> Bottom -> Back -> Top
|
||||
for (int i = 0; i < 3; i++) {
|
||||
top->tiles[i * 3 + colIndex] = back->tiles[i * 3 + colIndex];
|
||||
back->tiles[i * 3 + colIndex] = bottom->tiles[i * 3 + colIndex];
|
||||
bottom->tiles[i * 3 + colIndex] = front->tiles[i * 3 + colIndex];
|
||||
front->tiles[i * 3 + colIndex] = tempCol[i];
|
||||
}
|
||||
} else {
|
||||
// Top -> Back -> Bottom -> Front -> Top
|
||||
for (int i = 0; i < 3; i++) {
|
||||
top->tiles[i * 3 + colIndex] = front->tiles[i * 3 + colIndex];
|
||||
front->tiles[i * 3 + colIndex] = bottom->tiles[i * 3 + colIndex];
|
||||
bottom->tiles[i * 3 + colIndex] = back->tiles[i * 3 + colIndex];
|
||||
back->tiles[i * 3 + colIndex] = tempCol[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RotateCubeFace(CubeFace *face, Matrix rotationMatrix) {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
RotatePlane3D(&face->tiles[i], rotationMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
void RotatePlane3D(Plane3D *plane, Matrix rotationMatrix) {
|
||||
plane->one.pointOne = Vector3Transform(plane->one.pointOne, rotationMatrix);
|
||||
plane->one.pointTwo = Vector3Transform(plane->one.pointTwo, rotationMatrix);
|
||||
plane->one.pointThree =
|
||||
Vector3Transform(plane->one.pointThree, rotationMatrix);
|
||||
plane->two.pointOne = Vector3Transform(plane->two.pointOne, rotationMatrix);
|
||||
plane->two.pointTwo = Vector3Transform(plane->two.pointTwo, rotationMatrix);
|
||||
plane->two.pointThree =
|
||||
Vector3Transform(plane->two.pointThree, rotationMatrix);
|
||||
}
|
||||
|
||||
void HighlightFace(CubeFace *face) { DrawFace(face, true); }
|
||||
|
||||
void DrawFace(CubeFace *face, bool highlight = false) {
|
||||
Color faceColor = highlight ? LIGHTGRAY : face->tiles[0].color;
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
DrawPlane3D(&face->tiles[i]);
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckRayIntersectionWithFace(Ray ray, CubeFace face) {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
if (CheckRayCollision(ray, face.tiles[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckRayCollision(Ray ray, Plane3D plane) {
|
||||
RayCollision collisionOne = GetRayCollisionTriangle(
|
||||
ray, plane.one.pointOne, plane.one.pointTwo, plane.one.pointThree);
|
||||
RayCollision collisionTwo = GetRayCollisionTriangle(
|
||||
ray, plane.two.pointOne, plane.two.pointTwo, plane.two.pointThree);
|
||||
|
||||
return collisionOne.hit || collisionTwo.hit;
|
||||
}
|
||||
|
||||
Plane3D CreatePlane3D(float width, float height, Vector3 position,
|
||||
Color color, Vector3 normal, float scale) {
|
||||
Plane3D plane3D;
|
||||
plane3D.color = color;
|
||||
|
||||
Vector3 right, up;
|
||||
|
||||
if (Vector3Equals(normal, {0.0f, 1.0f, 0.0f}) ||
|
||||
Vector3Equals(normal, {0.0f, -1.0f, 0.0f})) {
|
||||
right = {1.0f, 0.0f, 0.0f};
|
||||
up = {0.0f, 0.0f, (normal.y > 0.0f) ? -1.0f : 1.0f};
|
||||
} else {
|
||||
right = {normal.z, 0.0f, -normal.x};
|
||||
up = {0.0f, 1.0f, 0.0f};
|
||||
}
|
||||
|
||||
float scaledWidth = width * scale;
|
||||
float scaledHeight = height * scale;
|
||||
|
||||
plane3D.one.pointOne =
|
||||
Vector3Add(position, Vector3Add(Vector3Scale(right, -scaledWidth / 2),
|
||||
Vector3Scale(up, -scaledHeight / 2)));
|
||||
plane3D.one.pointTwo =
|
||||
Vector3Add(position, Vector3Add(Vector3Scale(right, scaledWidth / 2),
|
||||
Vector3Scale(up, -scaledHeight / 2)));
|
||||
plane3D.one.pointThree =
|
||||
Vector3Add(position, Vector3Add(Vector3Scale(right, -scaledWidth / 2),
|
||||
Vector3Scale(up, scaledHeight / 2)));
|
||||
|
||||
plane3D.two.pointOne =
|
||||
Vector3Add(position, Vector3Add(Vector3Scale(right, scaledWidth / 2),
|
||||
Vector3Scale(up, -scaledHeight / 2)));
|
||||
plane3D.two.pointTwo =
|
||||
Vector3Add(position, Vector3Add(Vector3Scale(right, scaledWidth / 2),
|
||||
Vector3Scale(up, scaledHeight / 2)));
|
||||
plane3D.two.pointThree =
|
||||
Vector3Add(position, Vector3Add(Vector3Scale(right, -scaledWidth / 2),
|
||||
Vector3Scale(up, scaledHeight / 2)));
|
||||
|
||||
return plane3D;
|
||||
}
|
||||
|
||||
CubeFace CreateCubeFace(Vector3 center, Vector3 normal, float cubeSize,
|
||||
Color faceColor) {
|
||||
CubeFace face;
|
||||
|
||||
float tileSize = cubeSize / 3.0f;
|
||||
float halfSize = cubeSize / 2.0f;
|
||||
|
||||
Vector3 right = Vector3CrossProduct(normal, {0.0f, 1.0f, 0.0f});
|
||||
if (Vector3Length(right) == 0) {
|
||||
right = {1.0f, 0.0f, 0.0f};
|
||||
}
|
||||
|
||||
Vector3 up = Vector3CrossProduct(right, normal);
|
||||
Vector3 tileCenters[3][3];
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
tileCenters[i][j] = Vector3Add(
|
||||
center, Vector3Add(Vector3Scale(right, (i - 1) * tileSize),
|
||||
Vector3Scale(up, (j - 1) * tileSize)));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
face.tiles[i] =
|
||||
CreatePlane3D(tileSize, tileSize, tileCenters[i / 3][i % 3],
|
||||
faceColor, normal, 1.0f);
|
||||
}
|
||||
|
||||
return face;
|
||||
}
|
||||
|
||||
void DrawPlane3D(Plane3D *plane) {
|
||||
DrawTriangle3D(plane->one.pointOne, plane->one.pointTwo,
|
||||
plane->one.pointThree, plane->color);
|
||||
DrawTriangle3D(plane->two.pointOne, plane->two.pointTwo,
|
||||
plane->two.pointThree, plane->color);
|
||||
}
|
||||
};
|
||||
|
||||
class OOPCube : public RubixSimulation {
|
||||
public:
|
||||
bool Init() override {
|
||||
camera = {0};
|
||||
camera.position = {4.0f, 4.0f, 4.0f};
|
||||
camera.target = {0.0f, 0.0f, 0.0f};
|
||||
camera.up = {0.0f, 1.0f, 0.0f};
|
||||
camera.fovy = 45.0f;
|
||||
camera.projection = CAMERA_PERSPECTIVE;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Run() override {
|
||||
SetConfigFlags(FLAG_VSYNC_HINT);
|
||||
InitWindow(1920, 1080, "OOP Cube Simulation");
|
||||
|
||||
DisableCursor();
|
||||
rlDisableBackfaceCulling();
|
||||
bool isControllingCamera = false;
|
||||
|
||||
while (!WindowShouldClose()) {
|
||||
if (IsKeyPressed(KEY_SPACE)) {
|
||||
isControllingCamera = !isControllingCamera;
|
||||
}
|
||||
|
||||
if (isControllingCamera) {
|
||||
HideCursor();
|
||||
UpdateCamera(&camera, CAMERA_FREE);
|
||||
SetMousePosition(GetScreenWidth() / 2, GetScreenHeight() / 2);
|
||||
}
|
||||
BeginDrawing();
|
||||
ClearBackground(GRAY);
|
||||
ShowCursor();
|
||||
|
||||
BeginMode3D(camera);
|
||||
DrawGrid(10, 1.0f);
|
||||
|
||||
CubeFace *faceUnderMouse = cube.GetFaceUnderMouse(camera);
|
||||
if (faceUnderMouse != nullptr) {
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) {
|
||||
cube.RotateFace(faceUnderMouse, PI / 2.0f, {0.0f, 1.0f, 0.0f});
|
||||
} else if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) {
|
||||
cube.RotateFace(faceUnderMouse, -PI / 2.0f, {0.0f, 1.0f, 0.0f});
|
||||
}
|
||||
cube.Draw(true, faceUnderMouse);
|
||||
} else {
|
||||
cube.Draw();
|
||||
}
|
||||
|
||||
EndMode3D();
|
||||
|
||||
EndDrawing();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Camera camera;
|
||||
RubixCube cube;
|
||||
};
|
||||
} // namespace OOPCube
|
221
Sims/RlImGuiSim.hpp
Normal file
221
Sims/RlImGuiSim.hpp
Normal file
@ -0,0 +1,221 @@
|
||||
#pragma once
|
||||
|
||||
#include "../RubixSimulation.hpp"
|
||||
#include "imgui.h"
|
||||
#include "rlImGui.h"
|
||||
#include <raylib.h>
|
||||
#include <raymath.h>
|
||||
#include <rlgl.h>
|
||||
|
||||
namespace RlImGuiSim {
|
||||
enum CubeFace {
|
||||
FRONT = 0,
|
||||
RIGHT,
|
||||
BACK,
|
||||
LEFT,
|
||||
BOTTOM,
|
||||
TOP
|
||||
};
|
||||
|
||||
struct VecTriangle {
|
||||
Vector3 pointOne;
|
||||
Vector3 pointTwo;
|
||||
Vector3 pointThree;
|
||||
};
|
||||
|
||||
struct Plane3D {
|
||||
VecTriangle one;
|
||||
VecTriangle two;
|
||||
Color color;
|
||||
};
|
||||
|
||||
struct RubixCube {
|
||||
Plane3D faces[6][9];
|
||||
Vector3 pos;
|
||||
};
|
||||
|
||||
class RlImGuiSim : public RubixSimulation {
|
||||
public:
|
||||
bool Init() override { return true; }
|
||||
void Run() override {
|
||||
SetConfigFlags(FLAG_VSYNC_HINT);
|
||||
InitWindow(1920, 1080, "Rubix Cube");
|
||||
|
||||
DisableCursor();
|
||||
|
||||
Camera3D cam = {0};
|
||||
cam.position = {10.0f, 10.0f, 10.0f};
|
||||
cam.target = {0.0f, 0.0f, 0.0f};
|
||||
cam.up = {0.0f, 1.0f, 0.0f};
|
||||
cam.fovy = 45.0f;
|
||||
cam.projection = CAMERA_PERSPECTIVE;
|
||||
|
||||
float cubeSize = 3.0f;
|
||||
float previousCubeSize = cubeSize;
|
||||
float planeScale = 1.0f;
|
||||
|
||||
RubixCube cube = CreateRubixCube({0.0f, 0.0f, 0.0f}, cubeSize, planeScale);
|
||||
|
||||
// Disable backface culling
|
||||
rlDisableBackfaceCulling();
|
||||
|
||||
// Setup ImGui
|
||||
rlImGuiSetup(true);
|
||||
|
||||
bool isControllingCamera = true;
|
||||
|
||||
while (!WindowShouldClose()) {
|
||||
if (IsKeyPressed(KEY_SPACE))
|
||||
isControllingCamera = !isControllingCamera;
|
||||
if (isControllingCamera)
|
||||
UpdateCamera(&cam, CAMERA_FREE);
|
||||
if (!isControllingCamera)
|
||||
DrawText("Camera paused", 10, 10, 32, BLACK);
|
||||
|
||||
BeginDrawing();
|
||||
ClearBackground(GRAY);
|
||||
|
||||
rlImGuiBegin();
|
||||
ImGui::Begin("Controls");
|
||||
ImGui::SliderFloat("Cube Size", &cubeSize, 1.0f, 10.0f);
|
||||
ImGui::SliderFloat("Plane Scale", &planeScale, 0.1f, 1.0f);
|
||||
ImGui::End();
|
||||
rlImGuiEnd();
|
||||
|
||||
if (cubeSize != previousCubeSize || planeScale != 1.0f) {
|
||||
cube = CreateRubixCube({0.0f, 0.0f, 0.0f}, cubeSize, planeScale);
|
||||
previousCubeSize = cubeSize;
|
||||
}
|
||||
|
||||
BeginMode3D(cam);
|
||||
|
||||
DrawRubixCube(&cube);
|
||||
|
||||
DrawGrid(10, 1.0f);
|
||||
|
||||
EndMode3D();
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
rlImGuiShutdown();
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
void DrawRubixCube(RubixCube *cube) {
|
||||
rlDisableBackfaceCulling();
|
||||
for (int face = 0; face < 6; face++) {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
DrawPlane3D(&cube->faces[face][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RubixCube CreateRubixCube(Vector3 position, float size, float planeScale) {
|
||||
RubixCube cube;
|
||||
cube.pos = position;
|
||||
|
||||
float planeSize = size / 3.0f;
|
||||
int faceIndex;
|
||||
|
||||
for (int face = 0; face < 6; face++) {
|
||||
faceIndex = 0;
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
for (int y = -1; y <= 1; y++) {
|
||||
Vector3 planePos = {position.x + x * planeSize,
|
||||
position.y + y * planeSize, position.z};
|
||||
|
||||
switch (face) {
|
||||
case FRONT:
|
||||
planePos = {position.x + x * planeSize, position.y + y * planeSize,
|
||||
position.z + size / 2};
|
||||
cube.faces[face][faceIndex++] = CreatePlane3D(
|
||||
planeSize, planeSize, planePos, RED, {0, 0, 1}, planeScale);
|
||||
break;
|
||||
case BACK:
|
||||
planePos = {position.x + x * planeSize, position.y + y * planeSize,
|
||||
position.z - size / 2};
|
||||
cube.faces[face][faceIndex++] = CreatePlane3D(
|
||||
planeSize, planeSize, planePos, ORANGE, {0, 0, -1}, planeScale);
|
||||
break;
|
||||
case LEFT:
|
||||
planePos = {position.x - size / 2, position.y + y * planeSize,
|
||||
position.z + x * planeSize};
|
||||
cube.faces[face][faceIndex++] = CreatePlane3D(
|
||||
planeSize, planeSize, planePos, BLUE, {-1, 0, 0}, planeScale);
|
||||
break;
|
||||
case RIGHT:
|
||||
planePos = {position.x + size / 2, position.y + y * planeSize,
|
||||
position.z + x * planeSize};
|
||||
cube.faces[face][faceIndex++] = CreatePlane3D(
|
||||
planeSize, planeSize, planePos, GREEN, {1, 0, 0}, planeScale);
|
||||
break;
|
||||
case TOP:
|
||||
planePos = {position.x + x * planeSize, position.y + size / 2,
|
||||
position.z + y * planeSize};
|
||||
cube.faces[face][faceIndex++] = CreatePlane3D(
|
||||
planeSize, planeSize, planePos, YELLOW, {0, 1, 0}, planeScale);
|
||||
break;
|
||||
case BOTTOM:
|
||||
planePos = {position.x + x * planeSize, position.y - size / 2,
|
||||
position.z + y * planeSize};
|
||||
cube.faces[face][faceIndex++] = CreatePlane3D(
|
||||
planeSize, planeSize, planePos, WHITE, {0, -1, 0}, planeScale);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cube;
|
||||
}
|
||||
|
||||
void DrawPlane3D(Plane3D *plane) {
|
||||
DrawTriangle3D(plane->one.pointOne, plane->one.pointTwo,
|
||||
plane->one.pointThree, plane->color);
|
||||
DrawTriangle3D(plane->two.pointOne, plane->two.pointTwo,
|
||||
plane->two.pointThree, plane->color);
|
||||
}
|
||||
|
||||
Plane3D CreatePlane3D(float width, float height, Vector3 position,
|
||||
Color color, Vector3 normal, float scale) {
|
||||
Plane3D plane3D;
|
||||
plane3D.color = color;
|
||||
|
||||
Vector3 right, up;
|
||||
|
||||
if (Vector3Equals(normal, {0.0f, 1.0f, 0.0f}) ||
|
||||
Vector3Equals(normal, {0.0f, -1.0f, 0.0f})) {
|
||||
right = {1.0f, 0.0f, 0.0f};
|
||||
up = {0.0f, 0.0f, (normal.y > 0.0f) ? -1.0f : 1.0f};
|
||||
} else {
|
||||
right = {normal.z, 0.0f, -normal.x};
|
||||
up = {0.0f, 1.0f, 0.0f};
|
||||
}
|
||||
|
||||
float scaledWidth = width * scale;
|
||||
float scaledHeight = height * scale;
|
||||
|
||||
plane3D.one.pointOne =
|
||||
Vector3Add(Vector3Add(position, Vector3Scale(right, -scaledWidth / 2)),
|
||||
Vector3Scale(up, -scaledHeight / 2));
|
||||
plane3D.one.pointTwo =
|
||||
Vector3Add(Vector3Add(position, Vector3Scale(right, scaledWidth / 2)),
|
||||
Vector3Scale(up, -scaledHeight / 2));
|
||||
plane3D.one.pointThree =
|
||||
Vector3Add(Vector3Add(position, Vector3Scale(right, -scaledWidth / 2)),
|
||||
Vector3Scale(up, scaledHeight / 2));
|
||||
|
||||
plane3D.two.pointOne =
|
||||
Vector3Add(Vector3Add(position, Vector3Scale(right, scaledWidth / 2)),
|
||||
Vector3Scale(up, -scaledHeight / 2));
|
||||
plane3D.two.pointTwo =
|
||||
Vector3Add(Vector3Add(position, Vector3Scale(right, scaledWidth / 2)),
|
||||
Vector3Scale(up, scaledHeight / 2));
|
||||
plane3D.two.pointThree =
|
||||
Vector3Add(Vector3Add(position, Vector3Scale(right, -scaledWidth / 2)),
|
||||
Vector3Scale(up, scaledHeight / 2));
|
||||
|
||||
return plane3D;
|
||||
}
|
||||
};
|
||||
} // namespace RlImGuiSim
|
193
main.cpp
193
main.cpp
@ -1,187 +1,12 @@
|
||||
#include <raylib.h>
|
||||
#include <raymath.h>
|
||||
#include <rlgl.h>
|
||||
#include "rlImGui.h"
|
||||
#include "imgui.h"
|
||||
|
||||
enum CubeFace {
|
||||
FRONT = 0,
|
||||
RIGHT,
|
||||
BACK,
|
||||
LEFT,
|
||||
BOTTOM,
|
||||
TOP
|
||||
};
|
||||
|
||||
struct VecTriangle {
|
||||
Vector3 pointOne;
|
||||
Vector3 pointTwo;
|
||||
Vector3 pointThree;
|
||||
};
|
||||
|
||||
struct Plane3D {
|
||||
VecTriangle one;
|
||||
VecTriangle two;
|
||||
Color color;
|
||||
};
|
||||
|
||||
struct RubixCube {
|
||||
Plane3D faces[6][9];
|
||||
Vector3 pos;
|
||||
};
|
||||
|
||||
void DrawRubixCube(RubixCube* cube);
|
||||
void DrawPlane3D(Plane3D* plane);
|
||||
Plane3D CreatePlane3D(float width, float height, Vector3 position, Color color, Vector3 normal, float scale);
|
||||
RubixCube CreateRubixCube(Vector3 position, float size, float planeScale);
|
||||
#include "Sims/OOPCube.hpp"
|
||||
#include "Sims/RlImGuiSim.hpp"
|
||||
|
||||
int main() {
|
||||
SetConfigFlags(FLAG_VSYNC_HINT);
|
||||
InitWindow(1920, 1080, "Rubix Cube");
|
||||
RubixSimulationRunner simRunner;
|
||||
RlImGuiSim::RlImGuiSim rlImGuiSim;
|
||||
OOPCube::OOPCube oopCube;
|
||||
simRunner.SetSimulation(&oopCube);
|
||||
simRunner.StartSimulation();
|
||||
|
||||
DisableCursor();
|
||||
|
||||
Camera3D cam = { 0 };
|
||||
cam.position = { 10.0f, 10.0f, 10.0f };
|
||||
cam.target = { 0.0f, 0.0f, 0.0f };
|
||||
cam.up = { 0.0f, 1.0f, 0.0f };
|
||||
cam.fovy = 45.0f;
|
||||
cam.projection = CAMERA_PERSPECTIVE;
|
||||
|
||||
float cubeSize = 3.0f;
|
||||
float previousCubeSize = cubeSize;
|
||||
float planeScale = 1.0f;
|
||||
|
||||
RubixCube cube = CreateRubixCube({0.0f, 0.0f, 0.0f}, cubeSize, planeScale);
|
||||
|
||||
// Disable backface culling
|
||||
rlDisableBackfaceCulling();
|
||||
|
||||
// Setup ImGui
|
||||
rlImGuiSetup(true);
|
||||
|
||||
bool isControllingCamera = true;
|
||||
|
||||
while (!WindowShouldClose()) {
|
||||
if (IsKeyPressed(KEY_SPACE)) isControllingCamera = !isControllingCamera;
|
||||
if (isControllingCamera) UpdateCamera(&cam, CAMERA_FREE);
|
||||
if (!isControllingCamera) DrawText("Camera paused", 10, 10, 32, BLACK);
|
||||
|
||||
BeginDrawing();
|
||||
ClearBackground(GRAY);
|
||||
|
||||
rlImGuiBegin();
|
||||
ImGui::Begin("Controls");
|
||||
ImGui::SliderFloat("Cube Size", &cubeSize, 1.0f, 10.0f);
|
||||
ImGui::SliderFloat("Plane Scale", &planeScale, 0.1f, 1.0f);
|
||||
ImGui::End();
|
||||
rlImGuiEnd();
|
||||
|
||||
if (cubeSize != previousCubeSize || planeScale != 1.0f) {
|
||||
cube = CreateRubixCube({0.0f, 0.0f, 0.0f}, cubeSize, planeScale);
|
||||
previousCubeSize = cubeSize;
|
||||
}
|
||||
|
||||
BeginMode3D(cam);
|
||||
|
||||
DrawRubixCube(&cube);
|
||||
|
||||
DrawGrid(10, 1.0f);
|
||||
|
||||
EndMode3D();
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
rlImGuiShutdown();
|
||||
CloseWindow();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DrawRubixCube(RubixCube* cube) {
|
||||
rlDisableBackfaceCulling();
|
||||
for (int face = 0; face < 6; face++) {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
DrawPlane3D(&cube->faces[face][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RubixCube CreateRubixCube(Vector3 position, float size, float planeScale) {
|
||||
RubixCube cube;
|
||||
cube.pos = position;
|
||||
|
||||
float planeSize = size / 3.0f;
|
||||
int faceIndex;
|
||||
|
||||
for (int face = 0; face < 6; face++) {
|
||||
faceIndex = 0;
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
for (int y = -1; y <= 1; y++) {
|
||||
Vector3 planePos = { position.x + x * planeSize, position.y + y * planeSize, position.z };
|
||||
|
||||
switch (face) {
|
||||
case FRONT:
|
||||
planePos = { position.x + x * planeSize, position.y + y * planeSize, position.z + size / 2 };
|
||||
cube.faces[face][faceIndex++] = CreatePlane3D(planeSize, planeSize, planePos, RED, {0, 0, 1}, planeScale);
|
||||
break;
|
||||
case BACK:
|
||||
planePos = { position.x + x * planeSize, position.y + y * planeSize, position.z - size / 2 };
|
||||
cube.faces[face][faceIndex++] = CreatePlane3D(planeSize, planeSize, planePos, ORANGE, {0, 0, -1}, planeScale);
|
||||
break;
|
||||
case LEFT:
|
||||
planePos = { position.x - size / 2, position.y + y * planeSize, position.z + x * planeSize };
|
||||
cube.faces[face][faceIndex++] = CreatePlane3D(planeSize, planeSize, planePos, BLUE, {-1, 0, 0}, planeScale);
|
||||
break;
|
||||
case RIGHT:
|
||||
planePos = { position.x + size / 2, position.y + y * planeSize, position.z + x * planeSize };
|
||||
cube.faces[face][faceIndex++] = CreatePlane3D(planeSize, planeSize, planePos, GREEN, {1, 0, 0}, planeScale);
|
||||
break;
|
||||
case TOP:
|
||||
planePos = { position.x + x * planeSize, position.y + size / 2, position.z + y * planeSize };
|
||||
cube.faces[face][faceIndex++] = CreatePlane3D(planeSize, planeSize, planePos, YELLOW, {0, 1, 0}, planeScale);
|
||||
break;
|
||||
case BOTTOM:
|
||||
planePos = { position.x + x * planeSize, position.y - size / 2, position.z + y * planeSize };
|
||||
cube.faces[face][faceIndex++] = CreatePlane3D(planeSize, planeSize, planePos, WHITE, {0, -1, 0}, planeScale);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cube;
|
||||
}
|
||||
|
||||
void DrawPlane3D(Plane3D* plane) {
|
||||
DrawTriangle3D(plane->one.pointOne, plane->one.pointTwo, plane->one.pointThree, plane->color);
|
||||
DrawTriangle3D(plane->two.pointOne, plane->two.pointTwo, plane->two.pointThree, plane->color);
|
||||
}
|
||||
|
||||
Plane3D CreatePlane3D(float width, float height, Vector3 position, Color color, Vector3 normal, float scale) {
|
||||
Plane3D plane3D;
|
||||
plane3D.color = color;
|
||||
|
||||
Vector3 right, up;
|
||||
|
||||
if (Vector3Equals(normal, {0, 1, 0}) || Vector3Equals(normal, {0, -1, 0})) {
|
||||
right = {1, 0, 0};
|
||||
up = {0, 0, (normal.y > 0) ? -1 : 1};
|
||||
} else {
|
||||
right = {normal.z, 0, -normal.x};
|
||||
up = {0, 1, 0};
|
||||
}
|
||||
|
||||
float scaledWidth = width * scale;
|
||||
float scaledHeight = height * scale;
|
||||
|
||||
plane3D.one.pointOne = Vector3Add(Vector3Add(position, Vector3Scale(right, -scaledWidth / 2)), Vector3Scale(up, -scaledHeight / 2));
|
||||
plane3D.one.pointTwo = Vector3Add(Vector3Add(position, Vector3Scale(right, scaledWidth / 2)), Vector3Scale(up, -scaledHeight / 2));
|
||||
plane3D.one.pointThree = Vector3Add(Vector3Add(position, Vector3Scale(right, -scaledWidth / 2)), Vector3Scale(up, scaledHeight / 2));
|
||||
|
||||
plane3D.two.pointOne = Vector3Add(Vector3Add(position, Vector3Scale(right, scaledWidth / 2)), Vector3Scale(up, -scaledHeight / 2));
|
||||
plane3D.two.pointTwo = Vector3Add(Vector3Add(position, Vector3Scale(right, scaledWidth / 2)), Vector3Scale(up, scaledHeight / 2));
|
||||
plane3D.two.pointThree = Vector3Add(Vector3Add(position, Vector3Scale(right, -scaledWidth / 2)), Vector3Scale(up, scaledHeight / 2));
|
||||
|
||||
return plane3D;
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user