Stash for ergo (not rly working)

This commit is contained in:
illyum 2024-09-18 22:16:03 -06:00
parent 496cc2ae8c
commit 7711daaeb5
7 changed files with 783 additions and 186 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
.cache/
build/
compile_commands.json
build-vs/

67
.vscode/settings.json vendored
View File

@ -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
}
}

View File

@ -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
View 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
View 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
View 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

191
main.cpp
View File

@ -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;
}