hyporo-cpp/source/creator/transform.hpp
2023-04-10 22:01:56 +05:00

184 lines
5.7 KiB
C++

#pragma once
#include <hpr/math.hpp>
#include <hpr/gpu/shader_program.hpp>
#include "entity.hpp"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
class Transform
{
public:
enum Projection
{
Perspective,
Orthographic
};
protected:
Projection p_projection;
hpr::scalar p_distance;
hpr::scalar p_aspect;
hpr::scalar p_fieldOfView;
hpr::scalar p_nearPlane;
hpr::scalar p_farPlane;
hpr::vec3 p_target;
hpr::vec3 p_left;
hpr::vec3 p_front;
hpr::vec3 p_up;
hpr::vec3 p_rotation;
hpr::mat4 p_model;
Entity* p_entity;
hpr::vec3 p_position;
public:
inline Transform() = delete;
inline Transform(Entity* entity) :
p_projection {Orthographic},
p_distance {10},
p_aspect {800.f / 600},
p_fieldOfView {45},
p_nearPlane {0.1},
p_farPlane {100},
p_target {0, 0, 0},
p_left {1, 0, 0},
p_front {0, 0, -1},
p_up {0, 0, 1},
p_rotation {45, 45, 0},
p_model {hpr::mat4::identity()},
p_entity {entity},
p_position {}
{
//for (auto v : p_model)
// std::cout << v << std::endl;
}
hpr::mat4 view()
{
hpr::vec3 rotation {
hpr::cos(hpr::rad(p_rotation[1])) * hpr::sin(hpr::rad(p_rotation[0])),
hpr::cos(hpr::rad(p_rotation[1])) * hpr::cos(hpr::rad(p_rotation[0])),
hpr::sin(hpr::rad(p_rotation[1]))};
hpr::vec3 pos = p_target + p_distance * rotation;
p_front = p_target - pos;
p_front /= hpr::length(p_front);
p_up = hpr::vec3(0, 0, 1);
p_left = hpr::normalize(hpr::cross(p_up, p_front));
p_up = hpr::cross(p_front, p_left);
auto dd = glm::lookAt(glm::vec3(pos[0], pos[1], pos[2]), glm::vec3(pos[0] + p_front[0], pos[1] + p_front[1], pos[2] + p_front[2]), glm::vec3(p_up[0], p_up[1], p_up[2]));
auto dd2 = hpr::lookAt(pos, pos + p_front, p_up);
p_position = pos;
//for (auto v : dd2)
// std::cout << v << " ";
//std::cout << std::endl;
return dd2;
}
/*
-0.707107 0.707107 0 -0
-0.5 -0.5 0.707107 -1.90735e-06
0.5 0.5 0.707107 -10
0 0 0 1
*/
void rotateEvent(float xdelta, float ydelta)
{
p_rotation += hpr::vec3(xdelta, ydelta, 0);
}
void moveEvent(float xdelta, float ydelta)
{
p_target += (p_left * xdelta + p_up * ydelta) * 1e-3f;
}
void scrollEvent(float xdelta, float ydelta)
{
p_distance -= ydelta;
}
hpr::mat4 projection(Projection projection)
{
p_projection = projection;
switch (p_projection)
{
case Perspective:
return hpr::perspective(hpr::rad(p_fieldOfView), p_aspect, p_nearPlane, p_farPlane);
case Orthographic:
return hpr::ortho(-p_distance * p_aspect, p_distance * p_aspect, -p_distance, p_distance, p_nearPlane, p_farPlane);
}
}
void clear()
{
p_model = hpr::mat4::identity();
}
void translate(const hpr::vec3& position)
{
p_model = hpr::translate(p_model, position);
}
void rotate(const hpr::vec3& axis, hpr::scalar angle)
{
p_model = hpr::rotate(p_model, axis, hpr::rad(angle));
}
void scale(const hpr::vec3& size)
{
p_model = hpr::scale(p_model, size);
}
/*struct Vec {
float x, y, z, w;
};*/
void render()
{
//double model[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
//Vec model2[] = {Vec{0, 0, 0, 0}, Vec{0, 0, 0, 0},Vec{0, 0, 0, 0},Vec{0, 0, 0, 0}};
//static_assert(sizeof(model2) == sizeof(float) * 16 && std::is_standard_layout_v<Vec>);
//static_assert((sizeof(hpr::StaticArray<float, 16>::pointer) == (sizeof(GLfloat) * 16)) &&
// (std::is_standard_layout<hpr::mat4>::value),
// "Matrix4 does not satisfy contiguous storage requirements");
p_entity->shaderProgram()->bind();
//glUniformMatrix4fv(glGetUniformLocation(p_entity->shaderProgram()->index(), "model"),
// 1, GL_FALSE, p_model.data());
p_entity->shaderProgram()->uniformMatrix<4, 4, float>("model", 1, true, p_model.data());
hpr::mat4 _view = view();
p_entity->shaderProgram()->uniformMatrix<4, 4, float>("view", 1, true, _view.data());
hpr::mat4 _projection = projection(p_projection);
p_entity->shaderProgram()->uniformVector<float, 3>("viewPos", 1, p_position.data());
//for (auto v : _projection)
// std::cout << v << std::endl;
glm::mat4 _proj = glm::ortho(-p_distance * p_aspect, p_distance * p_aspect, -p_distance, p_distance, p_nearPlane, p_farPlane);
p_entity->shaderProgram()->uniformMatrix<4, 4, float>("projection", 1, true, _projection.data());
hpr::vec3 objectColor {1.0f, 0.5f, 0.31f};
p_entity->shaderProgram()->bind();
p_entity->shaderProgram()->uniformVector<float, 3>("objectColor", 1, objectColor.data());
p_entity->render(gpu::ArrayObject::Mode::Triangles);
objectColor = {1.0f, 1.0f, 1.0f};
p_entity->shaderProgram()->bind();
p_entity->shaderProgram()->uniformVector<float, 3>("objectColor", 1, objectColor.data());
p_entity->render(gpu::ArrayObject::Mode::LineLoop);
p_entity->shaderProgram()->unbind();
clear();
}
};