commit for push
This commit is contained in:
@@ -39,6 +39,7 @@ namespace Archimedes {
|
||||
glm::vec3 moveTo(glm::vec3 pos) {
|
||||
worldTransform = glm::translate(worldTransform, pos - position);
|
||||
position = pos;
|
||||
//position = glm::vec3(worldTransform[3][0], worldTransform[3][1], worldTransform[3][2]);
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
@@ -73,10 +73,11 @@ void Rubiks::onLoad() {
|
||||
|
||||
void Rubiks::run() {
|
||||
|
||||
static float scale = 0.8f, scalePrev = 1.0f;
|
||||
static float scale = 0.96f;
|
||||
//static float scalePrev = 1.0f;
|
||||
|
||||
static glm::vec3 pos(0), rot(0);
|
||||
static glm::vec3 posPrev(0), rotPrev(0);
|
||||
//static glm::vec3 posPrev(0), rotPrev(0);
|
||||
|
||||
static glm::vec3 camPos(0.0f, 0.0f, 10.0f), camRot(0.0f, glm::pi<float>(), 0.0f);
|
||||
static glm::vec3 camPosPrev(0.0f, 0.0f, 10.0f), camRotPrev(0.0f, glm::pi<float>(), 0.0f);
|
||||
@@ -97,11 +98,12 @@ void Rubiks::run() {
|
||||
camPosPrev = camPos;
|
||||
camRotPrev = camRot;
|
||||
|
||||
|
||||
for(auto& b : rubiksCube.getBlocks()) {
|
||||
b.scaleTo(scale);
|
||||
b.body.scaleTo(scale);
|
||||
window->getRenderer()->draw(
|
||||
b.getMesh(),
|
||||
b.getTransform(),
|
||||
b.body.getMesh(),
|
||||
b.body.getTransform(),
|
||||
camera.getTransform(),
|
||||
camera.getPerspective(),
|
||||
color
|
||||
@@ -144,6 +146,27 @@ void Rubiks::run() {
|
||||
|
||||
ImGui::SliderFloat("cube scale", &scale, 0.01f, 10.0f);
|
||||
|
||||
static bool updateCube = true;
|
||||
ImGui::Checkbox("auto update cube", &updateCube);
|
||||
if(updateCube) {
|
||||
rubiksCube.update();
|
||||
}
|
||||
|
||||
if(ImGui::Button("step cube")) {
|
||||
rubiksCube.update();
|
||||
}
|
||||
|
||||
if(ImGui::Button("xb")) {
|
||||
rubiksCube.doTurn(RubiksCube::Plate::X_Bottom, false);
|
||||
}
|
||||
|
||||
if(ImGui::Button("yt")) {
|
||||
rubiksCube.doTurn(RubiksCube::Plate::Y_Top, false);
|
||||
}
|
||||
|
||||
if(ImGui::Button("solve")) {
|
||||
rubiksCube.solve();
|
||||
}
|
||||
|
||||
if(ImGui::Button("Reset Window Size")) {
|
||||
app->emitEvent(new Archimedes::ResizeWindowEvent(500, 500));
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
#include "utils/Renderer/Renderer.h"
|
||||
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <stack>
|
||||
#include <queue>
|
||||
|
||||
class RubiksCube {
|
||||
|
||||
@@ -35,69 +35,265 @@ class RubiksCube {
|
||||
r->setupRenderTarget(rt);
|
||||
|
||||
for(int i = 0; i < blocks.size(); i++) {
|
||||
blocks.at(i) = Archimedes::Body(rt);
|
||||
blocks.at(i).moveTo(positions.at(i));
|
||||
blocks.at(i).body = Archimedes::Body(rt);
|
||||
blocks.at(i).body.moveTo(positions.at(i));
|
||||
|
||||
switch((int)positions.at(i).x) {
|
||||
case -1:
|
||||
blocks.at(i).plates |= Plate::X_Bottom;
|
||||
break;
|
||||
case 0:
|
||||
blocks.at(i).plates |= Plate::X_Middle;
|
||||
break;
|
||||
case 1:
|
||||
blocks.at(i).plates |= Plate::X_Top;
|
||||
break;
|
||||
}
|
||||
|
||||
switch((int)positions.at(i).y) {
|
||||
case -1:
|
||||
blocks.at(i).plates |= Plate::Y_Bottom;
|
||||
break;
|
||||
case 0:
|
||||
blocks.at(i).plates |= Plate::Y_Middle;
|
||||
break;
|
||||
case 1:
|
||||
blocks.at(i).plates |= Plate::Y_Top;
|
||||
break;
|
||||
}
|
||||
|
||||
switch((int)positions.at(i).z) {
|
||||
case -1:
|
||||
blocks.at(i).plates |= Plate::Z_Bottom;
|
||||
break;
|
||||
case 0:
|
||||
blocks.at(i).plates |= Plate::Z_Middle;
|
||||
break;
|
||||
case 1:
|
||||
blocks.at(i).plates |= Plate::Z_Top;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Archimedes::Body> getBlocks() { return blocks; }
|
||||
enum Plate {
|
||||
X_Bottom = 1 << 0,
|
||||
X_Middle = 1 << 1,
|
||||
X_Top = 1 << 2,
|
||||
|
||||
enum class Direction {
|
||||
X, Y, Z
|
||||
Y_Bottom = 1 << 3,
|
||||
Y_Middle = 1 << 4,
|
||||
Y_Top = 1 << 5,
|
||||
|
||||
Z_Bottom = 1 << 6,
|
||||
Z_Middle= 1 << 7,
|
||||
Z_Top = 1 << 8
|
||||
};
|
||||
|
||||
enum class Plate {
|
||||
Top = 1, Middle = 0, Bottom = -1
|
||||
struct Block {
|
||||
Archimedes::Body body;
|
||||
int plates = 0;
|
||||
};
|
||||
|
||||
std::vector<Block> getBlocks() { return blocks; }
|
||||
|
||||
|
||||
void orbit(Archimedes::Body& body, glm::vec3 center, glm::vec3 direction, float radians) {
|
||||
glm::vec3 o = body.getPosition() - center;
|
||||
|
||||
direction = glm::normalize(glm::cross(glm::cross(o, direction), o));
|
||||
//direction = glm::normalize(glm::cross(glm::cross(o, direction), o));
|
||||
|
||||
body.setTransform(glm::rotate(body.getTransform(), radians, direction));
|
||||
|
||||
glm::vec3 a = glm::cross(direction, o);
|
||||
|
||||
glm::vec3 b = glm::cross(a, direction);
|
||||
|
||||
glm::vec3 v = glm::cos(radians) * glm::normalize(b) - glm::sin(radians) * glm::normalize(a);
|
||||
|
||||
|
||||
glm::vec3 r = glm::length(o) * glm::normalize(v);
|
||||
|
||||
if(o != glm::vec3(0.0f)) {
|
||||
body.moveTo(center + r);
|
||||
}
|
||||
|
||||
body.rotateRel(radians * direction);
|
||||
}
|
||||
|
||||
std::vector<Archimedes::Body> selectPlate(Plate plate, Direction direction) {
|
||||
std::vector<Archimedes::Body> p;
|
||||
p.reserve(plate == Plate::Middle ? 8 : 9);
|
||||
switch(direction) {
|
||||
case Direction::X:
|
||||
struct Turn {
|
||||
Plate plate;
|
||||
bool reverse;
|
||||
};
|
||||
|
||||
std::stack<Turn> turnStack;
|
||||
std::queue<Turn> turnQueue;
|
||||
|
||||
bool goNext = true;
|
||||
|
||||
bool solving = false;
|
||||
|
||||
int frames = 120;
|
||||
|
||||
int frame = 120;
|
||||
|
||||
void rotatePlate(Turn turn, float radians) {
|
||||
if(turn.reverse) {
|
||||
radians = -radians;
|
||||
}
|
||||
switch(turn.plate) {
|
||||
case Plate::X_Bottom:
|
||||
case Plate::X_Middle:
|
||||
case Plate::X_Top:
|
||||
for(auto& b : blocks) {
|
||||
|
||||
if(b.getPosition().x == (float)plate) {
|
||||
p.push_back(b);
|
||||
|
||||
if(b.plates & turn.plate) {
|
||||
float p = -1 * (turn.plate & Plate::X_Bottom) / Plate::X_Bottom + (turn.plate & Plate::X_Top) / Plate::X_Top;
|
||||
orbit(b.body, glm::vec3(p, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), radians / 2);
|
||||
orbit(b.body, glm::vec3(p, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), radians / 2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Direction::Y:
|
||||
break;
|
||||
case Direction::Z:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case Plate::Y_Bottom:
|
||||
case Plate::Y_Middle:
|
||||
case Plate::Y_Top:
|
||||
for(auto& b : blocks) {
|
||||
|
||||
return p;
|
||||
}
|
||||
if(b.plates & turn.plate) {
|
||||
float p = -1 * (turn.plate & Plate::Y_Bottom) / Plate::Y_Bottom + (turn.plate & Plate::Y_Top) / Plate::Y_Top;
|
||||
orbit(b.body, glm::vec3(0.0f, p, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), radians / 2);
|
||||
orbit(b.body, glm::vec3(0.0f, p, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), radians / 2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Plate::Z_Bottom:
|
||||
case Plate::Z_Middle:
|
||||
case Plate::Z_Top:
|
||||
for(auto& b : blocks) {
|
||||
|
||||
void turn(Plate plate, Direction direction) {
|
||||
switch(direction) {
|
||||
case Direction::X:
|
||||
break;
|
||||
case Direction::Y:
|
||||
break;
|
||||
case Direction::Z:
|
||||
if(b.plates & turn.plate) {
|
||||
float p = -1 * (turn.plate & Plate::Z_Bottom) / Plate::Z_Bottom + (turn.plate & Plate::Z_Top) / Plate::Z_Top;
|
||||
orbit(b.body, glm::vec3(0.0f, 0.0f, p), glm::vec3(0.0f, 0.0f, 1.0f), radians / 2);
|
||||
orbit(b.body, glm::vec3(0.0f, 0.0f, p), glm::vec3(0.0f, 0.0f, 1.0f), radians / 2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void update() {}
|
||||
void doTurn(Plate plate, bool reverse) {
|
||||
|
||||
turnQueue.push({
|
||||
plate,
|
||||
reverse
|
||||
});
|
||||
}
|
||||
|
||||
void snap() {
|
||||
|
||||
bool repeat = true;
|
||||
|
||||
for(auto& b : blocks) {
|
||||
glm::vec3 pos = glm::vec3(b.body.getTransform()[3][0], b.body.getTransform()[3][1], b.body.getTransform()[3][2]);
|
||||
pos = glm::round(pos);
|
||||
|
||||
b.body.moveTo(pos);
|
||||
b.body.rotateTo(glm::round(b.body.getRotation() * 2.0f / glm::pi<float>()) * glm::pi<float>() / 2.0f);
|
||||
|
||||
//glm::vec3 pos = b.body.getPosition();
|
||||
|
||||
|
||||
if(repeat) {
|
||||
|
||||
std::cout << b.body.getTransform()[3][0] << " " << b.body.getTransform()[3][1] << " " << b.body.getTransform()[3][2] << std::endl;
|
||||
std::cout << pos.x << " " << pos.y << " " << pos.z << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
repeat = false;
|
||||
}
|
||||
|
||||
b.plates = 0;
|
||||
|
||||
switch((int)pos.x) {
|
||||
case -1:
|
||||
b.plates |= Plate::X_Bottom;
|
||||
break;
|
||||
case 0:
|
||||
b.plates |= Plate::X_Middle;
|
||||
break;
|
||||
case 1:
|
||||
b.plates |= Plate::X_Top;
|
||||
break;
|
||||
}
|
||||
|
||||
switch((int)pos.y) {
|
||||
case -1:
|
||||
b.plates |= Plate::Y_Bottom;
|
||||
break;
|
||||
case 0:
|
||||
b.plates |= Plate::Y_Middle;
|
||||
break;
|
||||
case 1:
|
||||
b.plates |= Plate::Y_Top;
|
||||
break;
|
||||
}
|
||||
|
||||
switch((int)pos.z) {
|
||||
case -1:
|
||||
b.plates |= Plate::Z_Bottom;
|
||||
break;
|
||||
case 0:
|
||||
b.plates |= Plate::Z_Middle;
|
||||
break;
|
||||
case 1:
|
||||
b.plates |= Plate::Z_Top;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void update() {
|
||||
|
||||
if(!turnQueue.empty()) {
|
||||
rotatePlate(turnQueue.front(), glm::radians(90.0f) / frames);
|
||||
goNext = --frame <= 0;
|
||||
} else if(solving) {
|
||||
solving = false;
|
||||
}
|
||||
|
||||
if(!turnQueue.empty() && goNext) {
|
||||
|
||||
snap();
|
||||
|
||||
frame = frames;
|
||||
goNext = false;
|
||||
|
||||
if(!solving) {
|
||||
turnStack.push({
|
||||
turnQueue.front().plate,
|
||||
!turnQueue.front().reverse
|
||||
});
|
||||
}
|
||||
|
||||
turnQueue.pop();
|
||||
}
|
||||
}
|
||||
|
||||
void solve() {
|
||||
while(!turnStack.empty()) {
|
||||
turnQueue.push(turnStack.top());
|
||||
turnStack.pop();
|
||||
}
|
||||
|
||||
solving = true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Archimedes::Body> blocks = std::vector<Archimedes::Body>(26);
|
||||
|
||||
|
||||
std::vector<Block> blocks = std::vector<Block>(26);
|
||||
|
||||
std::vector<glm::vec3> positions = {
|
||||
glm::vec3(-1.0f, 1.0f, 1.0f), glm::vec3(0.0f, 1.0f, 1.0f), glm::vec3(1.0f, 1.0f, 1.0f),
|
||||
|
||||
Reference in New Issue
Block a user