Feature Complete Private
This commit is contained in:
parent
85583a8880
commit
3887733e67
8
.gitignore
vendored
8
.gitignore
vendored
@ -1 +1,7 @@
|
||||
ExternalResources
|
||||
ExternalResources
|
||||
|
||||
Abgabe
|
||||
|
||||
963830_rohmenf.zip
|
||||
|
||||
bugs.md
|
||||
112
RubiksCube/Camera.h
Normal file
112
RubiksCube/Camera.h
Normal file
@ -0,0 +1,112 @@
|
||||
#pragma once
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <glm/ext.hpp>
|
||||
|
||||
|
||||
|
||||
#include "Entity.h"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
class Camera : public Entity {
|
||||
private:
|
||||
GLFWwindow* _window;
|
||||
InputSystem* _inputSystem;
|
||||
|
||||
glm::mat4 _view;
|
||||
glm::mat4 _projection;
|
||||
|
||||
glm::quat _orientation;
|
||||
|
||||
glm::vec2 _dragStart;
|
||||
bool _wasMouseClicked;
|
||||
|
||||
float _scrollPositionPrevious;
|
||||
float _scrollPositionDelta;
|
||||
|
||||
static inline float cameraDistance = 8.15f;
|
||||
|
||||
static inline Camera* _instance;
|
||||
|
||||
public:
|
||||
const glm::mat4& View() const { return _view * glm::mat4_cast(_orientation); }
|
||||
const glm::mat4& Projection() const { return _projection; }
|
||||
|
||||
public:
|
||||
Camera(GLFWwindow* window, InputSystem* inputSystem) : Entity(nullptr) {
|
||||
_instance = this;
|
||||
_window = window;
|
||||
_inputSystem = inputSystem;
|
||||
|
||||
_wasMouseClicked = false;
|
||||
|
||||
_view = glm::lookAt(glm::vec3(0.0f, 0.0f, cameraDistance), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
_projection = glm::mat4(1.0f);
|
||||
}
|
||||
|
||||
void Update(double deltaTime) override {
|
||||
int screenWidth;
|
||||
int screenHeight;
|
||||
|
||||
glfwGetFramebufferSize(_window, &screenWidth, &screenHeight);
|
||||
|
||||
float aspec = (float)screenWidth / (float)screenHeight;
|
||||
|
||||
_projection = glm::perspective(glm::radians(45.0f), aspec, 0.1f, 100.0f);
|
||||
|
||||
if (_inputSystem->WasKeyPressed(GLFW_KEY_SPACE))
|
||||
_orientation = glm::quat(1.0f, glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
|
||||
glm::fvec2 velocity(0.0f, 0.0f);
|
||||
if (_inputSystem->IsKeyPressed(GLFW_KEY_UP))
|
||||
velocity.x = glm::radians(90.0f);
|
||||
if (_inputSystem->IsKeyPressed(GLFW_KEY_DOWN))
|
||||
velocity.x = glm::radians(-90.0f);
|
||||
|
||||
if (_inputSystem->IsKeyPressed(GLFW_KEY_RIGHT))
|
||||
velocity.y = glm::radians(90.0f);
|
||||
if (_inputSystem->IsKeyPressed(GLFW_KEY_LEFT))
|
||||
velocity.y = glm::radians(-90.0f);
|
||||
|
||||
if (!_wasMouseClicked && _inputSystem->IsRightMouseDown()) {
|
||||
_inputSystem->GetMousePos(_dragStart);
|
||||
}
|
||||
|
||||
if (_wasMouseClicked && _inputSystem->IsRightMouseDown()) {
|
||||
glm::vec2 currentMousePositions;
|
||||
_inputSystem->GetMousePos(currentMousePositions);
|
||||
glm::vec2 dragDiff = currentMousePositions - _dragStart;
|
||||
_dragStart = currentMousePositions;
|
||||
|
||||
_orientation = glm::quat(1.0f, glm::vec3(dragDiff.y, dragDiff.x, 0.0f) * 0.008f) * _orientation;
|
||||
_orientation = glm::normalize(_orientation);
|
||||
}
|
||||
|
||||
_wasMouseClicked = _inputSystem->IsRightMouseDown();
|
||||
|
||||
glm::quat velocityQuaternion = glm::quat(0.0f, glm::vec3(velocity.x, velocity.y, 0.0f));
|
||||
|
||||
_orientation += 0.5f * (float)deltaTime * velocityQuaternion * _orientation;
|
||||
_orientation = glm::normalize(_orientation);
|
||||
|
||||
_view = glm::translate(_view, glm::vec3(0.0f, 0.0f, _scrollPositionDelta));
|
||||
_scrollPositionDelta = 0.0f;
|
||||
|
||||
// since callbacks need to be static use a singleton
|
||||
glfwSetScrollCallback(_window, Camera::scrollCallbackGlobal);
|
||||
}
|
||||
|
||||
static void scrollCallbackGlobal(GLFWwindow* window, double xOffset, double yOffset) {
|
||||
_instance->scrollCallback(window, xOffset, yOffset);
|
||||
}
|
||||
|
||||
void scrollCallback(GLFWwindow* window, double xOffset, double yOffset) {
|
||||
_scrollPositionDelta = yOffset;
|
||||
}
|
||||
|
||||
void SetAspectRatio(float aspec) {
|
||||
_projection = glm::perspective(glm::radians(45.0f), aspec, 0.1f, 100.0f);
|
||||
}
|
||||
};
|
||||
@ -1,9 +1,7 @@
|
||||
#include "Cube.h"
|
||||
|
||||
Cube::Cube()
|
||||
Cube::Cube() : Entity(nullptr)
|
||||
{
|
||||
this->_transform = glm::mat4(1.0f);
|
||||
|
||||
for(int x=-1;x<=1;x++) {
|
||||
for(int y=-1;y<=1;y++) {
|
||||
for(int z=-1;z<=1;z++) {
|
||||
@ -35,7 +33,7 @@ Cube::Cube()
|
||||
sideColors[Side::Forward] = SideColor[Side::Forward];
|
||||
}
|
||||
|
||||
PartitionedCube* cubeAtIndex = new PartitionedCube(glm::vec3(x, y, z), sideColors);
|
||||
PartitionedCube* cubeAtIndex = new PartitionedCube(this, glm::vec3(x, y, z), sideColors);
|
||||
|
||||
this->_children[x + 1][y + 1][z + 1] = cubeAtIndex;
|
||||
}
|
||||
@ -53,20 +51,6 @@ Cube::~Cube() {
|
||||
}
|
||||
}
|
||||
|
||||
void Cube::Update(double deltaTime) {
|
||||
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]->Update(deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cube::Transform(glm::mat4 transform) {
|
||||
this->_transform *= transform;
|
||||
}
|
||||
|
||||
void Cube::_FindAxisChildren(const glm::ivec3& axis, int index, std::vector<glm::ivec3>& result) const {
|
||||
glm::ivec3 orientationBuffer[3] = {
|
||||
axis,
|
||||
@ -83,12 +67,20 @@ void Cube::_FindAxisChildren(const glm::ivec3& axis, int index, std::vector<glm:
|
||||
}
|
||||
}
|
||||
|
||||
void Cube::_TransformData(const glm::ivec3& axis, int index, const glm::mat3& transform) {
|
||||
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) {
|
||||
@ -98,20 +90,22 @@ void Cube::_TransformData(const glm::ivec3& axis, int index, const glm::mat3& tr
|
||||
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);
|
||||
// _TransformData(axis, index, transform);
|
||||
|
||||
std::vector<glm::ivec3> result;
|
||||
|
||||
_FindAxisChildren(transform * axis, index, result);
|
||||
_FindAxisChildren(axis, index, result);
|
||||
|
||||
for(auto& position : result) {
|
||||
PartitionedCube* cube = _children[position.x + 1][position.y + 1][position.z + 1];
|
||||
|
||||
cube->Transform(glm::mat4(transform));
|
||||
cube->TransformLocal(glm::mat4(transform));
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,16 +117,29 @@ void Cube::TransformTemp(const glm::ivec3& axis, int index, const glm::mat3& tra
|
||||
for(auto& position : result) {
|
||||
PartitionedCube* cube = _children[position.x + 1][position.y + 1][position.z + 1];
|
||||
|
||||
cube->Transform(glm::mat4(transform));
|
||||
cube->TransformTemp(glm::mat4(transform));
|
||||
}
|
||||
}
|
||||
|
||||
void Cube::TransformAnimation(const glm::ivec3& axis, int index, const glm::mat3& transform, float duration) {
|
||||
_TransformData(axis, index, 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(transform * axis, index, 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];
|
||||
|
||||
@ -1,36 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <glm.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "Entity.h"
|
||||
|
||||
#include "PartitionedCube.h"
|
||||
|
||||
// Colors according to https://ruwix.com/the-rubiks-cube/japanese-western-color-schemes/
|
||||
class Cube
|
||||
class Cube : public Entity
|
||||
{
|
||||
private:
|
||||
glm::mat4 _transform;
|
||||
|
||||
PartitionedCube* _children[3][3][3];
|
||||
|
||||
void _TransformData(const glm::ivec3& axis, int index, const glm::mat3& transform);
|
||||
|
||||
void _FindAxisChildren(const glm::ivec3& axis, int index, std::vector<glm::ivec3>& result) const;
|
||||
|
||||
public:
|
||||
Cube();
|
||||
~Cube();
|
||||
|
||||
void Update(double deltaTime);
|
||||
virtual ~Cube();
|
||||
|
||||
const int ChildPartitionsCount = 27;
|
||||
PartitionedCube** Children() { return &(_children[0][0][0]); }
|
||||
|
||||
const glm::mat4& Transform() const { return _transform; }
|
||||
|
||||
void TransformAnimation(const glm::ivec3& axis, int index, const glm::mat3& transform, float duration);
|
||||
void TransformData(const glm::ivec3& axis, int index, int turns);
|
||||
void TransformAnimation(const glm::ivec3& axis, int index, float angle, float duration);
|
||||
void Transform(const glm::ivec3& axis, int index, const glm::mat3& transform);
|
||||
void TransformTemp(const glm::ivec3& axis, int index, const glm::mat3& transform);
|
||||
void Transform(glm::mat4 transform);
|
||||
void UndoTransformTemp();
|
||||
|
||||
static constexpr Color SideColor[6] = {
|
||||
Color::ORANGE(),
|
||||
|
||||
68
RubiksCube/Debug.cpp
Normal file
68
RubiksCube/Debug.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
#include "Debug.h"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <glm/ext.hpp>
|
||||
|
||||
void Debug::Render(DefaultUniform& uniform)
|
||||
{
|
||||
RenderLines(uniform);
|
||||
|
||||
_lines.clear();
|
||||
}
|
||||
|
||||
void Debug::RenderLines(DefaultUniform& uniform) const
|
||||
{
|
||||
glUseProgram(_shader);
|
||||
glBindVertexArray(_vba);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
|
||||
int vertexCount = _lines.size() * 6;
|
||||
|
||||
int viewportWidth, viewportHeight;
|
||||
glfwGetFramebufferSize(_window, &viewportWidth, &viewportHeight);
|
||||
|
||||
glm::vec2 viewport = glm::vec2(viewportWidth, viewportHeight);
|
||||
|
||||
|
||||
|
||||
glUniform2fv(_uniformViewportRes, 1, glm::value_ptr(viewport));
|
||||
glUniformMatrix4fv(_uniformModel, 1, GL_FALSE, glm::value_ptr(uniform.model));
|
||||
glUniformMatrix4fv(_uniformView, 1, GL_FALSE, glm::value_ptr(uniform.view));
|
||||
glUniformMatrix4fv(_uniformProjection, 1, GL_FALSE, glm::value_ptr(uniform.projection));
|
||||
|
||||
|
||||
|
||||
DebugVertexData* data = new DebugVertexData[vertexCount];
|
||||
int index = 0;
|
||||
for(const auto& line : _lines) {
|
||||
int vertexIndex = index * 6;
|
||||
|
||||
glm::vec3 quad[4] = {
|
||||
line.positionFirst,
|
||||
line.positionFirst,
|
||||
line.positionLast,
|
||||
line.positionLast
|
||||
};
|
||||
|
||||
glm::vec3 direction = line.positionLast - line.positionFirst;
|
||||
|
||||
data[ vertexIndex + 0 ] = DebugVertexData { quad[0], direction, line.color, line.lineWidth };
|
||||
data[ vertexIndex + 1 ] = DebugVertexData { quad[1], direction, line.color, line.lineWidth };
|
||||
data[ vertexIndex + 2 ] = DebugVertexData { quad[2], direction, line.color, line.lineWidth };
|
||||
data[ vertexIndex + 3 ] = DebugVertexData { quad[1], direction, line.color, line.lineWidth };
|
||||
data[ vertexIndex + 4 ] = DebugVertexData { quad[2], direction, line.color, line.lineWidth };
|
||||
data[ vertexIndex + 5 ] = DebugVertexData { quad[3], direction, line.color, line.lineWidth };
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(DebugVertexData) * vertexCount, data, GL_STATIC_DRAW);
|
||||
glDrawArrays(GL_TRIANGLES, 0, vertexCount);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
|
||||
delete[] data;
|
||||
}
|
||||
146
RubiksCube/Debug.h
Normal file
146
RubiksCube/Debug.h
Normal file
@ -0,0 +1,146 @@
|
||||
#pragma once
|
||||
|
||||
#include "Color.h"
|
||||
|
||||
#include "ShaderUtil.h"
|
||||
|
||||
#include "Mesh.h"
|
||||
|
||||
#include "Entity.h"
|
||||
|
||||
#include <gl/glew.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/ext.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
struct GLFWwindow;
|
||||
|
||||
struct DebugLine {
|
||||
glm::vec3 positionFirst;
|
||||
glm::vec3 positionLast;
|
||||
float lineWidth;
|
||||
Color color;
|
||||
};
|
||||
|
||||
struct DebugPoint {
|
||||
glm::vec3 position;
|
||||
Color color;
|
||||
};
|
||||
|
||||
struct DebugDirection {
|
||||
glm::vec3 origin;
|
||||
glm::vec3 direction;
|
||||
float lineWidth;
|
||||
Color color;
|
||||
};
|
||||
|
||||
struct DebugVertexData {
|
||||
glm::vec3 v;
|
||||
glm::vec3 tangent;
|
||||
Color color;
|
||||
float lineWidth;
|
||||
};
|
||||
|
||||
class Debug : public Entity
|
||||
{
|
||||
private:
|
||||
std::vector<DebugLine> _lines;
|
||||
std::vector<DebugPoint> _points;
|
||||
|
||||
GLFWwindow* _window;
|
||||
|
||||
GLuint _vba;
|
||||
GLuint _vbo;
|
||||
GLuint _shader;
|
||||
|
||||
GLuint _uniformViewportRes;
|
||||
GLuint _uniformModel;
|
||||
GLuint _uniformView;
|
||||
GLuint _uniformProjection;
|
||||
|
||||
public:
|
||||
Debug() : Entity(nullptr) { }
|
||||
Debug(GLFWwindow* window) : Entity(nullptr) {
|
||||
_window = window;
|
||||
|
||||
glGenBuffers(1, &_vbo);
|
||||
glGenVertexArrays(1, &_vba);
|
||||
glBindVertexArray(_vba);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(DebugVertexData), (void*)offsetof(DebugVertexData, v));
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(DebugVertexData), (void*)offsetof(DebugVertexData, tangent));
|
||||
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(DebugVertexData), (void*)offsetof(DebugVertexData, color));
|
||||
glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, sizeof(DebugVertexData), (void*)offsetof(DebugVertexData, lineWidth));
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
glEnableVertexAttribArray(3);
|
||||
|
||||
_shader = ShaderUtil::CreateShaderProgram("line.vert", "line.frag");
|
||||
|
||||
_uniformViewportRes = glGetUniformLocation(_shader, "uViewportRes");
|
||||
_uniformModel = glGetUniformLocation(_shader, "model");
|
||||
_uniformView = glGetUniformLocation(_shader, "view");
|
||||
_uniformProjection = glGetUniformLocation(_shader, "projection");
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
~Debug() {
|
||||
glDeleteVertexArrays(1, &_vba);
|
||||
glDeleteBuffers(1, &_vbo);
|
||||
glDeleteProgram(_shader);
|
||||
}
|
||||
|
||||
void Render(DefaultUniform& uniform) override;
|
||||
void RenderLines(DefaultUniform& uniform) const;
|
||||
|
||||
static inline Debug* Instance;
|
||||
|
||||
void Line(const glm::vec3& positionFirst, const glm::vec3& positionLast, const Color& color) {
|
||||
_lines.push_back(DebugLine { positionFirst, positionLast, 1.0f, color });
|
||||
}
|
||||
|
||||
void Direction(const glm::vec3& origin, const glm::vec3& direction, const Color& color) {
|
||||
glm::vec4 capWorldPos = glm::vec4(origin + direction * 1.0f, 1.0f);
|
||||
|
||||
_lines.push_back(DebugLine { origin, capWorldPos, 8.0f, color });
|
||||
|
||||
glm::vec3 up = glm::vec3(direction[1], direction[2], direction[0]);
|
||||
|
||||
glm::vec3 capOffsets[4] = {
|
||||
glm::vec3( 1.0f, 1.0f, -1.0f),
|
||||
glm::vec3(-1.0f, 1.0f, -1.0f),
|
||||
glm::vec3( 1.0f, -1.0f, -1.0f),
|
||||
glm::vec3(-1.0f, -1.0f, -1.0f)
|
||||
};
|
||||
|
||||
glm::mat4 capLocalTf = glm::lookAt(glm::vec3(capWorldPos), origin, up);
|
||||
|
||||
capLocalTf = glm::inverse(capLocalTf);
|
||||
|
||||
float extends = 0.05f;
|
||||
for(const glm::vec3& offset : capOffsets) {
|
||||
Line(capWorldPos, capLocalTf * glm::vec4(extends * offset, 1.0f), color);
|
||||
}
|
||||
}
|
||||
|
||||
void Point(const glm::vec3& position, const Color& color) {
|
||||
for(int axis=0;axis<3;axis++) {
|
||||
glm::vec3 forward = glm::vec3(0.0f);
|
||||
forward[axis] = 1.0f;
|
||||
|
||||
glm::vec3 lineOrigin = position - forward;
|
||||
glm::vec3 lineDestinatio = position + forward;
|
||||
|
||||
Line(lineOrigin, lineDestinatio, color);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
81
RubiksCube/Entity.cpp
Normal file
81
RubiksCube/Entity.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
#include "Entity.h"
|
||||
|
||||
void Entity::_UpdateChildTransform() const {
|
||||
for(auto& child : _children) {
|
||||
child->_localToWorld = _localToWorld * child->_transform;
|
||||
child->_worldToLocal = glm::inverse(child->_transform);
|
||||
|
||||
child->_UpdateChildTransform();
|
||||
}
|
||||
}
|
||||
|
||||
Entity::Entity(Entity* parent) : _localToWorld(1.0f), _worldToLocal(1.0f)
|
||||
{
|
||||
_parent = parent;
|
||||
_transform = glm::mat4(1.0f);
|
||||
|
||||
if (parent == nullptr)
|
||||
return;
|
||||
|
||||
parent->AddChild(this);
|
||||
_localToWorld = _parent->_localToWorld;
|
||||
_worldToLocal = glm::inverse(_localToWorld);
|
||||
}
|
||||
|
||||
Entity::~Entity() {
|
||||
_parent->RemoveChild(this);
|
||||
}
|
||||
|
||||
void Entity::AddChild(Entity* entity) {
|
||||
_children.insert(entity);
|
||||
}
|
||||
|
||||
void Entity::RemoveChild(Entity* entity) {
|
||||
_children.erase(entity);
|
||||
}
|
||||
|
||||
void Entity::Transform(const glm::mat4& transform) {
|
||||
glm::mat4 transformLocalBasis = _worldToLocal * transform;
|
||||
|
||||
_transform = transformLocalBasis * _transform;
|
||||
|
||||
if (_parent == nullptr) {
|
||||
_localToWorld = _transform;
|
||||
}
|
||||
else {
|
||||
_localToWorld = _parent->LocalToWorld() * _transform;
|
||||
}
|
||||
|
||||
_worldToLocal = glm::inverse(_localToWorld);
|
||||
_UpdateChildTransform();
|
||||
}
|
||||
|
||||
void Entity::TransformLocal(const glm::mat4& transform)
|
||||
{
|
||||
_transform = transform * _transform;
|
||||
|
||||
if (_parent == nullptr) {
|
||||
_localToWorld = _transform;
|
||||
}
|
||||
else {
|
||||
_localToWorld = _parent->LocalToWorld() * _transform;
|
||||
}
|
||||
|
||||
_worldToLocal = glm::inverse(_localToWorld);
|
||||
_UpdateChildTransform();
|
||||
}
|
||||
|
||||
void Entity::SetTransform(const glm::mat4& transform) {
|
||||
_transform = transform;
|
||||
|
||||
if (_parent != nullptr) {
|
||||
_localToWorld = transform * _parent->_localToWorld;
|
||||
_worldToLocal = glm::inverse(transform) * _parent->_worldToLocal;
|
||||
}
|
||||
else {
|
||||
_localToWorld = transform;
|
||||
_worldToLocal = glm::inverse(transform);
|
||||
}
|
||||
|
||||
_UpdateChildTransform();
|
||||
}
|
||||
40
RubiksCube/Entity.h
Normal file
40
RubiksCube/Entity.h
Normal file
@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "Mesh.h"
|
||||
|
||||
class Entity {
|
||||
private:
|
||||
glm::mat4 _transform;
|
||||
|
||||
glm::mat4 _localToWorld;
|
||||
glm::mat4 _worldToLocal;
|
||||
|
||||
Entity* _parent;
|
||||
std::unordered_set<Entity*> _children;
|
||||
|
||||
void _UpdateChildTransform() const;
|
||||
|
||||
public:
|
||||
Entity(Entity* parent);
|
||||
virtual ~Entity();
|
||||
|
||||
void AddChild(Entity* entity);
|
||||
void RemoveChild(Entity* entity);
|
||||
|
||||
Entity* Parent() const { return _parent; }
|
||||
|
||||
void Transform(const glm::mat4& transform);
|
||||
void TransformLocal(const glm::mat4& transform);
|
||||
void SetTransform(const glm::mat4& transform);
|
||||
const glm::mat4& LocalToWorld() const { return _localToWorld; }
|
||||
const glm::mat4& WorldToLocal() const { return _worldToLocal; }
|
||||
const glm::mat4& LocalObjectTransform() const { return _transform; }
|
||||
|
||||
virtual void Render(DefaultUniform& uniform) { };
|
||||
virtual void Update(double deltaTime) { };
|
||||
|
||||
};
|
||||
@ -4,9 +4,9 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <glm.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <ext.hpp>
|
||||
#include <glm/ext.hpp>
|
||||
|
||||
void InputSystem::ObserveKey(int key) {
|
||||
_keyCodeDictionaryObserver.emplace(key, KeyObserver(_window, key));
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <glm.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "KeyObserver.h"
|
||||
|
||||
|
||||
1
RubiksCube/Mesh.cpp
Normal file
1
RubiksCube/Mesh.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "Mesh.h"
|
||||
97
RubiksCube/Mesh.h
Normal file
97
RubiksCube/Mesh.h
Normal file
@ -0,0 +1,97 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <gl/glew.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/ext.hpp>
|
||||
|
||||
#include "Shader.h"
|
||||
|
||||
class DefaultUniform {
|
||||
private:
|
||||
|
||||
public:
|
||||
glm::mat4 model;
|
||||
glm::mat4 view;
|
||||
glm::mat4 projection;
|
||||
};
|
||||
|
||||
template<class TVertexData, class TUniform = DefaultUniform>
|
||||
class Mesh
|
||||
{
|
||||
private:
|
||||
TUniform _uniform;
|
||||
|
||||
GLuint _uniformModel;
|
||||
GLuint _uniformView;
|
||||
GLuint _uniformProjection;
|
||||
|
||||
protected:
|
||||
std::vector<TVertexData> _vertexData;
|
||||
|
||||
GLuint _vba;
|
||||
GLuint _vbo;
|
||||
Shader* shader;
|
||||
|
||||
bool _isVertexDirty;
|
||||
|
||||
public:
|
||||
|
||||
TUniform& Uniform() { return _uniform; }
|
||||
|
||||
public:
|
||||
Mesh(Shader* shader) : shader(shader), _isVertexDirty(true) {
|
||||
shader->Initialize();
|
||||
|
||||
glCreateVertexArrays(1, &_vba);
|
||||
glCreateBuffers(1, &_vbo);
|
||||
|
||||
_uniformModel = glGetUniformLocation(shader->Reference(), "model");
|
||||
_uniformView = glGetUniformLocation(shader->Reference(), "view");
|
||||
_uniformProjection = glGetUniformLocation(shader->Reference(), "projection");
|
||||
}
|
||||
|
||||
~Mesh() {
|
||||
glDeleteVertexArrays(1, &_vba);
|
||||
glDeleteBuffers(1, &_vbo);
|
||||
}
|
||||
|
||||
void AddTriangle(const TVertexData& p0, const TVertexData& p1, const TVertexData& p2) {
|
||||
_vertexData.push_back(p0);
|
||||
_vertexData.push_back(p1);
|
||||
_vertexData.push_back(p2);
|
||||
|
||||
_isVertexDirty = true;
|
||||
}
|
||||
|
||||
void AddQuad(const TVertexData& p0, const TVertexData& p1, const TVertexData& p2, const TVertexData& p3) {
|
||||
AddTriangle(p0, p1, p2);
|
||||
AddTriangle(p1, p2, p3);
|
||||
}
|
||||
|
||||
virtual void Render(const TUniform& uniform) {
|
||||
shader->Use();
|
||||
|
||||
glUniformMatrix4fv(_uniformModel, 1, GL_FALSE, glm::value_ptr(uniform.model));
|
||||
glUniformMatrix4fv(_uniformView, 1, GL_FALSE, glm::value_ptr(uniform.view));
|
||||
glUniformMatrix4fv(_uniformProjection, 1, GL_FALSE, glm::value_ptr(uniform.projection));
|
||||
|
||||
glBindVertexArray(_vba);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
|
||||
if (_isVertexDirty) {
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(TVertexData) * _vertexData.size(), _vertexData.data(), GL_STATIC_DRAW);
|
||||
|
||||
_isVertexDirty = false;
|
||||
}
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, _vertexData.size());
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
shader->Disable();
|
||||
}
|
||||
};
|
||||
@ -1 +0,0 @@
|
||||
#pragma once
|
||||
@ -1,23 +1,30 @@
|
||||
#include "PartitionedCube.h"
|
||||
|
||||
#include "Debug.h"
|
||||
|
||||
#include "Cube.h"
|
||||
|
||||
#include <glm.hpp>
|
||||
#include <ext.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/ext.hpp>
|
||||
|
||||
PartitionedCube::PartitionedCube(const glm::vec3& position, Color* sideColors) : _faces {
|
||||
sideColors[0],
|
||||
sideColors[1],
|
||||
sideColors[2],
|
||||
sideColors[3],
|
||||
sideColors[4],
|
||||
sideColors[5],
|
||||
}
|
||||
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->_transform = glm::translate(glm::mat4(1.0f), position);
|
||||
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;
|
||||
_animationTransformInvoke = _transform;
|
||||
_animationTransform = glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
_animationFinished = true;
|
||||
|
||||
@ -33,7 +40,7 @@ PartitionedCube::PartitionedCube(const glm::vec3& position, Color* sideColors) :
|
||||
|
||||
z[axis] = factor;
|
||||
x[(axis+1)%3] = 1.0f;
|
||||
y[(axis+2)%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;
|
||||
@ -42,37 +49,109 @@ PartitionedCube::PartitionedCube(const glm::vec3& position, Color* sideColors) :
|
||||
|
||||
int s = 2 * axis + reverse; // (-x, +x, -y, +y, -z, +z)
|
||||
|
||||
_meshData.addFace(v0, v1, v2, v3, sideColors[s]);
|
||||
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) {
|
||||
_animationFinished = true;
|
||||
_animationTime = 0.0f;
|
||||
|
||||
_transform = glm::mat4_cast(_animationTransform) * _animationTransformInvoke;
|
||||
const glm::mat4 finishedAnimationTransform = TransformCustom();
|
||||
SetTransform(finishedAnimationTransform);
|
||||
_animationFinished = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PartitionedCube::Transform(glm::mat4 transformation)
|
||||
{
|
||||
this->_transform = transformation * this->_transform;
|
||||
_animationTransformInvoke = transformation * _animationTransformInvoke;
|
||||
_animationTransform = glm::quat_cast(transformation * glm::mat4_cast(_animationTransform));
|
||||
void PartitionedCube::Render(DefaultUniform& uniform) {
|
||||
uniform.model = TransformCustom();
|
||||
|
||||
_mesh.Render(uniform);
|
||||
}
|
||||
|
||||
void PartitionedCube::TransformAnimation(const glm::mat4& transform, float duration) {
|
||||
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)
|
||||
_transform = glm::mat4_cast(_animationTransform) * _animationTransformInvoke;
|
||||
|
||||
this->_animationTransformInvoke = this->_transform;
|
||||
this->_animationTransform = glm::quat_cast(transform);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -4,47 +4,121 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <glm.hpp>
|
||||
#include <ext.hpp>
|
||||
#include <ext/quaternion_float.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/ext.hpp>
|
||||
#include <glm/ext/quaternion_float.hpp>
|
||||
#include <math.h>
|
||||
#include <vector>
|
||||
|
||||
#include "Entity.h"
|
||||
|
||||
#include "Texture.h"
|
||||
#include "Shader.h"
|
||||
#include "Mesh.h"
|
||||
|
||||
struct VertexData {
|
||||
glm::vec3 position;
|
||||
glm::vec3 normal;
|
||||
glm::vec2 uv0;
|
||||
glm::vec3 tangent;
|
||||
glm::vec3 bitangent;
|
||||
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) {
|
||||
VertexData(const glm::vec3& position, const glm::vec3& normal, const glm::vec2 uv0, Color color) : position(position), color(color), normal(normal), uv0(uv0), tangent(0.0f), bitangent(0.0f) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
struct MeshData {
|
||||
int vertexIndex;
|
||||
std::vector<VertexData> data;
|
||||
int triangleIndex;
|
||||
class PartitionedCubeMesh : public Mesh<VertexData> {
|
||||
private:
|
||||
static Shader _shader;
|
||||
static Texture _diffuse;
|
||||
static Texture _roughness;
|
||||
static Texture _normal;
|
||||
|
||||
MeshData() {
|
||||
vertexIndex = 0;
|
||||
triangleIndex = 0;
|
||||
GLuint _uniformDiffuse;
|
||||
GLuint _uniformRoughness;
|
||||
GLuint _uniformNormal;
|
||||
|
||||
public:
|
||||
PartitionedCubeMesh() : Mesh(&_shader) {
|
||||
_shader.Use();
|
||||
|
||||
glBindVertexArray(_vba);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
|
||||
int shd = shader->Reference();
|
||||
|
||||
_uniformDiffuse = glGetUniformLocation(shd, "diffuse");
|
||||
_uniformRoughness = glGetUniformLocation(shd, "roughness");
|
||||
_uniformNormal = glGetUniformLocation(shd, "normal");
|
||||
|
||||
glUniform1i(_uniformDiffuse, 0);
|
||||
glUniform1i(_uniformRoughness, 1);
|
||||
glUniform1i(_uniformNormal, 2);
|
||||
|
||||
glVertexAttribPointer(glGetAttribLocation(shd, "position"), 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, position));
|
||||
glVertexAttribPointer(glGetAttribLocation(shd, "normal"), 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, normal));
|
||||
glVertexAttribPointer(glGetAttribLocation(shd, "uv0"), 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, uv0));
|
||||
glVertexAttribPointer(glGetAttribLocation(shd, "tangent"), 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, tangent));
|
||||
glVertexAttribPointer(glGetAttribLocation(shd, "bitangent"), 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, bitangent));
|
||||
glVertexAttribPointer(glGetAttribLocation(shd, "color"), 4, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, color));
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
glEnableVertexAttribArray(3);
|
||||
glEnableVertexAttribArray(4);
|
||||
glEnableVertexAttribArray(5);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
_shader.Disable();
|
||||
}
|
||||
|
||||
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;
|
||||
virtual void Render(const DefaultUniform& uniform) override {
|
||||
_shader.Use();
|
||||
|
||||
triangleIndex ++;
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, _diffuse.Reference());
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, _roughness.Reference());
|
||||
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D, _normal.Reference());
|
||||
|
||||
_shader.Disable();
|
||||
|
||||
Mesh::Render(uniform);
|
||||
}
|
||||
|
||||
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);
|
||||
static void LoadResources() {
|
||||
_diffuse = Texture("diffuse.png");
|
||||
_roughness = Texture("roughness.png");
|
||||
_normal = Texture("normal.png");
|
||||
}
|
||||
|
||||
void CalculateTangents() {
|
||||
for(int i=0;i<_vertexData.size();i += 3) {
|
||||
VertexData& d0 = _vertexData.at(i + 0);
|
||||
VertexData& d1 = _vertexData.at(i + 1);
|
||||
VertexData& d2 = _vertexData.at(i + 2);
|
||||
|
||||
glm::vec3 deltaPos1 = d1.position - d0.position;
|
||||
glm::vec3 deltaPos2 = d2.position - d0.position;
|
||||
|
||||
glm::vec2 deltaUV1 = d1.uv0 - d0.uv0;
|
||||
glm::vec2 deltaUV2 = d2.uv0 - d0.uv0;
|
||||
|
||||
float r = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV1.y * deltaUV2.x);
|
||||
d0.tangent = (deltaPos1 * deltaUV2.y - deltaPos2 * deltaUV1.y) * r;
|
||||
d0.bitangent = (deltaPos2 * deltaUV1.x - deltaPos1 * deltaUV2.x) * r;
|
||||
d1.tangent = (deltaPos1 * deltaUV2.y - deltaPos2 * deltaUV1.y) * r;
|
||||
d1.bitangent = (deltaPos2 * deltaUV1.x - deltaPos1 * deltaUV2.x) * r;
|
||||
d2.tangent = (deltaPos1 * deltaUV2.y - deltaPos2 * deltaUV1.y) * r;
|
||||
d2.bitangent = (deltaPos2 * deltaUV1.x - deltaPos1 * deltaUV2.x) * r;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -61,40 +135,45 @@ constexpr glm::vec3 SideToDirection[6] = {
|
||||
glm::vec3(0.0f, 0.0f, 1.0f),
|
||||
};
|
||||
|
||||
class PartitionedCube
|
||||
class Cube;
|
||||
|
||||
class PartitionedCube : public Entity
|
||||
{
|
||||
private:
|
||||
glm::mat4 _transform;
|
||||
glm::mat4 _transformTem;
|
||||
|
||||
glm::mat4 _animationTransformInvoke;
|
||||
glm::quat _animationTransform;
|
||||
float _animationTime;
|
||||
float _animationTimeExtend;
|
||||
bool _animationFinished;
|
||||
|
||||
Color _faces[6];
|
||||
MeshData _meshData;
|
||||
PartitionedCubeMesh _mesh;
|
||||
|
||||
public:
|
||||
PartitionedCube(const glm::vec3& position, Color sideColors[6]);
|
||||
PartitionedCube(Cube* parent, const glm::vec3& position, Color* sideColors);
|
||||
|
||||
void Update(double deltaTime);
|
||||
void Update(double deltaTime) override;
|
||||
void Render(DefaultUniform& uniform) override;
|
||||
|
||||
const glm::mat4 Transform() const {
|
||||
const glm::mat4 TransformCustom() const {
|
||||
// Need to use slerp since rotations are non-linear and would not interpolate this way
|
||||
//
|
||||
// However a lerp can be used and then normalized, with not that much of an
|
||||
// error but being much more performant thus preferred function
|
||||
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));
|
||||
glm::mat4 animationView = glm::mat4_cast(glm::normalize(glm::lerp(glm::quat(1.0f, 0.0f, 0.0f, 0.0f), _animationTransform, lerpFactor)));
|
||||
|
||||
return animationView * _animationTransformInvoke;
|
||||
return Parent()->LocalToWorld() * animationView * LocalObjectTransform();
|
||||
}
|
||||
|
||||
return _transform;
|
||||
return Parent()->LocalToWorld() * _transformTem * LocalObjectTransform();
|
||||
}
|
||||
|
||||
const MeshData& MeshData() const { return _meshData; };
|
||||
|
||||
void Transform(glm::mat4 transformation);
|
||||
void TransformAnimation(const glm::mat4& transform, float duration);
|
||||
void TransformData(const glm::ivec3& axis, int turns);
|
||||
void TransformAnimation(const glm::quat& transform, float duration);
|
||||
void TransformTemp(const glm::mat4& transform);
|
||||
void UndoTransformTemp();
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <glm.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
class Plane
|
||||
{
|
||||
|
||||
@ -8,6 +8,8 @@
|
||||
#include "GameInterface.h"
|
||||
#include "SceneInterface.h"
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb_image.h>
|
||||
|
||||
|
||||
|
||||
|
||||
@ -71,10 +71,10 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ExternalIncludePath>$(SolutionDir)/../ExternalResources/glew/include;$(SolutionDir)/../ExternalResources/glfw/include;$(SolutionDir)/../ExternalResources/glm/glm;$(SolutionDir)/../ExternalResources/stb;$(ExternalIncludePath)</ExternalIncludePath>
|
||||
<ExternalIncludePath>$(SolutionDir)/../ExternalResources/glew/include;$(SolutionDir)/../ExternalResources/glfw/include;$(SolutionDir)/../ExternalResources/glm;$(SolutionDir)/../ExternalResources/stb;$(ExternalIncludePath)</ExternalIncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ExternalIncludePath>$(SolutionDir)/../ExternalResources/glew/include;$(SolutionDir)/../ExternalResources/glfw/include;$(SolutionDir)/../ExternalResources/glm/glm;$(SolutionDir)/../ExternalResources/stb;$(ExternalIncludePath)</ExternalIncludePath>
|
||||
<ExternalIncludePath>$(SolutionDir)/../ExternalResources/glew/include;$(SolutionDir)/../ExternalResources/glfw/include;$(SolutionDir)/../ExternalResources/glm;$(SolutionDir)/../ExternalResources/stb;$(ExternalIncludePath)</ExternalIncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
@ -110,6 +110,7 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -126,6 +127,7 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -139,30 +141,36 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Color.cpp" />
|
||||
<ClCompile Include="Cube.cpp" />
|
||||
<ClCompile Include="Debug.cpp" />
|
||||
<ClCompile Include="Entity.cpp" />
|
||||
<ClCompile Include="GameInterface.cpp" />
|
||||
<ClCompile Include="InputSystem.cpp" />
|
||||
<ClCompile Include="KeyObserver.cpp" />
|
||||
<ClCompile Include="Mesh.cpp" />
|
||||
<ClCompile Include="PartitionedCube.cpp" />
|
||||
<ClCompile Include="Plane.cpp" />
|
||||
<ClCompile Include="RubiksCube.cpp" />
|
||||
<ClCompile Include="SceneInterface.cpp" />
|
||||
<ClCompile Include="Shader.cpp" />
|
||||
<ClCompile Include="ShaderUtil.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Camera.h" />
|
||||
<ClInclude Include="Color.h" />
|
||||
<ClInclude Include="Cube.h" />
|
||||
<ClInclude Include="Debug.h" />
|
||||
<ClInclude Include="Entity.h" />
|
||||
<ClInclude Include="GameInterface.h" />
|
||||
<ClInclude Include="InputSystem.h" />
|
||||
<ClInclude Include="KeyObserver.h" />
|
||||
<ClInclude Include="MeshData.h" />
|
||||
<ClInclude Include="Mesh.h" />
|
||||
<ClInclude Include="PartitionedCube.h" />
|
||||
<ClInclude Include="Plane.h" />
|
||||
<ClInclude Include="SceneInterface.h" />
|
||||
<ClInclude Include="Settings.h" />
|
||||
<ClInclude Include="Shader.h" />
|
||||
<ClInclude Include="ShaderUtil.h" />
|
||||
<ClInclude Include="Side.h" />
|
||||
<ClInclude Include="VertexData.h" />
|
||||
<ClInclude Include="Texture.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CopyFileToFolders Include="cube.frag">
|
||||
@ -176,6 +184,40 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</CopyFileToFolders>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CopyFileToFolders Include="line.frag">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||
<FileType>Document</FileType>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</CopyFileToFolders>
|
||||
<CopyFileToFolders Include="line.vert">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||
<FileType>Document</FileType>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</CopyFileToFolders>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CopyFileToFolders Include="normal.png">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</CopyFileToFolders>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CopyFileToFolders Include="diffuse.png">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</CopyFileToFolders>
|
||||
<CopyFileToFolders Include="roughness.png">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</CopyFileToFolders>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CopyFileToFolders Include="diffuse_test.png">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||
</CopyFileToFolders>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
||||
@ -36,9 +36,6 @@
|
||||
<ClCompile Include="Color.cpp">
|
||||
<Filter>Quelldateien</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Shader.cpp">
|
||||
<Filter>Quelldateien</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ShaderUtil.cpp">
|
||||
<Filter>Quelldateien</Filter>
|
||||
</ClCompile>
|
||||
@ -51,6 +48,15 @@
|
||||
<ClCompile Include="Plane.cpp">
|
||||
<Filter>Quelldateien</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Debug.cpp">
|
||||
<Filter>Quelldateien</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Mesh.cpp">
|
||||
<Filter>Quelldateien</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Entity.cpp">
|
||||
<Filter>Quelldateien</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="GameInterface.h">
|
||||
@ -68,15 +74,6 @@
|
||||
<ClInclude Include="Color.h">
|
||||
<Filter>Headerdateien</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Shader.h">
|
||||
<Filter>Headerdateien</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="VertexData.h">
|
||||
<Filter>Headerdateien</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MeshData.h">
|
||||
<Filter>Headerdateien</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Side.h">
|
||||
<Filter>Headerdateien</Filter>
|
||||
</ClInclude>
|
||||
@ -92,6 +89,27 @@
|
||||
<ClInclude Include="Plane.h">
|
||||
<Filter>Headerdateien</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Debug.h">
|
||||
<Filter>Headerdateien</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Settings.h">
|
||||
<Filter>Headerdateien</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Mesh.h">
|
||||
<Filter>Headerdateien</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Texture.h">
|
||||
<Filter>Headerdateien</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Shader.h">
|
||||
<Filter>Headerdateien</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Entity.h">
|
||||
<Filter>Headerdateien</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Camera.h">
|
||||
<Filter>Headerdateien</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CopyFileToFolders Include="cube.frag">
|
||||
@ -100,5 +118,23 @@
|
||||
<CopyFileToFolders Include="cube.vert">
|
||||
<Filter>Shaders</Filter>
|
||||
</CopyFileToFolders>
|
||||
<CopyFileToFolders Include="line.frag">
|
||||
<Filter>Shaders</Filter>
|
||||
</CopyFileToFolders>
|
||||
<CopyFileToFolders Include="line.vert">
|
||||
<Filter>Shaders</Filter>
|
||||
</CopyFileToFolders>
|
||||
<CopyFileToFolders Include="normal.png">
|
||||
<Filter>Ressourcendateien</Filter>
|
||||
</CopyFileToFolders>
|
||||
<CopyFileToFolders Include="diffuse.png">
|
||||
<Filter>Ressourcendateien</Filter>
|
||||
</CopyFileToFolders>
|
||||
<CopyFileToFolders Include="roughness.png">
|
||||
<Filter>Ressourcendateien</Filter>
|
||||
</CopyFileToFolders>
|
||||
<CopyFileToFolders Include="diffuse_test.png">
|
||||
<Filter>Ressourcendateien</Filter>
|
||||
</CopyFileToFolders>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -6,9 +6,10 @@
|
||||
|
||||
#include "Plane.h"
|
||||
|
||||
#include <glm.hpp>
|
||||
#include <ext.hpp>
|
||||
#include <gtx/string_cast.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/ext.hpp>
|
||||
#include <glm/gtx/string_cast.hpp>
|
||||
|
||||
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
@ -16,6 +17,20 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
SceneInterface::SceneInterface()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SceneInterface::~SceneInterface()
|
||||
{
|
||||
for(Entity* entity : _entities) {
|
||||
delete entity;
|
||||
}
|
||||
|
||||
delete currentAction;
|
||||
}
|
||||
|
||||
void SceneInterface::Initialize(GLFWwindow* window)
|
||||
{
|
||||
_inputSystem.SetWindow(window);
|
||||
@ -39,23 +54,31 @@ void SceneInterface::Initialize(GLFWwindow* window)
|
||||
_inputSystem.ObserveKey(GLFW_KEY_KP_9);
|
||||
|
||||
_wasMouseDown = false;
|
||||
|
||||
this->_shaderProgram = ShaderUtil::CreateShaderProgram("cube.vert", "cube.frag");
|
||||
this->_transformLocation = glGetUniformLocation(this->_shaderProgram, "transformation");
|
||||
|
||||
glGenVertexArrays(1, &this->_arrayBufferObject);
|
||||
glGenBuffers(1, &this->_vertexBufferObject);
|
||||
|
||||
glBindVertexArray(_arrayBufferObject);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, this->_vertexBufferObject);
|
||||
|
||||
glVertexAttribPointer(glGetAttribLocation(_shaderProgram, "position"), 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, position));
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(glGetAttribLocation(_shaderProgram, "color"), 4, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)offsetof(VertexData, color));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
_debug = new Debug(window);
|
||||
|
||||
PartitionedCubeMesh::LoadResources();
|
||||
|
||||
_camera = new Camera(window, &_inputSystem);
|
||||
Cube* cube = new Cube();
|
||||
_cube = cube;
|
||||
|
||||
_entities.push_back(_debug);
|
||||
_entities.push_back(_camera);
|
||||
_entities.push_back(_cube);
|
||||
|
||||
for(PartitionedCube** cube = _cube->Children();cube != _cube->Children() + _cube->ChildPartitionsCount;cube++) {
|
||||
_entities.push_back(*cube);
|
||||
}
|
||||
|
||||
std::cout << "Controls: " << std::endl;
|
||||
std::cout << "Numpad 1, 2, 3, 7, 8, 9 + Shift Rotate X Axis Down Up View" << std::endl;
|
||||
std::cout << "Numpad 1, 4, 7, 3, 6, 9 Rotate Y Axis Left Right View" << std::endl;
|
||||
std::cout << "Arrows Up, Down, Right, Left Rotate Camera relative lookat" << std::endl;
|
||||
std::cout << "Space Reset Look Changes" << std::endl;
|
||||
std::cout << "Mouse Scroll Vertically Zoom" << std::endl;
|
||||
std::cout << "Left Mouse Rotate Cube Planes" << std::endl;
|
||||
std::cout << "Right Mouse Rotate Camera" << std::endl;
|
||||
}
|
||||
|
||||
glm::vec3 basisCoordinateVectors[] = {
|
||||
@ -113,33 +136,19 @@ void IntersectLinePlane(const glm::vec3& lineStart, const glm::vec3& lineDirecti
|
||||
}
|
||||
}
|
||||
|
||||
void SceneInterface::EnqueueAction(const Action& action) {
|
||||
void SceneInterface::EnqueueAction(Action* action) {
|
||||
_actions.push(action);
|
||||
}
|
||||
|
||||
void SceneInterface::Update(float deltaTime)
|
||||
{
|
||||
_cube.Update(deltaTime);
|
||||
_inputSystem.Update();
|
||||
|
||||
if (_inputSystem.WasKeyPressed(GLFW_KEY_SPACE))
|
||||
_orientation = glm::quat(1.0f, glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
for(Entity* entity : _entities) {
|
||||
entity->Update(deltaTime);
|
||||
}
|
||||
|
||||
glm::fvec2 velocity(0.0f, 0.0f);
|
||||
if (_inputSystem.IsKeyPressed(GLFW_KEY_UP))
|
||||
velocity.x = glm::radians(90.0f);
|
||||
if (_inputSystem.IsKeyPressed(GLFW_KEY_DOWN))
|
||||
velocity.x = glm::radians(-90.0f);
|
||||
|
||||
if (_inputSystem.IsKeyPressed(GLFW_KEY_RIGHT))
|
||||
velocity.y = glm::radians(90.0f);
|
||||
if (_inputSystem.IsKeyPressed(GLFW_KEY_LEFT))
|
||||
velocity.y = glm::radians(-90.0f);
|
||||
|
||||
glm::quat velocityQuaternion = glm::quat(0.0f, glm::vec3(velocity.x, velocity.y, 0.0f));
|
||||
|
||||
_orientation += 0.5f * (float)deltaTime * velocityQuaternion * _orientation;
|
||||
_orientation = glm::normalize(_orientation);
|
||||
|
||||
|
||||
// int spinIndex = 0;
|
||||
|
||||
@ -170,49 +179,98 @@ void SceneInterface::Update(float deltaTime)
|
||||
int axisIndex = spinAxis.x == 0; // x => 0, y => 1
|
||||
int spinIndex = keyToIndex[axisIndex][rotationKey - 1];
|
||||
|
||||
if (reverse)
|
||||
spinAxis *= -1;
|
||||
int reverseSign = reverse ? -1 : 1;
|
||||
|
||||
spinAxis *= reverseSign;
|
||||
spinIndex *= reverseSign;
|
||||
|
||||
glm::mat3 cubeMat = glm::mat3(_cube->LocalToWorld()) * glm::mat3(_camera->View());
|
||||
|
||||
glm::mat3 orthogonalized = cubeMat;
|
||||
for(int column=0;column<3;column++) {
|
||||
int nearestCardinalisedAxis = 0;
|
||||
for(int i=0;i<3;i++) {
|
||||
if (glm::abs(orthogonalized[column][i]) > glm::abs(orthogonalized[column][nearestCardinalisedAxis])) {
|
||||
nearestCardinalisedAxis = i;
|
||||
}
|
||||
}
|
||||
|
||||
for(int columnToPlace=0;columnToPlace<3;columnToPlace++) {
|
||||
for(int i=0;i<3;i++) {
|
||||
if (columnToPlace == column) {
|
||||
if (nearestCardinalisedAxis == i) {
|
||||
orthogonalized[columnToPlace][i] = glm::sign(orthogonalized[columnToPlace][i]);
|
||||
}
|
||||
else {
|
||||
orthogonalized[columnToPlace][i] = 0.0f;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (nearestCardinalisedAxis == i) {
|
||||
orthogonalized[columnToPlace][i] = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glm::mat3 screenToCube = glm::inverse(orthogonalized);
|
||||
|
||||
spinAxis = screenToCube * spinAxis;
|
||||
int direction = spinAxis.x + spinAxis.y + spinAxis.z;
|
||||
|
||||
EnqueueAction(new ActionSpinDefault(_cube, spinAxis, spinIndex, 1.0f));
|
||||
|
||||
// _cube.TransformAnimation(cubeSpinAxis, spinIndex, rotation, 1.0f);
|
||||
|
||||
EnqueueAction(Action(spinAxis, spinIndex, 1.0f));
|
||||
|
||||
std::cout << glm::to_string(spinAxis) << " " << spinIndex << std::endl;
|
||||
}
|
||||
|
||||
if (!_wasMouseDown && _inputSystem.IsLeftMouseDown()) {
|
||||
OnDragStart();
|
||||
if (currentAction == nullptr) {
|
||||
if (!_wasMouseDown && _inputSystem.IsLeftMouseDown()) {
|
||||
OnDragStart();
|
||||
}
|
||||
else if (_wasMouseDown && !_inputSystem.IsLeftMouseDown()) {
|
||||
OnDragStop();
|
||||
}
|
||||
else if (_wasMouseDown && _inputSystem.IsLeftMouseDown()) {
|
||||
OnDrag(deltaTime);
|
||||
}
|
||||
|
||||
_wasMouseDown = _inputSystem.IsLeftMouseDown();
|
||||
}
|
||||
else if (_wasMouseDown && !_inputSystem.IsLeftMouseDown()) {
|
||||
OnDragStop();
|
||||
}
|
||||
else if (_wasMouseDown && _inputSystem.IsLeftMouseDown()) {
|
||||
OnDrag(deltaTime);
|
||||
|
||||
if (currentAction != nullptr) {
|
||||
currentAction->duration -= deltaTime;
|
||||
}
|
||||
|
||||
_wasMouseDown = _inputSystem.IsLeftMouseDown();
|
||||
if (currentAction != nullptr && currentAction->duration > 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentAction.duration -= deltaTime;
|
||||
if (currentAction.duration <= 0.0f && _actions.size() > 0) {
|
||||
Action& action = _actions.front();
|
||||
if (_actions.size() > 0) {
|
||||
delete currentAction;
|
||||
|
||||
Action* action = _actions.front();
|
||||
_actions.pop();
|
||||
|
||||
ApplyAction(action);
|
||||
}
|
||||
else {
|
||||
currentAction = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void SceneInterface::OnDragStart() {
|
||||
_inputSystem.GetMousePos(_initialMouseLocation);
|
||||
|
||||
Plane planes[6];
|
||||
|
||||
glm::vec3 lineStart;
|
||||
glm::vec3 lineDirection;
|
||||
glm::mat4 viewPerspective = _perspective * _view;
|
||||
glm::mat4 viewPerspective = _camera->Projection() * _camera->View();
|
||||
|
||||
_inputSystem.GetPickingRay(viewPerspective, lineStart, lineDirection);
|
||||
|
||||
glm::mat4 transform = glm::mat4(1.0f);
|
||||
glm::mat4 transform = _cube->LocalToWorld();
|
||||
|
||||
for(int axis=0;axis<3;axis++) {
|
||||
for(int direction=-1;direction<=1;direction+=2) {
|
||||
@ -252,7 +310,7 @@ void SceneInterface::OnDrag(double deltaTime) {
|
||||
|
||||
glm::vec3 lineStart;
|
||||
glm::vec3 lineDirection;
|
||||
glm::mat4 transform = _perspective * _view;
|
||||
glm::mat4 transform = _camera->Projection() * _camera->View();
|
||||
_inputSystem.GetPickingRay(transform, lineStart, lineDirection);
|
||||
|
||||
float intersectionDistance = -1.0f;
|
||||
@ -269,7 +327,7 @@ void SceneInterface::OnDrag(double deltaTime) {
|
||||
float dragAbsDistance = abs(glm::distance(glm::vec2(0.0f), directionPlane));
|
||||
|
||||
if (dragAbsDistance >= MIN_DRAG_MAGNITUDE) {
|
||||
glm::vec3 mousePosition = glm::inverse(planeTransform) * glm::vec4(_mousePositionPlane, 0.0f, 1.0f);
|
||||
glm::vec3 mousePosition = planeTransform * glm::vec4(_mousePositionPlane, 0.0f, 1.0f);
|
||||
|
||||
glm::vec3 direction = glm::inverse(planeTransform) * glm::vec4(directionPlane, 0.0f, 0.0f);
|
||||
|
||||
@ -279,113 +337,76 @@ void SceneInterface::OnDrag(double deltaTime) {
|
||||
axisSingle = orthogonalise(axisSingle);
|
||||
|
||||
float projection = glm::dot(mousePosition, axisSingle);
|
||||
|
||||
|
||||
int index = floor((projection + 0.5f));
|
||||
|
||||
glm::ivec3 axis = orthogonalise(axisSingle);
|
||||
|
||||
std::cout << glm::to_string(axisSingle) << std::endl;
|
||||
std::cout << glm::to_string(direction) << std::endl;
|
||||
std::cout << glm::to_string(axis) << std::endl;
|
||||
_cube->UndoTransformTemp();
|
||||
|
||||
_cube.TransformTemp(axis, index, glm::rotate(glm::mat4(1.0f), glm::radians(abs(glm::distance(glm::vec2(0.0f), directionPlane))), axisSingle));
|
||||
float angle = glm::radians(90.0f * ( 1.0f / 3.0f ) * abs(glm::distance(glm::vec2(0.0f), directionPlane)));
|
||||
|
||||
_cube->TransformTemp(axis, index, glm::rotate(glm::mat4(1.0f), angle, axisSingle));
|
||||
_spinIndex = index;
|
||||
_spinAxis = axis;
|
||||
_spinDelta = angle;
|
||||
}
|
||||
}
|
||||
|
||||
const float rotations = 2 * glm::pi<float>();
|
||||
|
||||
const float quarterRotation = rotations * 0.25f;
|
||||
|
||||
void SceneInterface::OnDragStop() {
|
||||
// Undo any temporarilies
|
||||
_cube->UndoTransformTemp();
|
||||
|
||||
// Transform Instantly to current angle
|
||||
_cube->Transform(_spinAxis, _spinIndex, glm::rotate(glm::mat4(1.0f), _spinDelta, glm::vec3(_spinAxis)));
|
||||
|
||||
float angleNormalized = std::fmodf(_spinDelta, quarterRotation);
|
||||
|
||||
float remainingAngle = 0.5f - glm::abs(angleNormalized - quarterRotation * 0.5f);
|
||||
|
||||
float remainingFactor = remainingAngle / quarterRotation;
|
||||
|
||||
int rotations = round(_spinDelta / quarterRotation);
|
||||
|
||||
// remaining rotation animating
|
||||
if (_spinDelta > 0.0f && rotations > 0) {
|
||||
EnqueueAction(new ActionSpinAfterDragging(_cube, _spinAxis, _spinIndex, ( quarterRotation * rotations ) - _spinDelta, rotations, remainingFactor * 1.0f));
|
||||
}
|
||||
else {
|
||||
EnqueueAction(new ActionSpinAfterDragging(_cube, _spinAxis, _spinIndex, -( _spinDelta ), rotations, remainingFactor * 1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
void SceneInterface::ApplyAction(const Action& action) {
|
||||
void SceneInterface::ApplyAction(Action* action) {
|
||||
currentAction = action;
|
||||
|
||||
glm::mat3 cubeMat = _cube.Transform() * glm::mat4_cast(_orientation);
|
||||
|
||||
glm::mat3 orthogonalized = cubeMat;
|
||||
for(int column=0;column<3;column++) {
|
||||
int nearestCardinalisedAxis = 0;
|
||||
for(int i=0;i<3;i++) {
|
||||
if (glm::abs(orthogonalized[column][i]) > glm::abs(orthogonalized[column][nearestCardinalisedAxis])) {
|
||||
nearestCardinalisedAxis = i;
|
||||
}
|
||||
}
|
||||
|
||||
for(int columnToPlace=0;columnToPlace<3;columnToPlace++) {
|
||||
for(int i=0;i<3;i++) {
|
||||
if (columnToPlace == column) {
|
||||
if (nearestCardinalisedAxis == i) {
|
||||
orthogonalized[columnToPlace][i] = glm::sign(orthogonalized[columnToPlace][i]);
|
||||
}
|
||||
else {
|
||||
orthogonalized[columnToPlace][i] = 0.0f;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (nearestCardinalisedAxis == i) {
|
||||
orthogonalized[columnToPlace][i] = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 axis = action.axis;
|
||||
|
||||
int direction = axis.x + axis.y + axis.z;
|
||||
|
||||
axis = glm::inverse(orthogonalized) * axis;
|
||||
|
||||
int index = action.index;
|
||||
index *= direction;
|
||||
|
||||
glm::mat4 rotationMat = glm::rotate(glm::mat4(1.0f), glm::radians(90.0f), axis);
|
||||
for(int i=0;i<3;i++) {
|
||||
for(int g=0;g<3;g++) {
|
||||
rotationMat[i][g] = round(rotationMat[i][g]);
|
||||
}
|
||||
}
|
||||
glm::imat3x3 rotation = glm::imat3x3(rotationMat);
|
||||
|
||||
_cube.TransformAnimation(axis, index, rotation, action.duration);
|
||||
action->Invoke();
|
||||
}
|
||||
|
||||
void SceneInterface::Render(float aspectRatio) {
|
||||
glUseProgram(_shaderProgram);
|
||||
glBindVertexArray(this->_arrayBufferObject);
|
||||
if (_camera == nullptr)
|
||||
return;
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, this->_vertexBufferObject);
|
||||
DefaultUniform uniform;
|
||||
uniform.view = _camera->View();
|
||||
uniform.projection = _camera->Projection();
|
||||
|
||||
_view = glm::lookAt(glm::vec3(0.0f, 0.0f, 4.75f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f)) * glm::mat4_cast(_orientation);
|
||||
_perspective = glm::perspective(glm::radians(45.0f), aspectRatio, 0.1f, 100.0f);
|
||||
for(Entity* entity : _entities) {
|
||||
uniform.model = entity->LocalToWorld();
|
||||
|
||||
auto transformation = _perspective * _view;
|
||||
entity->Render(uniform);
|
||||
}
|
||||
|
||||
// std::cout << "perspective: " << glm::to_string(glm::perspective(glm::radians(45.0f), aspectRatio, 0.1f, 100.0f)) << std::endl;
|
||||
// std::cout << "view : " << glm::to_string(glm::lookAt(glm::vec3(0.0f, 0.0f, -3.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f))) << std::endl;
|
||||
// std::cout << "model : " << glm::to_string(_cube.Transform()) << std::endl;
|
||||
|
||||
for(int i=0;i<_cube.ChildPartitionsCount;i++) {
|
||||
const PartitionedCube* cube = _cube.Children()[i];
|
||||
|
||||
const MeshData& meshData = cube->MeshData();
|
||||
|
||||
const glm::vec3& position = meshData.data[0].position;
|
||||
|
||||
auto localTransform = transformation * cube->Transform();
|
||||
|
||||
glUniformMatrix4fv(_transformLocation, 1, GL_FALSE, glm::value_ptr(localTransform));
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexData) * meshData.vertexIndex, meshData.data.data(), GL_STATIC_DRAW);
|
||||
glDrawArrays(GL_TRIANGLES, 0, meshData.vertexIndex);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
void SceneInterface::ClearResources()
|
||||
{
|
||||
glDeleteBuffers(1, &_vertexBufferObject);
|
||||
glDeleteVertexArrays(1, &_arrayBufferObject);
|
||||
glDeleteProgram(_shaderProgram);
|
||||
|
||||
}
|
||||
|
||||
@ -2,69 +2,109 @@
|
||||
|
||||
#include <queue>
|
||||
|
||||
#include "Debug.h"
|
||||
#include "Plane.h"
|
||||
#include "InputSystem.h"
|
||||
#include "GameInterface.h"
|
||||
#include "Camera.h"
|
||||
#include "Shader.h"
|
||||
#include "Cube.h"
|
||||
|
||||
#include <ext/quaternion_float.hpp>
|
||||
#include <glm/ext/quaternion_float.hpp>
|
||||
|
||||
#include <gl/glew.h>
|
||||
|
||||
struct Action {
|
||||
glm::ivec3 axis;
|
||||
int index;
|
||||
protected:
|
||||
Cube* _cube;
|
||||
|
||||
public:
|
||||
double duration;
|
||||
|
||||
Action() : axis(glm::ivec3(0)), index(0), duration(0.0f) { }
|
||||
Action(Cube* cube, double duration) : _cube(cube), duration(duration) { }
|
||||
virtual void Invoke() = 0;
|
||||
};
|
||||
|
||||
Action(const glm::ivec3& axis, int index, double duration)
|
||||
: axis(axis), index(index), duration(duration) {
|
||||
struct ActionSpinDefault : public Action {
|
||||
glm::ivec3 axis;
|
||||
int index;
|
||||
|
||||
ActionSpinDefault() : Action(nullptr, 0.0f), axis(glm::ivec3(0)), index(0) { }
|
||||
|
||||
ActionSpinDefault(Cube* cube, const glm::ivec3& axis, int index, double duration)
|
||||
: Action(cube, duration), axis(axis), index(index) {
|
||||
|
||||
}
|
||||
|
||||
void Invoke() override {
|
||||
_cube->TransformAnimation(axis, index, glm::radians(90.0f), duration);
|
||||
|
||||
_cube->TransformData(axis, index, 1);
|
||||
}
|
||||
};
|
||||
|
||||
struct ActionSpinAfterDragging : public Action {
|
||||
glm::ivec3 axis;
|
||||
int index;
|
||||
float angle;
|
||||
int turns;
|
||||
|
||||
ActionSpinAfterDragging() : Action(nullptr, 0.0f), axis(glm::ivec3(0)), index(0), angle(0.0f), turns(0) { }
|
||||
|
||||
ActionSpinAfterDragging(Cube* cube, const glm::ivec3& axis, int index, float angle, int turns, double duration)
|
||||
: Action(cube, duration), axis(axis), index(index), angle(angle), turns(turns) {
|
||||
|
||||
}
|
||||
|
||||
void Invoke() override {
|
||||
_cube->TransformAnimation(axis, index, angle, duration);
|
||||
|
||||
_cube->TransformData(axis, index, turns);
|
||||
}
|
||||
};
|
||||
|
||||
class SceneInterface : public GameInterface
|
||||
{
|
||||
private:
|
||||
Cube _cube;
|
||||
std::queue<Action> _actions;
|
||||
Action currentAction;
|
||||
Cube* _cube;
|
||||
Camera* _camera;
|
||||
|
||||
std::vector<Entity*> _entities;
|
||||
|
||||
std::queue<Action*> _actions;
|
||||
Action* currentAction;
|
||||
|
||||
Debug* _debug;
|
||||
|
||||
InputSystem _inputSystem;
|
||||
|
||||
glm::quat _orientation;
|
||||
|
||||
bool _wasMouseDown;
|
||||
glm::vec2 _initialMouseLocation;
|
||||
Plane _plane;
|
||||
glm::vec2 _mousePositionPlane;
|
||||
|
||||
glm::mat4 _view;
|
||||
glm::mat4 _perspective;
|
||||
|
||||
GLuint _shaderProgram;
|
||||
GLuint _transformLocation;
|
||||
GLuint _arrayBufferObject;
|
||||
GLuint _vertexBufferObject;
|
||||
int _spinIndex;
|
||||
glm::ivec3 _spinAxis;
|
||||
float _spinDelta;
|
||||
|
||||
const float MIN_DRAG_MAGNITUDE = 0.16f;
|
||||
|
||||
void ApplyAction(const Action& action);
|
||||
void ApplyAction(Action* action);
|
||||
|
||||
void OnDragStart();
|
||||
void OnDrag(double deltaTime);
|
||||
void OnDragStop();
|
||||
|
||||
public:
|
||||
SceneInterface();
|
||||
~SceneInterface();
|
||||
|
||||
void Initialize(GLFWwindow* window) override;
|
||||
|
||||
void Update(float deltaTime) override;
|
||||
void Render(float aspectRatio) override;
|
||||
|
||||
void EnqueueAction(const Action& action);
|
||||
void EnqueueAction(Action* action);
|
||||
|
||||
void ClearResources() override;
|
||||
};
|
||||
|
||||
|
||||
12
RubiksCube/Settings.h
Normal file
12
RubiksCube/Settings.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
const bool ENABLE_DEBUG = true;
|
||||
|
||||
namespace Settings {
|
||||
const float TURN_ANIMATION_DURATION = 1.25f;
|
||||
const float MIN_TURN_DISTANCE = 3.0f;
|
||||
|
||||
const float MIN_CAMERA_DISTANCE = 4.2f;
|
||||
const float MAX_CAMERA_DISTANCE = 10.0f;
|
||||
const float CAMERA_DISTANCE_START = 8.0f;
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
#include "Shader.h"
|
||||
@ -1,5 +1,45 @@
|
||||
#pragma once
|
||||
class Shader
|
||||
{
|
||||
};
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "ShaderUtil.h"
|
||||
|
||||
class Shader {
|
||||
private:
|
||||
const char* _vert;
|
||||
const char* _frag;
|
||||
|
||||
GLuint _id;
|
||||
|
||||
public:
|
||||
Shader(const char* vert, const char* frag) : _vert(vert), _frag(frag), _id(0) {
|
||||
|
||||
}
|
||||
|
||||
~Shader() {
|
||||
if (_id != 0) {
|
||||
glDeleteProgram(_id);
|
||||
}
|
||||
}
|
||||
|
||||
GLuint Reference() const { return _id; }
|
||||
|
||||
void Initialize() {
|
||||
if (_id != 0)
|
||||
return;
|
||||
|
||||
_id = ShaderUtil::CreateShaderProgram(_vert, _frag);
|
||||
}
|
||||
|
||||
void Use() {
|
||||
Initialize();
|
||||
|
||||
glUseProgram(_id);
|
||||
}
|
||||
|
||||
void Disable() {
|
||||
Initialize();
|
||||
|
||||
glUseProgram(0);
|
||||
}
|
||||
};
|
||||
|
||||
97
RubiksCube/Texture.h
Normal file
97
RubiksCube/Texture.h
Normal file
@ -0,0 +1,97 @@
|
||||
#pragma once
|
||||
|
||||
#include <stb_image.h>
|
||||
|
||||
#include <gl/glew.h>
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
class Texture {
|
||||
private:
|
||||
GLuint _id;
|
||||
|
||||
protected:
|
||||
const char* _texture;
|
||||
|
||||
public:
|
||||
GLuint Reference() const {
|
||||
return _id;
|
||||
}
|
||||
|
||||
public:
|
||||
Texture() : _id(0) { }
|
||||
|
||||
Texture(const char* file) {
|
||||
int width, height, len;
|
||||
|
||||
stbi_set_flip_vertically_on_load(1);
|
||||
unsigned char* data = stbi_load(file, &width, &height, &len, STBI_rgb_alpha);
|
||||
|
||||
glGenTextures(1, &_id);
|
||||
glBindTexture(GL_TEXTURE_2D, _id);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
stbi_image_free(data);
|
||||
}
|
||||
|
||||
Texture(const Texture& other) : Texture(other._texture) {
|
||||
|
||||
}
|
||||
|
||||
Texture& operator=(const Texture& other) {
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
Texture copy(other._texture);
|
||||
this->_id = other._id;
|
||||
this->_texture = other._texture;
|
||||
|
||||
copy._id = 0;
|
||||
copy._texture = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Texture(Texture&& other) noexcept {
|
||||
_id = other._id;
|
||||
_texture = other._texture;
|
||||
|
||||
other._id = 0;
|
||||
other._texture = nullptr;
|
||||
}
|
||||
|
||||
Texture& operator= (Texture&& other) noexcept {
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
this->_id = other._id;
|
||||
this->_texture = other._texture;
|
||||
|
||||
other._id = 0;
|
||||
other._texture = nullptr;
|
||||
}
|
||||
|
||||
~Texture() {
|
||||
if (_id == 0)
|
||||
return;
|
||||
|
||||
glDeleteTextures(1, &_id);
|
||||
}
|
||||
|
||||
void Use() const {
|
||||
glBindTexture(GL_TEXTURE_2D, _id);
|
||||
}
|
||||
|
||||
void Disable() const {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
};
|
||||
@ -1 +0,0 @@
|
||||
#pragma once
|
||||
@ -1,9 +1,45 @@
|
||||
#version 330
|
||||
|
||||
uniform mat4 view;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
in vec4 vertexColor;
|
||||
|
||||
in mat3 TBN;
|
||||
|
||||
in vec3 fPos;
|
||||
in vec2 TCordinate;
|
||||
|
||||
uniform sampler2D diffuse;
|
||||
uniform sampler2D roughness;
|
||||
uniform sampler2D normal;
|
||||
|
||||
const vec3 lightColor = vec3(1.0f, 1.0f, 1.0f);
|
||||
const vec3 lightDir = vec3(-1.0f, -1.0f, 1.0f);
|
||||
const float ambient = 0.24f;
|
||||
const float specularValue = 1.0f;
|
||||
|
||||
void main() {
|
||||
color = vertexColor;
|
||||
vec4 diffuseBase = texture(diffuse, TCordinate);
|
||||
|
||||
vec3 normal = texture(normal, TCordinate).rgb;
|
||||
normal = normal * 2.0f - 1.0f;
|
||||
normal = normalize(mat3(view) * TBN * normal);
|
||||
|
||||
vec3 lightNormal = normalize(vec3(view * vec4(lightDir, 0.0f)));
|
||||
|
||||
float diffValue = max(dot(normal, lightNormal), 0.0f);
|
||||
float diffuse = diffValue;
|
||||
|
||||
vec3 viewDir = normalize(-fPos);
|
||||
|
||||
vec3 reflectDir = reflect(-lightNormal, normal);
|
||||
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0f), 16);
|
||||
float specular = specularValue * spec;
|
||||
|
||||
float roughness = texture(roughness, TCordinate).g;
|
||||
|
||||
color = vertexColor * diffuseBase * vec4((ambient + diffuse) * lightColor, 1.0f) + vec4(roughness * specular * lightColor, 1.0f);
|
||||
}
|
||||
|
||||
@ -1,13 +1,34 @@
|
||||
#version 330
|
||||
|
||||
uniform mat4 transformation;
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
layout (location=0) in vec3 position;
|
||||
layout (location=1) in vec4 color;
|
||||
layout (location=1) in vec3 normal;
|
||||
layout (location=2) in vec2 uv0;
|
||||
layout (location=3) in vec3 tangent;
|
||||
layout (location=4) in vec3 bitangent;
|
||||
layout (location=5) in vec4 color;
|
||||
|
||||
out vec4 vertexColor;
|
||||
|
||||
out mat3 TBN;
|
||||
|
||||
out vec3 fPos;
|
||||
out vec2 TCordinate;
|
||||
|
||||
void main() {
|
||||
gl_Position = transformation * vec4(position, 1.0f);
|
||||
gl_Position = projection * view * model * vec4(position, 1.0f);
|
||||
|
||||
fPos = vec3(view * model * vec4(position, 1.0f));
|
||||
|
||||
vertexColor = color;
|
||||
|
||||
vec3 T = normalize(vec3(model * vec4(tangent, 0.0f)));
|
||||
vec3 B = normalize(vec3(model * vec4(bitangent, 0.0f)));
|
||||
vec3 N = normalize(vec3(model * vec4(normal, 0.0f)));
|
||||
TBN = mat3(T, B, N);
|
||||
|
||||
TCordinate = uv0;
|
||||
}
|
||||
|
||||
BIN
RubiksCube/diffuse.png
Normal file
BIN
RubiksCube/diffuse.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
BIN
RubiksCube/diffuse_test.png
Normal file
BIN
RubiksCube/diffuse_test.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
19
RubiksCube/line.frag
Normal file
19
RubiksCube/line.frag
Normal file
@ -0,0 +1,19 @@
|
||||
#version 330
|
||||
|
||||
const float blend = 1.5f;
|
||||
|
||||
in float lineStrength;
|
||||
|
||||
in vec4 color;
|
||||
in float lineWidth;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 col = color;
|
||||
float d = length(vec2(lineStrength) - gl_FragCoord.xy);
|
||||
float w = lineWidth;
|
||||
|
||||
fragColor = col;
|
||||
}
|
||||
69
RubiksCube/line.vert
Normal file
69
RubiksCube/line.vert
Normal file
@ -0,0 +1,69 @@
|
||||
#version 330
|
||||
|
||||
uniform vec2 uViewportRes;
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
layout (location = 0) in vec3 position;
|
||||
layout (location = 1) in vec3 tangent;
|
||||
layout (location = 2) in vec4 iColor;
|
||||
layout (location = 3) in float iLineWidth;
|
||||
|
||||
out vec4 color;
|
||||
out float lineWidth;
|
||||
out float lineStrength;
|
||||
|
||||
void main(void) {
|
||||
int index = gl_VertexID % 6;
|
||||
float orientation = 1.0f + ( (index % 2) * -2 );
|
||||
|
||||
vec4 positionScreen = projection * view * model * vec4(position, 1.0f);
|
||||
vec4 directionScreen = projection * view * model * vec4(position + tangent, 0.0f);
|
||||
|
||||
vec4 normal = positionScreen - directionScreen;
|
||||
|
||||
positionScreen.xyz /= positionScreen.w;
|
||||
positionScreen.xy *= (uViewportRes * 0.5f);
|
||||
|
||||
float aspectRatio = projection[1][1] / projection[0][0];
|
||||
|
||||
normal.xyz /= normal.w;
|
||||
positionScreen += vec4(normalize(normal.yx * vec2(-1.0f, 1.0f) * orientation), 0.0f, 0.0f) * 0.5f * iLineWidth;
|
||||
|
||||
positionScreen.xy /= (uViewportRes * 0.5f);
|
||||
positionScreen.xyz *= positionScreen.w;
|
||||
|
||||
|
||||
gl_Position = positionScreen;
|
||||
|
||||
lineWidth = iLineWidth;
|
||||
lineStrength = orientation;
|
||||
color = iColor;
|
||||
}
|
||||
|
||||
void mainBackup(void)
|
||||
{
|
||||
float aspectRatio = 0.0f;
|
||||
|
||||
int index = gl_VertexID % 6;
|
||||
float orientation = 1 + ( (index % 2) * -2 );
|
||||
|
||||
vec4 positionCamera = view * model * vec4(position, 1.0f);
|
||||
|
||||
float distance = -position.z;
|
||||
|
||||
vec4 tv = projection * view * model * vec4(position + tangent, 0.0f);
|
||||
|
||||
vec4 v = vec4(normalize(tv.yx) * orientation * vec2(-1.0f, 1.0f), 0.0f, 0.0f) * distance;
|
||||
|
||||
vec4 direction = positionCamera - tv;
|
||||
|
||||
direction.xy = direction.yx * vec2(-1.0f, 1.0f) * orientation;
|
||||
|
||||
gl_Position = (projection * positionCamera) + vec4(direction.xy, 0.0f, 0.0f);
|
||||
|
||||
lineWidth = iLineWidth;
|
||||
lineStrength = orientation;
|
||||
color = vec4(iColor.xyz, 1.0f);
|
||||
}
|
||||
BIN
RubiksCube/normal.png
Normal file
BIN
RubiksCube/normal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
RubiksCube/roughness.png
Normal file
BIN
RubiksCube/roughness.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
39
readme.txt
Normal file
39
readme.txt
Normal file
@ -0,0 +1,39 @@
|
||||
Rubiks Cube Projekt
|
||||
|
||||
|
||||
|
||||
Steuerung:
|
||||
|
||||
Linke Maustaste Halten und Ziehen Cube angeklickte Scheibe drehen
|
||||
Rechte Maustaste Halten und Ziehen Kamera drehen
|
||||
Scrollrad Zoom
|
||||
|
||||
Shift + Numpad 1, 2, 3 ( Numlock ausschalten! ) Cube Horizontal nach unten
|
||||
Shift + Numpad 7, 8, 9 ( Numlock ausschalten! ) Cube Horizontal nach oben
|
||||
Numpad 1, 4, 7 Cube vertikal links drehen
|
||||
Numpad 9, 6, 3 Cube vertikal rechts drehen
|
||||
|
||||
Space Ansicht ( Drehung ) zurücksetzen
|
||||
|
||||
Kurze Übersicht der Welt:
|
||||
Die Anwendung wird gestartet, mit der Kamera von vorne auf den Cube gerichtet.
|
||||
Der Cube bleibt im World-Space ohne Veränderungen.
|
||||
Die Kamera dreht sich um den Cube herum.
|
||||
Die Lichtquelle leuchtet von unten links und von vorne.
|
||||
|
||||
Features:
|
||||
- Logische Repräsentation
|
||||
- Tastatursteuerung
|
||||
- + Animations
|
||||
- Kamerasteuerung
|
||||
- Maussteuerung Kamerarelativ
|
||||
- + Animations
|
||||
|
||||
|
||||
|
||||
Rendering:
|
||||
- Directional Lighting
|
||||
- Blinn-Shading
|
||||
- Diffuse Texturierung
|
||||
- Normal Map mit Textur als Normal
|
||||
- Specular Map
|
||||
Loading…
x
Reference in New Issue
Block a user