222 lines
6.5 KiB
C++
222 lines
6.5 KiB
C++
#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
|