This commit is contained in:
2026-04-27 15:45:13 -05:00
parent ee24681d07
commit 359da63167
3 changed files with 111 additions and 103 deletions

View File

@@ -37,28 +37,37 @@ 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]);
moveRel(-position);
moveRel(pos);
return position;
}
glm::vec3 moveRel(glm::vec3 pos) {
return moveTo(pos + position);
worldTransform = glm::translate(worldTransform, pos);
position += pos;
return position;
}
glm::vec3 rotateTo(glm::vec3 angles) {
worldTransform = glm::rotate(worldTransform, angles.x - rotation.x, glm::vec3(1.0f, 0.0f, 0.0f));
worldTransform = glm::rotate(worldTransform, angles.y - rotation.y, glm::vec3(0.0f, 1.0f, 0.0f));
worldTransform = glm::rotate(worldTransform, angles.z - rotation.z, glm::vec3(0.0f, 0.0f, 1.0f));
rotation = angles;
worldTransform = glm::rotate(worldTransform, -angles.z, glm::vec3(0.0f, 0.0f, 1.0f));
worldTransform = glm::rotate(worldTransform, -angles.y, glm::vec3(0.0f, 1.0f, 0.0f));
worldTransform = glm::rotate(worldTransform, -angles.x, glm::vec3(1.0f, 0.0f, 0.0f));
rotation = rotateRel(angles);
return rotation;
}
glm::vec3 rotateRel(glm::vec3 angles) {
return rotateTo(angles + rotation);
worldTransform = glm::rotate(worldTransform, angles.x, glm::vec3(1.0f, 0.0f, 0.0f));
worldTransform = glm::rotate(worldTransform, angles.y, glm::vec3(0.0f, 1.0f, 0.0f));
worldTransform = glm::rotate(worldTransform, angles.z, glm::vec3(0.0f, 0.0f, 1.0f));
rotation += angles;
return rotation;
}
glm::vec3& getPosition() { return position; }

View File

@@ -79,7 +79,7 @@ void Rubiks::run() {
static glm::vec3 pos(0), rot(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 camPos(6.0f, 8.0f, 6.0f), camRot(-glm::pi<float>() / 4, 5.0 / 4.0 * glm::pi<float>(), 0.0f);
static glm::vec3 camPosPrev(0.0f, 0.0f, 10.0f), camRotPrev(0.0f, glm::pi<float>(), 0.0f);
static glm::vec4 color = { 0.4f, 3.0f, 0.4f, 1.0f };

View File

@@ -38,41 +38,7 @@ class RubiksCube {
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;
}
setPlate(blocks.at(i));
}
}
@@ -103,21 +69,26 @@ class RubiksCube {
//direction = glm::normalize(glm::cross(glm::cross(o, direction), o));
glm::vec4 d = glm::vec4(direction, 0) * body.getTransform();
glm::vec3 a = glm::cross(direction, o);
direction = glm::vec3(d.x, d.y, d.z);
glm::vec3 b = glm::cross(a, direction);
glm::vec3 a = glm::cross(o, direction);
glm::vec3 v = glm::cos(radians) * glm::normalize(b) - glm::sin(radians) * glm::normalize(a);
glm::vec3 v = glm::cos(radians) * glm::normalize(a) + glm::sin(radians) * glm::normalize(o);
glm::vec3 r = glm::length(o) * glm::normalize(v);
if(o != glm::vec3(0.0f)) {
body.moveTo(center + r);
body.moveTo(center);
}
body.rotateRel(radians * direction);
if(o != glm::vec3(0.0f)) {
body.moveTo(center + o);
}
}
struct Turn {
@@ -140,41 +111,45 @@ class RubiksCube {
if(turn.reverse) {
radians = -radians;
}
float p;
glm::vec4 c;
switch(turn.plate) {
case Plate::X_Bottom:
case Plate::X_Middle:
case Plate::X_Top:
p = -1 * (turn.plate & Plate::X_Bottom) / Plate::X_Bottom + (turn.plate & Plate::X_Top) / Plate::X_Top;
for(auto& b : blocks) {
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);
c = glm::vec4(p, 0.0f, 0.0f, 0.0f) * b.body.getTransform();
glm::vec3 center = glm::vec3(c.x, c.y, c.z);
orbit(b.body, center, glm::vec3(1.0f, 0.0f, 0.0f), radians);
}
}
break;
case Plate::Y_Bottom:
case Plate::Y_Middle:
case Plate::Y_Top:
p = -1 * (turn.plate & Plate::Y_Bottom) / Plate::Y_Bottom + (turn.plate & Plate::Y_Top) / Plate::Y_Top;
for(auto& b : blocks) {
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);
c = glm::vec4(0.0f, p, 0.0f, 0.0f) * b.body.getTransform();
glm::vec3 center = glm::vec3(c.x, c.y, c.z);
orbit(b.body, center, glm::vec3(0.0f, 1.0f, 0.0f), radians);
}
}
break;
case Plate::Z_Bottom:
case Plate::Z_Middle:
case Plate::Z_Top:
p = -1 * (turn.plate & Plate::Z_Bottom) / Plate::Z_Bottom + (turn.plate & Plate::Z_Top) / Plate::Z_Top;
for(auto& b : blocks) {
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);
c = glm::vec4(0.0f, 0.0f, p, 0.0f) * b.body.getTransform();
glm::vec3 center = glm::vec3(c.x, c.y, c.z);
orbit(b.body, center, glm::vec3(0.0f, 0.0f, 1.0f), radians);
}
}
break;
@@ -190,67 +165,91 @@ class RubiksCube {
reverse
});
}
void setPlate(Block& b) {
glm::vec3 pos = glm::round(b.body.getPosition());
glm::vec4 p = b.body.getTransform() * glm::vec4(pos, 0);
pos = glm::vec3(p.x, p.y, p.z);
b.plates = 0;
if(pos.x > 0.5) {
b.plates |= Plate::X_Top;
} else if(pos.x < -0.5) {
b.plates |= Plate::X_Bottom;
} else {
b.plates |= Plate::X_Middle;
}
if(pos.y > 0.5) {
b.plates |= Plate::Y_Top;
} else if(pos.y < -0.5) {
b.plates |= Plate::Y_Bottom;
} else {
b.plates |= Plate::Y_Middle;
}
if(pos.z > 0.5) {
b.plates |= Plate::Z_Top;
} else if(pos.z < -0.5) {
b.plates |= Plate::Z_Bottom;
} else {
b.plates |= Plate::Z_Middle;
}
}
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);
glm::vec3 pos = glm::round(b.body.getPosition());
b.body.moveTo(pos);
b.body.moveTo(glm::vec3(0));
b.body.rotateTo(glm::round(b.body.getRotation() * 2.0f / glm::pi<float>()) * glm::pi<float>() / 2.0f);
b.body.moveTo(pos);
//glm::vec3 pos = b.body.getPosition();
glm::vec4 p = glm::vec4(pos, 0) * b.body.getTransform();
pos = glm::vec3(p.x, p.y, p.z);
setPlate(b);
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 << 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;
if(b.plates & Plate::X_Top) {
std::cout << "X_Top\n";
}
if(b.plates & Plate::X_Middle) {
std::cout << "X_Middle\n";
}
if(b.plates & Plate::X_Bottom) {
std::cout << "X_Bottom\n";
}
if(b.plates & Plate::Y_Top) {
std::cout << "Y_Top\n";
}
if(b.plates & Plate::Y_Middle) {
std::cout << "Y_Middle\n";
}
if(b.plates & Plate::Y_Bottom) {
std::cout << "Y_Bottom\n";
}
if(b.plates & Plate::Z_Top) {
std::cout << "Z_Top\n";
}
if(b.plates & Plate::Z_Middle) {
std::cout << "Z_Middle\n";
}
if(b.plates & Plate::Z_Bottom) {
std::cout << "Z_Bottom\n";
}
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;
}
}
}