#include "PartitionedCube.h" #include "Debug.h" #include "Cube.h" #include #include Shader PartitionedCubeMesh::_shader("cube.vert", "cube.frag"); Texture PartitionedCubeMesh::_diffuse; Texture PartitionedCubeMesh::_roughness; Texture PartitionedCubeMesh::_normal; PartitionedCube::PartitionedCube(Cube* parent, const glm::vec3& position, Color* sideColors) : Entity(parent) { this->TransformLocal(glm::translate(glm::mat4(1.0f), position)); this->_transformTem = glm::mat4(1.0f); for(int i=0;i<6;i++) { _faces[i] = sideColors[i]; } _animationTime = 0.0f; _animationTimeExtend = 0.0f; _animationTransform = glm::quat(1.0f, 0.0f, 0.0f, 0.0f); _animationFinished = true; for(int axis=0;axis<3;axis++) { float factor = 1.0f * -1; for(int reverse=0;reverse<2;reverse++) { glm::vec3 x, y, z, v; x = glm::vec3(0.0f); y = glm::vec3(0.0f); z = glm::vec3(0.0f); z[axis] = factor; x[(axis+1)%3] = 1.0f; y = glm::cross(x, z); glm::vec3 v0 = x * 0.5f + y * 0.5f + 0.5f * z; glm::vec3 v1 = x * -0.5f + y * 0.5f + 0.5f * z; glm::vec3 v2 = x * 0.5f + y * -0.5f + 0.5f * z; glm::vec3 v3 = x * -0.5f + y * -0.5f + 0.5f * z; int s = 2 * axis + reverse; // (-x, +x, -y, +y, -z, +z) glm::vec2 uv0 = glm::vec2(1.0f, 1.0f); glm::vec2 uv1 = glm::vec2(0.0f, 1.0f); glm::vec2 uv2 = glm::vec2(1.0f, 0.0f); glm::vec2 uv3 = glm::vec2(0.0f, 0.0f); VertexData d0 = VertexData(v0, z, uv0, sideColors[s]); VertexData d1 = VertexData(v1, z, uv1, sideColors[s]); VertexData d2 = VertexData(v2, z, uv2, sideColors[s]); VertexData d3 = VertexData(v3, z, uv3, sideColors[s]); _mesh.AddQuad(d0, d1, d2, d3); factor = -factor; } } _mesh.CalculateTangents(); } void PartitionedCube::Update(double deltaTime) { this->_animationTime -= deltaTime; if (!_animationFinished && _animationTime <= 0.0f) { _animationTime = 0.0f; const glm::mat4 finishedAnimationTransform = TransformCustom(); SetTransform(finishedAnimationTransform); _animationFinished = true; } } void PartitionedCube::Render(DefaultUniform& uniform) { uniform.model = TransformCustom(); _mesh.Render(uniform); } int toIndex(const glm::ivec3& direction) { int axis = glm::abs(direction.x * 1 + direction.y * 2 + direction.z * 3) - 1; int allAxis = direction.x + direction.y + direction.z; int x = glm::sign(allAxis); int reverse = (x + 1) / 2; return axis * 2 + reverse; } glm::ivec3 toDirection(int index) { int axis = index / 2; int reverse = index % 2; glm::ivec3 direction = glm::ivec3(0); direction[axis] = 1; if (reverse == 0) direction = -direction; return direction; } void PartitionedCube::TransformData(const glm::ivec3& axis, int turns) { Color previousListColors[6]; for(int i=0;i<6;i++) { previousListColors[i] = _faces[i]; } glm::mat3 rotations = glm::rotate(glm::mat4(1.0f), glm::radians(90.0f) * turns, glm::vec3(axis)); for(int axis=0;axis<3;axis++) { for(int direction=-1;direction<=1;direction+=2) { glm::ivec3 position = glm::ivec3(0); position[axis] = direction; glm::vec3 newPosition = rotations * position; glm::ivec3 newPositionStable; newPositionStable.x = std::round(newPosition.x); newPositionStable.y = std::round(newPosition.y); newPositionStable.z = std::round(newPosition.z); int newIndex = toIndex(newPositionStable); int index = toIndex(position); _faces[newIndex] = previousListColors[index]; } } } void PartitionedCube::TransformAnimation(const glm::quat& transform, float duration) { if (!_animationFinished) SetTransform(TransformCustom()); this->_animationTransform = transform; this->_animationTime = duration; this->_animationTimeExtend = duration; _animationFinished = false; } void PartitionedCube::TransformTemp(const glm::mat4& transform) { _transformTem = transform; } void PartitionedCube::UndoTransformTemp() { _transformTem = glm::mat4(1.0f); }