Spieleprogrammierung/RubiksCube/PartitionedCube.h
2025-01-09 01:57:18 +01:00

101 lines
2.2 KiB
C++

#pragma once
#include "Color.h"
#include <stdint.h>
#include <glm.hpp>
#include <ext.hpp>
#include <ext/quaternion_float.hpp>
#include <math.h>
#include <vector>
struct VertexData {
glm::vec3 position;
Color color;
VertexData() : position(glm::vec3(0.0f, 0.0f, 0.0f)), color(Color::WHITE()) {
}
VertexData(const glm::vec3& position, Color color) : position(position), color(color) {
}
};
struct MeshData {
int vertexIndex;
std::vector<VertexData> data;
int triangleIndex;
MeshData() {
vertexIndex = 0;
triangleIndex = 0;
}
void addTriangle(glm::vec3 v0, glm::vec3 v1, glm::vec3 v2, Color color) {
data.push_back(VertexData(v0, color));
data.push_back(VertexData(v1, color));
data.push_back(VertexData(v2, color));
vertexIndex += 3;
triangleIndex ++;
}
void addFace(glm::vec3 v0, glm::vec3 v1, glm::vec3 v2, glm::vec3 v3, Color color) {
addTriangle(v0, v1, v2, color);
addTriangle(v3, v2, v1, color);
}
};
enum Side {
Left, Right, Bottom, Top, Back, Forward
};
constexpr glm::vec3 SideToDirection[6] = {
glm::vec3(-1.0f, 0.0f, 0.0f),
glm::vec3(1.0f, 0.0f, 0.0f),
glm::vec3(0.0f, -1.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f),
glm::vec3(0.0f, 0.0f, -1.0f),
glm::vec3(0.0f, 0.0f, 1.0f),
};
class PartitionedCube
{
private:
glm::mat4 _transform;
glm::mat4 _animationTransformInvoke;
glm::quat _animationTransform;
float _animationTime;
float _animationTimeExtend;
bool _animationFinished;
Color _faces[6];
MeshData _meshData;
public:
PartitionedCube(const glm::vec3& position, Color sideColors[6]);
void Update(double deltaTime);
const glm::mat4 Transform() const {
// Need to use slerp since rotations are non-linear and would not interpolate this way
if (false == _animationFinished) {
float lerpFactor = 1.0f - ( _animationTime / _animationTimeExtend);
glm::mat4 animationView = glm::mat4_cast(glm::slerp(glm::quat(1.0f, 0.0f, 0.0f, 0.0f), _animationTransform, lerpFactor));
return animationView * _animationTransformInvoke;
}
return _transform;
}
const MeshData& MeshData() const { return _meshData; };
void Transform(glm::mat4 transformation);
void TransformAnimation(const glm::mat4& transform, float duration);
};