2025-01-19 16:03:36 +01:00

144 lines
3.4 KiB
C++

#include "Cube.h"
Cube::Cube() : Entity(nullptr)
{
for(int x=-1;x<=1;x++) {
for(int y=-1;y<=1;y++) {
for(int z=-1;z<=1;z++) {
Side side = Side::Forward;
Color sideColors[6];
if (x == -1) {
sideColors[Side::Left] = SideColor[Side::Left];
}
if (x == 1) {
sideColors[Side::Right] = SideColor[Side::Right];
}
if (y == -1) {
sideColors[Side::Bottom] = SideColor[Side::Bottom];
}
if (y == 1) {
sideColors[Side::Top] = SideColor[Side::Top];
}
if (z == -1) {
sideColors[Side::Back] = SideColor[Side::Back];
}
if (z == 1) {
sideColors[Side::Forward] = SideColor[Side::Forward];
}
PartitionedCube* cubeAtIndex = new PartitionedCube(this, glm::vec3(x, y, z), sideColors);
this->_children[x + 1][y + 1][z + 1] = cubeAtIndex;
}
}
}
}
Cube::~Cube() {
}
void Cube::_FindAxisChildren(const glm::ivec3& axis, int index, std::vector<glm::ivec3>& result) const {
glm::ivec3 orientationBuffer[3] = {
axis,
glm::ivec3(axis[1], axis[2], axis[0]),
glm::ivec3(axis[2], axis[0], axis[1])
};
for(int x = -1;x<=1;x++) {
for(int y = -1;y<=1;y++) {
glm::ivec3 position = axis * index + orientationBuffer[1] * x + orientationBuffer[2] * y;
result.push_back(position);
}
}
}
void Cube::TransformData(const glm::ivec3& axis, int index, int turns) {
PartitionedCube* previousCubeList[3][3][3];
memcpy(previousCubeList, this->_children, sizeof(this->_children));
std::vector<glm::ivec3> result;
glm::mat3 transform = glm::rotate(glm::mat4(1.0f), glm::radians(90.0f) * turns, glm::vec3(axis));
for(int x=0;x<3;x++) {
for(int y=0;y<3;y++) {
transform[x][y] = lroundf(transform[x][y]);
}
}
_FindAxisChildren(axis, index, result);
for(auto& position : result) {
glm::ivec3 newPosition = transform * position;
position += glm::ivec3(1);
newPosition += glm::ivec3(1);
_children[newPosition.x][newPosition.y][newPosition.z] = previousCubeList[position.x][position.y][position.z];
_children[newPosition.x][newPosition.y][newPosition.z]->TransformData(axis, turns);
}
}
void Cube::Transform(const glm::ivec3& axis, int index, const glm::mat3& transform) {
// _TransformData(axis, index, transform);
std::vector<glm::ivec3> result;
_FindAxisChildren(axis, index, result);
for(auto& position : result) {
PartitionedCube* cube = _children[position.x + 1][position.y + 1][position.z + 1];
cube->TransformLocal(glm::mat4(transform));
}
}
void Cube::TransformTemp(const glm::ivec3& axis, int index, const glm::mat3& transform) {
std::vector<glm::ivec3> result;
_FindAxisChildren(axis, index, result);
for(auto& position : result) {
PartitionedCube* cube = _children[position.x + 1][position.y + 1][position.z + 1];
cube->TransformTemp(glm::mat4(transform));
}
}
void Cube::UndoTransformTemp()
{
for(int x=0;x<3;x++) {
for(int y=0;y<3;y++) {
for(int z=0;z<3;z++) {
_children[x][y][z]->UndoTransformTemp();
}
}
}
}
void Cube::TransformAnimation(const glm::ivec3& axis, int index, float angle, float duration) {
// _TransformData(axis, index, transform);
std::vector<glm::ivec3> result;
_FindAxisChildren(axis, index, result);
glm::quat transform = glm::angleAxis(angle, glm::vec3(axis));
for(auto& position : result) {
PartitionedCube* cube = _children[position.x + 1][position.y + 1][position.z + 1];
cube->TransformAnimation(glm::mat4(transform), duration);
}
}