Move math library to separate project

This commit is contained in:
2022-02-23 19:26:58 -08:00
parent 96b409adc2
commit 283ce10697
55 changed files with 348 additions and 2861 deletions

View File

@@ -19,12 +19,12 @@
#ifndef OUR_DICK_ENGINE_BASE_TYPES_HPP
#define OUR_DICK_ENGINE_BASE_TYPES_HPP
#include "math/vec.hpp"
#include <rml/vec.hpp>
namespace egn{
//Represent a 3D point
using point = math::vec3f;
using point = rml::vec3f;
//Represent a line segment in 3D space given the end points
class line_segment
@@ -52,7 +52,7 @@ namespace egn{
point point2 = {};
public:
aabb(void) = default;
aabb(const math::vec3f& p1, const math::vec3f& p2);
aabb(const rml::vec3f& p1, const rml::vec3f& p2);
aabb(const aabb&) = default;
aabb(aabb&&) = default;
~aabb(void) = default;

View File

@@ -19,7 +19,7 @@
#ifndef OUR_DICK_ENGINE_CAMERA_HPP
#define OUR_DICK_ENGINE_CAMERA_HPP
#include "math/math.hpp"
#include <rml/math.hpp>
#include "object.hpp"
namespace egn{
@@ -37,15 +37,15 @@ namespace egn{
protected:
//mutable because they're only really a cached value representation of the data
//in position, orientation, near, far, etc
mutable math::mat4f m_projection_matrix; //camera-to-sceen matrix
mutable math::mat4f m_view_matrix; //world-to-camera matrix
mutable rml::mat4f m_projection_matrix; //camera-to-sceen matrix
mutable rml::mat4f m_view_matrix; //world-to-camera matrix
float m_near = 1; //near clipping plane in camera space
float m_far = 100; //far clipping plane in camera space
public:
camera_iface(void) = default;
//Initialize with given projection matrix and clipping planes
camera_iface(const math::mat4f& proj, float n, float f);
camera_iface(const rml::mat4f& proj, float n, float f);
camera_iface(const camera_iface&) = default;
camera_iface(camera_iface&&) = default;
virtual ~camera_iface(void) = default;
@@ -54,13 +54,13 @@ namespace egn{
camera_iface& operator=(camera_iface&&) = default;
//Set the camera's location and update relevant data structures
void set_position(const math::vec3f& pos)override;
void set_position(const rml::vec3f& pos)override;
//Set the camera's facing angle and update relevant data structures
void set_orientation(const math::quat_f& distance)override;
void set_orientation(const rml::quat_f& distance)override;
//getters
const math::mat4f& get_projection_matrix(void)const;
const math::mat4f& get_view_matrix(void)const;
const rml::mat4f& get_projection_matrix(void)const;
const rml::mat4f& get_view_matrix(void)const;
float get_near_plane(void)const;
float get_far_plane(void)const;

View File

@@ -33,11 +33,11 @@
namespace egn{
struct font_character{
math::vec2<size_t> atlas_offset;
math::vec2i size;
math::vec2i bearing;
math::vec2i advance;
math::vec2f texture_coords[4];
rml::vec2<size_t> atlas_offset;
rml::vec2i size;
rml::vec2i bearing;
rml::vec2i advance;
rml::vec2f texture_coords[4];
public:
float aspect_ratio(void)const;
@@ -67,7 +67,7 @@ namespace egn{
font_character& operator[](int character);
math::vec2<size_t> glyph_size(void)const;
rml::vec2<size_t> glyph_size(void)const;
};
class font
@@ -92,8 +92,8 @@ namespace egn{
private:
using atlas_meta = std::tuple<size_t,size_t,size_t,size_t>;
template<class... Ts>
void generate_atlas_piece_(gfx::ogl::texture& atlas, font_atlas::map_type& metadata, math::vec2<size_t>& target_pos, const atlas_meta& info, unsigned char* data_buffer, const std::pair<int,int>& range, Ts&&... ranges);
void generate_atlas_piece_impl_(gfx::ogl::texture& atlas, font_atlas::map_type& metadata, math::vec2<size_t>& target_pos, const atlas_meta& info, unsigned char* data_buffer, const std::pair<int,int>& range);
void generate_atlas_piece_(gfx::ogl::texture& atlas, font_atlas::map_type& metadata, rml::vec2<size_t>& target_pos, const atlas_meta& info, unsigned char* data_buffer, const std::pair<int,int>& range, Ts&&... ranges);
void generate_atlas_piece_impl_(gfx::ogl::texture& atlas, font_atlas::map_type& metadata, rml::vec2<size_t>& target_pos, const atlas_meta& info, unsigned char* data_buffer, const std::pair<int,int>& range);
template<class... Ts>
atlas_meta get_atlas_size_ranges_(Ts&&... ranges);
template<class... Ts>
@@ -108,7 +108,7 @@ namespace egn{
template<class... Ts>
void font::generate_atlas_piece_(gfx::ogl::texture& atlas, font_atlas::map_type& metadata, math::vec2<size_t>& target_pos, const atlas_meta& info, unsigned char* data_buffer, const std::pair<int,int>& range, Ts&&... ranges){
void font::generate_atlas_piece_(gfx::ogl::texture& atlas, font_atlas::map_type& metadata, rml::vec2<size_t>& target_pos, const atlas_meta& info, unsigned char* data_buffer, const std::pair<int,int>& range, Ts&&... ranges){
generate_atlas_piece_impl_(atlas, metadata, target_pos, info, data_buffer, range);
if constexpr(sizeof...(ranges) > 0){
@@ -125,7 +125,7 @@ namespace egn{
gfx::ogl::texture atlas(format, atlas_width, atlas_height, GL_UNSIGNED_BYTE, false);
font_atlas::map_type atlas_metadata;
math::vec2<size_t> target_position = {0, 0};
rml::vec2<size_t> target_position = {0, 0};
std::unique_ptr<unsigned char[]> dest_data(new unsigned char[max_glyph_height * max_glyph_width * m_depth]);
generate_atlas_piece_(atlas, atlas_metadata, target_position, std::tuple{atlas_width, atlas_height, max_glyph_width, max_glyph_height}, dest_data.get(), std::forward<Ts>(ranges)...);

View File

@@ -23,7 +23,7 @@
#include "game_state.hpp"
#include "gfx/ogl/window.hpp"
#include "input.hpp"
#include "math/vec.hpp"
#include <rml/vec.hpp>
#include "wip/renderer.hpp"
#include <queue>
@@ -50,7 +50,7 @@ namespace egn{
void keypress(int key, int action, int mods);
void resize(int width, int height);
math::vec2<double> get_mouse_pos(void)const;
rml::vec2<double> get_mouse_pos(void)const;
void on_notify(const game_state_event& e)override;

View File

@@ -19,7 +19,7 @@
#ifndef OUR_DICK_ENGINE_OBJECT_HPP
#define OUR_DICK_ENGINE_OBJECT_HPP
#include "math/math.hpp"
#include <rml/math.hpp>
#include "base_types.hpp"
namespace egn{
@@ -35,19 +35,19 @@ namespace egn{
BOUNDING_VOLUME_UPDATE = 8,
};
protected:
math::vec3f m_position; //track current positon in world space
math::quat_f m_orientation; //track current model space rotation
math::vec3f m_scale{1.0f, 1.0f, 1.0f}; //track model space scale
rml::vec3f m_position; //track current positon in world space
rml::quat_f m_orientation; //track current model space rotation
rml::vec3f m_scale{1.0f, 1.0f, 1.0f}; //track model space scale
private:
mutable math::mat4f m_model_matrix; //compile all the above info into a matrix
mutable rml::mat4f m_model_matrix; //compile all the above info into a matrix
protected:
mutable int m_update_flag = NO_UPDATE; //whether or not to update the matrix upon access
//make the update flag protected so subclasses can share it
public:
object(void) = default;
explicit object(const math::vec3f& position);
object(const math::vec3f& position, const math::quat_f& orientation);
explicit object(const rml::vec3f& position);
object(const rml::vec3f& position, const rml::quat_f& orientation);
object(const object&) = default;
object(object&&) = default;
virtual ~object(void) = default;
@@ -55,19 +55,19 @@ namespace egn{
object& operator=(const object&) = default;
object& operator=(object&&) = default;
void translate(const math::vec3f& distance);
void rotate(const math::quat_f& distance);
void scale(const math::vec3f& distance);
void look_at(const math::vec3f& targ, const math::vec3f& up);
void translate(const rml::vec3f& distance);
void rotate(const rml::quat_f& distance);
void scale(const rml::vec3f& distance);
void look_at(const rml::vec3f& targ, const rml::vec3f& up);
virtual void set_position(const math::vec3f& pos);
virtual void set_orientation(const math::quat_f& orient);
virtual void set_scale(const math::vec3f& scale);
virtual void set_position(const rml::vec3f& pos);
virtual void set_orientation(const rml::quat_f& orient);
virtual void set_scale(const rml::vec3f& scale);
const math::mat4f& model_matrix(void)const;
const math::vec3f& position(void)const;
const math::vec3f& scale(void)const;
const math::quat_f& orientation(void)const;
const rml::mat4f& model_matrix(void)const;
const rml::vec3f& position(void)const;
const rml::vec3f& scale(void)const;
const rml::quat_f& orientation(void)const;
protected:
void recalc_model_matrix(void)const;

View File

@@ -22,7 +22,7 @@
#include "gl_include.hpp"
#include "texture.hpp"
#include "rbo.hpp"
#include "math/vec.hpp"
#include <rml/vec.hpp>
#include "util/init_constants.hpp"
namespace gfx::ogl{
@@ -32,7 +32,7 @@ namespace gfx::ogl{
{
private:
GLuint m_buffer;
math::vec4f m_vp_coords; //Opengl doesn't associate viewports with framebuffers, so i do
rml::vec4f m_vp_coords; //Opengl doesn't associate viewports with framebuffers, so i do
public:
//Construct an object representing the default 'root' framebuffer
@@ -59,7 +59,7 @@ namespace gfx::ogl{
bool attach(const rbo& r, GLenum point);
//Clear individual fields
void clear_color_buffer(const math::vec4f& color = {0.0f, 0.0f, 0.0f, 1.0f});
void clear_color_buffer(const rml::vec4f& color = {0.0f, 0.0f, 0.0f, 1.0f});
void clear_depth_buffer(GLfloat value = 1.0f);
void clear_stencil_buffer(GLint value = 0);
//Clear fields as by glClear
@@ -69,7 +69,7 @@ namespace gfx::ogl{
void set_viewport(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
//Activate this framebuffer's viewport. Calls glViewport
void apply_viewport(void)const;
const math::vec4f& get_viewport(void)const;
const rml::vec4f& get_viewport(void)const;
//Set this as the active framebuffer
bool bind(void)const;

View File

@@ -27,12 +27,10 @@
#include <utility> //forward
#include <string>
#include "math/math.hpp"
#include <rml/math.hpp>
namespace gfx::ogl{
using namespace math;
class uniform
{
private:
@@ -52,49 +50,49 @@ namespace gfx::ogl{
GLenum get_type(void)const;
GLfloat get_float(void)const;
math::vec2f get_vec2(void)const;
math::vec3f get_vec3(void)const;
math::vec4f get_vec4(void)const;
rml::vec2f get_vec2(void)const;
rml::vec3f get_vec3(void)const;
rml::vec4f get_vec4(void)const;
GLdouble get_double(void)const;
math::vec2d get_dvec2(void)const;
math::vec3d get_dvec3(void)const;
math::vec4d get_dvec4(void)const;
rml::vec2d get_dvec2(void)const;
rml::vec3d get_dvec3(void)const;
rml::vec4d get_dvec4(void)const;
GLint get_int(void)const;
math::vec2i get_ivec2(void)const;
math::vec3i get_ivec3(void)const;
math::vec4i get_ivec4(void)const;
rml::vec2i get_ivec2(void)const;
rml::vec3i get_ivec3(void)const;
rml::vec4i get_ivec4(void)const;
GLuint get_uint(void)const;
math::vec2u get_uvec2(void)const;
math::vec3u get_uvec3(void)const;
math::vec4u get_uvec4(void)const;
rml::vec2u get_uvec2(void)const;
rml::vec3u get_uvec3(void)const;
rml::vec4u get_uvec4(void)const;
GLboolean get_bool(void)const;
math::vec2i get_bvec2(void)const;
math::vec3i get_bvec3(void)const;
math::vec4i get_bvec4(void)const;
rml::vec2i get_bvec2(void)const;
rml::vec3i get_bvec3(void)const;
rml::vec4i get_bvec4(void)const;
math::mat2f get_mat2(void)const;
math::mat3f get_mat3(void)const;
math::mat4f get_mat4(void)const;
math::matrix<GLfloat,2,3> get_mat2x3(void)const;
math::matrix<GLfloat,2,4> get_mat2x4(void)const;
math::matrix<GLfloat,3,2> get_mat3x2(void)const;
math::matrix<GLfloat,3,4> get_mat3x4(void)const;
math::matrix<GLfloat,4,2> get_mat4x2(void)const;
math::matrix<GLfloat,4,3> get_mat4x3(void)const;
rml::mat2f get_mat2(void)const;
rml::mat3f get_mat3(void)const;
rml::mat4f get_mat4(void)const;
rml::matrix<float,2,3> get_mat2x3(void)const;
rml::matrix<float,2,4> get_mat2x4(void)const;
rml::matrix<float,3,2> get_mat3x2(void)const;
rml::matrix<float,3,4> get_mat3x4(void)const;
rml::matrix<float,4,2> get_mat4x2(void)const;
rml::matrix<float,4,3> get_mat4x3(void)const;
math::mat2d get_dmat2(void)const;
math::mat3d get_dmat3(void)const;
math::mat4d get_dmat4(void)const;
math::matrix<GLdouble,2,3> get_dmat2x3(void)const;
math::matrix<GLdouble,2,4> get_dmat2x4(void)const;
math::matrix<GLdouble,3,2> get_dmat3x2(void)const;
math::matrix<GLdouble,3,4> get_dmat3x4(void)const;
math::matrix<GLdouble,4,2> get_dmat4x2(void)const;
math::matrix<GLdouble,4,3> get_dmat4x3(void)const;
rml::mat2d get_dmat2(void)const;
rml::mat3d get_dmat3(void)const;
rml::mat4d get_dmat4(void)const;
rml::matrix<double,2,3> get_dmat2x3(void)const;
rml::matrix<double,2,4> get_dmat2x4(void)const;
rml::matrix<double,3,2> get_dmat3x2(void)const;
rml::matrix<double,3,4> get_dmat3x4(void)const;
rml::matrix<double,4,2> get_dmat4x2(void)const;
rml::matrix<double,4,3> get_dmat4x3(void)const;
//float
void set(GLfloat);
@@ -119,14 +117,14 @@ namespace gfx::ogl{
void set(const texture_array& t, GLuint tex_unit = 0);
//Float vectors
void set(const vec2f&);
void set(const vec3f&);
void set(const vec4f&);
void set(const rml::vec2f&);
void set(const rml::vec3f&);
void set(const rml::vec4f&);
//Float vector array
void set(GLsizei count, const vec2f*);
void set(GLsizei count, const vec3f*);
void set(GLsizei count, const vec4f*);
void set(GLsizei count, const rml::vec2f*);
void set(GLsizei count, const rml::vec3f*);
void set(GLsizei count, const rml::vec4f*);
//Explicit float vectors
void set_1(GLsizei count, const GLfloat*);
@@ -135,14 +133,14 @@ namespace gfx::ogl{
void set_4(GLsizei count, const GLfloat*);
//Int vectors
void set(const vec2<GLint>&);
void set(const vec3<GLint>&);
void set(const vec4<GLint>&);
void set(const rml::vec2i&);
void set(const rml::vec3i&);
void set(const rml::vec4i&);
//Int vector array
void set(GLsizei count, const vec2<GLint>*);
void set(GLsizei count, const vec3<GLint>*);
void set(GLsizei count, const vec4<GLint>*);
void set(GLsizei count, const rml::vec2i*);
void set(GLsizei count, const rml::vec3i*);
void set(GLsizei count, const rml::vec4i*);
//Explicit int vectors
void set_1(GLsizei count, const GLint*);
@@ -151,14 +149,14 @@ namespace gfx::ogl{
void set_4(GLsizei count, const GLint*);
//Unsigned int vectors
void set(const vec2<GLuint>&);
void set(const vec3<GLuint>&);
void set(const vec4<GLuint>&);
void set(const rml::vec2u&);
void set(const rml::vec3u&);
void set(const rml::vec4u&);
//Unsigned int vector array
void set(GLsizei count, const vec2<GLuint>*);
void set(GLsizei count, const vec3<GLuint>*);
void set(GLsizei count, const vec4<GLuint>*);
void set(GLsizei count, const rml::vec2u*);
void set(GLsizei count, const rml::vec3u*);
void set(GLsizei count, const rml::vec4u*);
//Explicit unsigned int vectors
void set_1(GLsizei count, const GLuint*);
@@ -167,14 +165,14 @@ namespace gfx::ogl{
void set_4(GLsizei count, const GLuint*);
//Matrices
void set(const mat2f&);
void set(const mat3f&);
void set(const mat4f&);
void set(const rml::mat2f&);
void set(const rml::mat3f&);
void set(const rml::mat4f&);
//Matrix array
void set(GLsizei count, const mat2f*);
void set(GLsizei count, const mat3f*);
void set(GLsizei count, const mat4f*);
void set(GLsizei count, const rml::mat2f*);
void set(GLsizei count, const rml::mat3f*);
void set(GLsizei count, const rml::mat4f*);
//Explicit matrices
void set_mat2(GLsizei count, const GLfloat*);

View File

@@ -21,7 +21,7 @@
#include "egn/image.hpp"
#include "gl_include.hpp"
#include "math/vec.hpp"
#include <rml/vec.hpp>
namespace gfx::ogl{
@@ -85,7 +85,7 @@ namespace gfx::ogl{
magfilter get_mag_filter(void)const;
minfilter get_min_filter(void)const;
math::vec4f get_border_color(void)const;
rml::vec4f get_border_color(void)const;
wrap get_wrap_x(void)const;
wrap get_wrap_y(void)const;

View File

@@ -21,8 +21,8 @@
#include "gl_include.hpp"
#include "math/mat.hpp"
#include "math/vec.hpp"
#include <rml/mat.hpp>
#include <rml/vec.hpp>
#include <type_traits> //a lot of stuff
@@ -51,7 +51,7 @@ namespace gfx::ogl{
template<class T>
struct is_valid_uniform_matrix{
template<class U, size_t R, size_t C>
static constexpr bool test(math::matrix_base<U,R,C>*){
static constexpr bool test(rml::matrix_base<U,R,C>*){
return is_valid_uniform_scalar<typename T::value_type>::value && T::Columns <= 4 && T::Rows <= 4;
}
static constexpr bool test(void*){

View File

@@ -229,7 +229,7 @@ namespace gfx::ogl{
return 4;
}
}else if constexpr(detail::is_bounded_array<T>::value){
return get_alignment_of_<math::vec4f>();
return get_alignment_of_<rml::vec4f>();
}else{
constexpr size_t element_alignment = get_alignment_of_<typename T::value_type>();
if constexpr(T::Columns > 1){ //matrix

View File

@@ -20,11 +20,10 @@
#define OUR_DICK_GRAPHICS_OGL_VAO_HPP
#include "gl_include.hpp"
#include "math/math.hpp"
#include <rml/math.hpp>
#include "vbo.hpp"
namespace gfx::ogl{
using namespace math;
class vertex_attribute;

View File

@@ -21,7 +21,7 @@
#include "gl_include.hpp"
#include "../init.hpp"
#include "math/math.hpp"
#include <rml/math.hpp>
#include "util/init_constants.hpp"
namespace gfx::ogl{
@@ -69,12 +69,12 @@ namespace gfx::ogl{
void destroy(void);
void set_size(const math::vec2i&);
void set_size(const rml::vec2i&);
void set_size(int w, int h);
void set_width(int w);
void set_height(int h);
void set_title(const char* t);
void set_pos(const math::vec2i&);
void set_pos(const rml::vec2i&);
void set_pos(int x, int y);
void set_x(int x);
void set_y(int y);
@@ -95,20 +95,20 @@ namespace gfx::ogl{
void set_active(void);
math::vec2i get_size(void)const;
rml::vec2i get_size(void)const;
int get_width(void)const;
int get_height(void)const;
math::vec2i get_pos(void)const;
rml::vec2i get_pos(void)const;
int get_posx(void)const;
int get_posy(void)const;
math::vec2i get_context_version(void)const;
rml::vec2i get_context_version(void)const;
int get_context_vmaj(void)const;
int get_context_vmin(void)const;
int get_swap_interval(void)const;
math::vec2d get_cursor_pos(void)const;
rml::vec2d get_cursor_pos(void)const;
double get_cursor_posx(void)const;
double get_cursor_posy(void)const;
bool get_key(int key, int action)const;

View File

@@ -1,75 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_MATH_DEBUG_HPP
#define OUR_DICK_MATH_DEBUG_HPP
#include <cstdio> //printf
#include <cstdlib> //size_t
#include "quat.hpp"
#include "mat.hpp"
namespace math{
namespace detail{
static inline void print_integral(int i){
printf("%d", i);
}
static inline void print_integral(float f){
printf("%f", f);
}
static inline void print_double(double d){
printf("%lf", d);
}
static inline void print_integral(unsigned int i){
printf("%u", i);
}
static inline void print_integral(long int i){
printf("%li", i);
}
static inline void print_integral(unsigned long int i){
printf("%lu", i);
}
static inline void print_integral(long double d){
printf("%Lf", d);
}
}
//Debug
template<Scalar T, size_t R, size_t C>
void dump_matrix(const matrix_base<T,R,C>& mat){
for(size_t i = 0;i < C;++i){
for(size_t j = 0;j < R;++j){
detail::print_integral(mat[i][j]);
printf(" ");
}
printf("\n");
}
printf("\n");
}
template<Scalar T>
void dump_quaternion(const quaternion<T>& q){
for(size_t i = 0;i < 4;++i){
detail::print_integral(q[i]);
printf(" ");
}
printf("\n");
}
}
#endif

View File

@@ -1,117 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_DETAIL_MATRIX_HPP
#define REXY_DETAIL_MATRIX_HPP
#include <cstdlib> //size_t
#include <utility> //integer_sequence
#include "../fwd_declare.hpp"
namespace math::detail{
template<size_t SW, size_t W = SW, size_t H = SW-1, size_t... Args>
struct gen_id_tup {
using tup = typename gen_id_tup<SW, W-1, H, Args..., 0>::tup;
};
template<size_t SW, size_t H, size_t... Args>
struct gen_id_tup<SW,SW,H,Args...> {
using tup = typename gen_id_tup<SW, SW-1, H, Args..., 1>::tup;
};
template<size_t SW, size_t H, size_t... Args>
struct gen_id_tup<SW,0,H,Args...> {
using tup = typename gen_id_tup<SW, SW, H-1, Args..., 0>::tup;
};
template<size_t SW, size_t... Args>
struct gen_id_tup<SW,SW,0,Args...> {
using tup = std::integer_sequence<size_t,Args...,1>;
};
template<size_t N, size_t... Args>
struct gen_zero_tup {
using tup = typename gen_zero_tup<N-1,Args...,0>::tup;
};
template<size_t... Args>
struct gen_zero_tup<0,Args...> {
using tup = std::integer_sequence<size_t,Args...>;
};
template<size_t W>
struct id_initialization_matrix {
using tuple = typename gen_id_tup<W>::tup;
};
template<size_t W, size_t H>
struct default_initialization_matrix {
using tuple = typename gen_zero_tup<W>::tup;
};
template<size_t W>
struct default_initialization_matrix<W,W> {
using tuple = typename id_initialization_matrix<W>::tuple;
};
template<Scalar T, size_t R>
class mat_ref_obj
{
public:
using size_type = size_t;
protected:
T* m_data = nullptr;
public:
constexpr mat_ref_obj(T* d, size_type i);
constexpr T& operator[](size_type i);
constexpr const T& operator[](size_type i)const;
};
template<Scalar T, size_t R>
struct determinate_helper {
static constexpr T perform(const matrix<T,R,R>& m);
};
template<Scalar T>
struct determinate_helper<T,3> {
static constexpr T perform(const matrix<T,3,3>& m);
};
template<Scalar T>
struct determinate_helper<T,2> {
static constexpr T perform(const matrix<T,2,2>& m);
};
template<Scalar T, size_t R>
struct inverse_helper {
//TODO generalized inverse
};
template<Scalar T>
struct inverse_helper<T,2> {
static constexpr matrix<T,2,2> perform(const matrix<T,2,2>& m);
};
template<Scalar T>
struct inverse_helper<T,3> {
static constexpr matrix<T,3,3> perform(const matrix<T,3,3>& m);
};
template<Scalar T>
struct inverse_helper<T,4> {
static constexpr matrix<T,4,4> perform(const matrix<T,4,4>& m);
};
}
#include "matrix.tpp"
#endif

View File

@@ -1,151 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_DETAIL_MATRIX_TPP
#define REXY_DETAIL_MATRIX_TPP
#include <cstdlib> //size_t
#include <utility> //integer_sequence
namespace math::detail{
template<Scalar T, size_t R>
constexpr mat_ref_obj<T,R>::mat_ref_obj(T* d, size_type i):
m_data(d+(i*R)){}
template<Scalar T, size_t R>
constexpr T& mat_ref_obj<T,R>::operator[](size_type i){
return m_data[i];
}
template<Scalar T, size_t R>
constexpr const T& mat_ref_obj<T,R>::operator[](size_type i)const{
return m_data[i];
}
template<Scalar T, size_t R>
constexpr T determinate_helper<T,R>::perform(const matrix<T,R,R>& m){
T sum = 0;
T op = 1;
for(size_t i = 0; i < R; ++i){
T item = op * m[0][i];
matrix<T,R-1,R-1> mul(no_initialize);
for(size_t j = 1, mj = 0; j < R; ++j){
for(size_t k = 0, mk = 0; k < R; ++k){
if(k == i)
continue;
mul[mj][mk] = m[j][k];
++mk;
}
++mj;
}
sum += item * determinate_helper<T,R-1>::perform(mul);
op = -op;
}
return sum;
}
template<Scalar T>
constexpr T determinate_helper<T,3>::perform(const matrix<T,3,3>& m){
return (m.get(0) * ((m.get(4) * m.get(8)) - (m.get(5) * m.get(7))) -
m.get(1) * ((m.get(3) * m.get(8)) - (m.get(5) * m.get(6))) +
m.get(2) * ((m.get(3) * m.get(7)) - (m.get(4) * m.get(6))));
}
template<Scalar T>
constexpr T determinate_helper<T,2>::perform(const matrix<T,2,2>& m){
return m.get(0) * m.get(3) - m.get(1) * m.get(2);
}
template<Scalar T>
constexpr matrix<T,2,2> inverse_helper<T,2>::perform(const matrix<T,2,2>& m){
T det = m.determinate();
if(!det)
return matrix<T,2,2>(zero_initialize);
return matrix<T,2,2>(m.get(3) / det, -(m.get(1)) / det, -(m.get(2)) / det, m.get(0) / det);
}
template<Scalar T>
constexpr matrix<T,3,3> inverse_helper<T,3>::perform(const matrix<T,3,3>& m){
T det = m.determinate();
if(!det)
return matrix<T,3,3>(zero_initialize);
return matrix<T,3,3>(((m.get(4) * m.get(8)) - (m.get(5) * m.get(7))) / det,
-((m.get(1) * m.get(8)) - (m.get(2) * m.get(7))) / det,
((m.get(1) * m.get(5)) - (m.get(2) * m.get(4))) / det,
-((m.get(3) * m.get(8)) - (m.get(5) * m.get(6))) / det,
((m.get(0) * m.get(8)) - (m.get(2) * m.get(6))) / det,
-((m.get(0) * m.get(5)) - (m.get(2) * m.get(3))) / det,
((m.get(3) * m.get(7)) - (m.get(4) * m.get(6))) / det,
-((m.get(0) * m.get(7)) - (m.get(1) * m.get(6))) / det,
((m.get(0) * m.get(4)) - (m.get(1) * m.get(3))) / det);
}
template<Scalar T>
constexpr matrix<T,4,4> inverse_helper<T,4>::perform(const matrix<T,4,4>& m){
//barely over 50 lines, can be made slightly shorter by making the return statement unreadable
T det = m.determinate();
if(!det)
return matrix<T,4,4>(zero_initialize);
return matrix<T,4,4>((m.get(5) * ((m.get(10) * m.get(15)) - (m.get(11) * m.get(14))) -
m.get(6) * ((m.get(9) * m.get(15)) - (m.get(11) * m.get(13))) +
m.get(7) * ((m.get(9) * m.get(14)) - (m.get(10) * m.get(13)))) / det,
-(m.get(1) * ((m.get(10) * m.get(15)) - (m.get(11) * m.get(14))) -
m.get(2) * ((m.get(9) * m.get(15)) - (m.get(11) * m.get(13))) +
m.get(3) * ((m.get(9) * m.get(14)) - (m.get(10) * m.get(13)))) / det,
(m.get(1) * ((m.get(6) * m.get(15)) - (m.get(7) * m.get(14))) -
m.get(2) * ((m.get(5) * m.get(15)) - (m.get(7) * m.get(13))) +
m.get(3) * ((m.get(5) * m.get(14)) - (m.get(6) * m.get(13)))) / det,
-(m.get(1) * ((m.get(6) * m.get(11)) - (m.get(7) * m.get(10))) -
m.get(2) * ((m.get(5) * m.get(11)) - (m.get(7) * m.get(9))) +
m.get(3) * ((m.get(5) * m.get(10)) - (m.get(6) * m.get(9)))) / det,
-(m.get(4) * ((m.get(10) * m.get(15)) - (m.get(11) * m.get(14))) -
m.get(6) * ((m.get(8) * m.get(15)) - (m.get(11) * m.get(12))) +
m.get(7) * ((m.get(8) * m.get(14)) - (m.get(10) * m.get(12)))) / det,
(m.get(0) * ((m.get(10) * m.get(15)) - (m.get(11) * m.get(14))) -
m.get(2) * ((m.get(8) * m.get(15)) - (m.get(11) * m.get(12))) +
m.get(3) * ((m.get(8) * m.get(14)) - (m.get(10) * m.get(12)))) / det,
-(m.get(0) * ((m.get(6) * m.get(15)) - (m.get(7) * m.get(14))) -
m.get(2) * ((m.get(4) * m.get(15)) - (m.get(7) * m.get(12))) +
m.get(3) * ((m.get(4) * m.get(14)) - (m.get(6) * m.get(12)))) / det,
(m.get(0) * ((m.get(6) * m.get(11)) - (m.get(7) * m.get(10))) -
m.get(2) * ((m.get(4) * m.get(11)) - (m.get(7) * m.get(8))) +
m.get(3) * ((m.get(4) * m.get(10)) - (m.get(6) * m.get(8)))) / det,
(m.get(4) * ((m.get(9) * m.get(15)) - (m.get(11) * m.get(13))) -
m.get(5) * ((m.get(8) * m.get(15)) - (m.get(11) * m.get(12))) +
m.get(7) * ((m.get(8) * m.get(13)) - (m.get(9) * m.get(12)))) / det,
-(m.get(0) * ((m.get(9) * m.get(15)) - (m.get(11) * m.get(13))) -
m.get(1) * ((m.get(8) * m.get(15)) - (m.get(11) * m.get(12))) +
m.get(3) * ((m.get(8) * m.get(13)) - (m.get(9) * m.get(12)))) / det,
(m.get(0) * ((m.get(5) * m.get(15)) - (m.get(7) * m.get(13))) -
m.get(1) * ((m.get(4) * m.get(15)) - (m.get(7) * m.get(12))) +
m.get(3) * ((m.get(4) * m.get(13)) - (m.get(5) * m.get(12)))) / det,
-(m.get(0) * ((m.get(5) * m.get(11)) - (m.get(7) * m.get(9))) -
m.get(1) * ((m.get(4) * m.get(11)) - (m.get(7) * m.get(8))) +
m.get(3) * ((m.get(4) * m.get(9)) - (m.get(5) * m.get(8)))) / det,
-(m.get(4) * ((m.get(9) * m.get(14)) - (m.get(10) * m.get(13))) -
m.get(5) * ((m.get(8) * m.get(14)) - (m.get(10) * m.get(12))) +
m.get(6) * ((m.get(8) * m.get(13)) - (m.get(9) * m.get(12)))) / det,
(m.get(0) * ((m.get(9) * m.get(14)) - (m.get(10) * m.get(13))) -
m.get(1) * ((m.get(8) * m.get(14)) - (m.get(10) * m.get(12))) +
m.get(2) * ((m.get(8) * m.get(13)) - (m.get(9) * m.get(12)))) / det,
-(m.get(0) * ((m.get(5) * m.get(14)) - (m.get(6) * m.get(13))) -
m.get(1) * ((m.get(4) * m.get(14)) - (m.get(6) * m.get(12))) +
m.get(2) * ((m.get(4) * m.get(13)) - (m.get(5) * m.get(12)))) / det,
(m.get(0) * ((m.get(5) * m.get(10)) - (m.get(6) * m.get(9))) -
m.get(1) * ((m.get(4) * m.get(10)) - (m.get(6) * m.get(8))) +
m.get(2) * ((m.get(4) * m.get(9)) - (m.get(5) * m.get(8)))) / det);
}
}
#endif

View File

@@ -1,196 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_MATH_FWD_DECLARE_HPP
#define REXY_MATH_FWD_DECLARE_HPP
#include <cstdlib> //size_t
#include <type_traits>
#ifdef __cpp_lib_concepts
#include <concepts>
namespace detail{
template<class T, class U>
concept convertible_to = std::convertible_to<T,U>;
}
#else
namespace detail{
template<class T, class U>
concept convertible_to = std::is_convertible_v<T,U>;
}
#endif
//Provide aliases for common matrix, vector, and quaternion types
namespace math{
//Must forward declare type traits for use in concepts because you can't forward declare concepts
template<class... Ms>
struct is_vector;
template<class... Qs>
struct is_quaternion;
template<class... Ms>
struct is_matrix;
//Create concepts that depend on the type traits
template<class T>
concept Quaternion = is_quaternion<T>::value;
template<class T>
concept Matrix = is_matrix<T>::value;
template<class T>
concept Vector = is_vector<T>::value;
template<class T>
concept Scalar = !Matrix<T> && !Vector<T> && !Quaternion<T> && requires(std::decay_t<T> t){
{t += t} -> detail::convertible_to<T>;
{t -= t} -> detail::convertible_to<T>;
{t /= t} -> detail::convertible_to<T>;
{t *= t} -> detail::convertible_to<T>;
{t + t} -> detail::convertible_to<std::decay_t<T>>;
{t - t} -> detail::convertible_to<std::decay_t<T>>;
{t / t} -> detail::convertible_to<std::decay_t<T>>;
{t * t} -> detail::convertible_to<std::decay_t<T>>;
{-t} -> detail::convertible_to<std::decay_t<T>>;
{t > t} -> detail::convertible_to<bool>;
{t < t} -> detail::convertible_to<bool>;
{t >= t} -> detail::convertible_to<bool>;
{t <= t} -> detail::convertible_to<bool>;
{t == t} -> detail::convertible_to<bool>;
{t != t} -> detail::convertible_to<bool>;
};
template<Scalar T, size_t R, size_t C>
class matrix_base;
template<Scalar T, size_t R, size_t C>
class matrix;
template<Scalar T, size_t R>
class vector;
template<Scalar T>
class quaternion;
template<Scalar T>
using mat2 = matrix<T,2,2>;
template<Scalar T>
using mat3 = matrix<T,3,3>;
template<Scalar T>
using mat4 = matrix<T,4,4>;
template<Scalar T>
using vec2 = vector<T,2>;
template<Scalar T>
using vec3 = vector<T,3>;
template<Scalar T>
using vec4 = vector<T,4>;
using vec2f = vec2<float>;
using vec2i = vec2<int>;
using vec2u = vec2<unsigned int>;
using vec2d = vec2<double>;
using vec2s = vec2<size_t>;
using vec2b = vec2<int>;
using vec3f = vec3<float>;
using vec3i = vec3<int>;
using vec3u = vec3<unsigned int>;
using vec3d = vec3<double>;
using vec3s = vec3<size_t>;
using vec3b = vec3<int>;
using vec4f = vec4<float>;
using vec4i = vec4<int>;
using vec4u = vec4<unsigned int>;
using vec4d = vec4<double>;
using vec4s = vec4<size_t>;
using vec4b = vec4<int>;
using mat2f = mat2<float>;
using mat2i = mat2<int>;
using mat2u = mat2<unsigned int>;
using mat2d = mat2<double>;
using mat2s = mat2<size_t>;
using mat2b = mat2<int>;
using mat3f = mat3<float>;
using mat3i = mat3<int>;
using mat3u = mat3<unsigned int>;
using mat3d = mat3<double>;
using mat3s = mat3<size_t>;
using mat4f = mat4<float>;
using mat4i = mat4<int>;
using mat4u = mat4<unsigned int>;
using mat4d = mat4<double>;
using mat4s = mat4<size_t>;
using mat4b = mat4<int>;
template<Scalar T>
using quat = quaternion<T>;
using quat_f = quat<float>;
using quat_i = quat<int>;
using quat_u = quat<unsigned int>;
using quat_d = quat<double>;
using quat_s = quat<size_t>;
using quat_b = quat<int>;
namespace detail{
template<class T>
struct is_matrix_helper {
template<class U, size_t R, size_t C>
static std::true_type test(matrix_base<U,R,C>*);
static std::false_type test(void*);
static constexpr bool value = std::is_same<std::true_type,decltype(test(static_cast<std::decay_t<T>*>(nullptr)))>::value;
};
template<class T>
struct is_quat_helper {
template<class U>
static std::true_type test(quaternion<U>*);
static std::false_type test(void*);
static constexpr bool value = std::is_same<std::true_type,decltype(test(static_cast<std::decay_t<T>*>(nullptr)))>::value;
};
template<class T>
struct is_vector_helper {
template<class U, size_t R>
static std::true_type test(vector<U,R>*);
static std::false_type test(void*);
static constexpr bool value = std::is_same<std::true_type,decltype(test(static_cast<std::decay_t<T>*>(nullptr)))>::value;
};
}
template<class... Ms>
struct is_vector{
static constexpr bool value = (detail::is_vector_helper<Ms>::value && ...);
};
template<class... Qs>
struct is_quaternion {
static constexpr bool value = (detail::is_quat_helper<Qs>::value && ...);
};
template<class... Ms>
struct is_matrix {
static constexpr bool value = (detail::is_matrix_helper<Ms>::value && ...);
};
}
#endif

View File

@@ -1,243 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_MAT_HPP
#define REXY_MAT_HPP
#include <cstdlib> //size_t
#include <utility> //integer_sequence
#include <type_traits> //decay_t, is_same, integral_constant
#include "math_common.hpp"
#include "fwd_declare.hpp"
#include <cstdio>
namespace math{
//Common stuff shared by all types of matrices
template<Scalar T, size_t R, size_t C>
class matrix_base
{
static_assert(C > 0, "Cannot have 0 columns matrix");
static_assert(R > 0, "Cannot have 0 rows matrix");
public:
using value_type = T;
using size_type = size_t;
using pointer = value_type*;
using const_pointer = const value_type*;
using reference = value_type&;
using const_reference = const value_type&;
static constexpr size_type Columns = C;
static constexpr size_type Rows = R;
protected:
value_type m_data[R*C];
protected:
template<size_t... Ss>
constexpr matrix_base(std::integer_sequence<size_type,Ss...>);
public:
//Default construct as identity when square, zero otherwise
constexpr matrix_base(void);
//Range initializing constructors
constexpr explicit matrix_base(detail::zero_initialize_t);
constexpr explicit matrix_base(detail::no_initialize_t);
//Value initializing constructors
constexpr explicit matrix_base(value_type v);
template<Scalar... Args, std::enable_if_t<(std::is_convertible_v<Args,T> && ...),int> = 0>
constexpr matrix_base(Args&&... args);
//Copying constructors
constexpr matrix_base(const matrix_base&) = default;
constexpr matrix_base(matrix_base&&) = default;
template<Scalar U>
constexpr matrix_base(const matrix_base<U,Columns,Rows>& m);
~matrix_base(void) = default;
constexpr matrix_base& operator=(const matrix_base&) = default;
constexpr matrix_base& operator=(matrix_base&&) = default;
template<Scalar U, size_t TR, size_t TC>
constexpr matrix_base& operator=(const matrix_base<U,TR,TC>& m);
//Getters/Setters
constexpr auto operator[](size_type x);
constexpr auto operator[](size_type x)const;
constexpr reference get(size_type x, size_type y);
constexpr const_reference get(size_type x, size_type y)const;
constexpr reference get(size_type i);
constexpr const_reference get(size_type i)const;
constexpr size_type columns(void)const;
constexpr size_type rows(void)const;
constexpr size_type size(void)const;
constexpr pointer raw(void);
constexpr const_pointer raw(void)const;
constexpr operator pointer(void);
constexpr operator const_pointer(void)const;
};
//Non square matrices
template<Scalar T, size_t R, size_t C>
class matrix : public matrix_base<T,R,C>
{
private:
using base = matrix_base<T,R,C>;
public:
using value_type = typename base::value_type;
using size_type = typename base::size_type;
using pointer = typename base::pointer;
using const_pointer = typename base::const_pointer;
using reference = typename base::reference;
using const_reference = typename base::const_reference;
public:
using base::base;
template<size_t TR, size_t TC, std::enable_if_t<TR <= R && TC <= C,int> = 0>
constexpr matrix(const matrix_base<value_type,TR,TC>& other);
template<Scalar U>
constexpr matrix(const matrix<U,R,C>& other);
constexpr matrix(const matrix&) = default;
constexpr matrix(matrix&&) = default;
~matrix(void) = default;
//Assignement
constexpr matrix& operator=(const matrix&) = default;
constexpr matrix& operator=(matrix&&) = default;
template<Scalar U>
constexpr matrix& operator=(const matrix<U,R,C>& m);
};
//Square matrices
template<Scalar T, size_t R>
class matrix<T,R,R> : public matrix_base<T,R,R>
{
private:
using base = matrix_base<T,R,R>;
public:
using value_type = typename base::value_type;
using size_type = typename base::size_type;
using pointer = typename base::pointer;
using const_pointer = typename base::const_pointer;
using reference = typename base::reference;
using const_reference = typename base::const_reference;
public:
using base::base;
constexpr matrix(const matrix&) = default;
constexpr matrix(matrix&&) = default;
constexpr explicit matrix(detail::id_initialize_t);
template<size_t TR, size_t TC, std::enable_if_t<TR <= R && TC <= R,int> = 0>
constexpr matrix(const matrix_base<value_type,TR,TC>& other);
template<Scalar U>
constexpr matrix(const matrix<U,R,R>& other);
~matrix(void) = default;
//Assignement
constexpr matrix& operator=(const matrix&) = default;
constexpr matrix& operator=(matrix&&) = default;
template<Scalar U>
constexpr matrix& operator=(const matrix<U,R,R>& m);
//square matrix arithmetic operations
constexpr value_type determinate(void)const;
constexpr value_type trace(void)const;
constexpr matrix transpose(void)const;
constexpr matrix inverse(void)const;
};
template<Scalar T, size_t R>
constexpr T determinate(const matrix<T,R,R>& m);
template<Scalar T, size_t R>
constexpr matrix<T,R,R> inverse(const matrix<T,R,R>& m);
template<Scalar T>
matrix<T,2,2> rotation2d_pure(T angle);
template<Scalar T>
constexpr matrix<T,2,2> rotation2d_pure(T sin, T cos);
template<Scalar T>
constexpr matrix<T,2,2> scale2d(T x, T y);
template<Scalar T>
matrix<T,3,3> rotation2d(T angle);
template<Scalar T>
constexpr matrix<T,3,3> rotation2d(T sin, T cos);
template<Scalar T>
matrix<T,3,3> rotation2d(T x, T y, T z);
template<Scalar T>
constexpr matrix<T,4,4> rotation3d(T angle_x, T angle_y, T angle_z);
template<Scalar T>
constexpr matrix<T,4,4> translation3d(T x, T y, T z);
template<Scalar T>
constexpr matrix<T,4,4> scale3d(T x, T y, T z);
//Logic operators
template<Scalar T, Scalar U, size_t R, size_t C>
constexpr bool operator==(const matrix_base<T,R,C>& left, const matrix_base<U,R,C> right);
template<Scalar T, Scalar U, size_t R, size_t C>
constexpr bool operator!=(const matrix_base<T,R,C>& left, const matrix_base<U,R,C> right);
//Arithmetic operators
template<Scalar T, Scalar U, size_t R1, size_t C1, size_t R2>
constexpr auto operator*(const matrix<T,R1,C1>& left, const matrix<U,C1,R2>& right);
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr auto operator*(const matrix<T,R,C>& left, U&& right);
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr auto operator*(U&& left, const matrix<T,R,C>& right);
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr auto operator/(const matrix<T,R,C>& left, U&& right);
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr auto operator+(const matrix<T,R,C>& left, const matrix<U,R,C>& right);
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr auto operator-(const matrix<T,R,C>& left, const matrix<U,R,C>& right);
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr auto operator-(const matrix<T,R,C>& left);
template<Scalar T, size_t R, size_t C>
constexpr auto abs(const matrix_base<T,R,C>& left);
template<Scalar T, Scalar U, Scalar V, size_t R, size_t C>
constexpr bool fuzzy_eq(const matrix_base<T,R,C>& left, const matrix_base<U,R,C>& right, const V& epsilon);
template<Scalar T, Scalar U, Scalar V, size_t R, size_t C>
constexpr bool fuzzy_neq(const matrix_base<T,R,C>& left, const matrix_base<U,R,C>& right, const V& epsilon);
//Arithmetic assignment operators
template<Scalar T, Scalar U, size_t R>
constexpr decltype(auto) operator*=(matrix<T,R,R>& left, const matrix<U,R,R>& right);
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr decltype(auto) operator*=(matrix<T,R,C>& left, U&& right);
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr decltype(auto) operator/=(matrix<T,R,C>& left, U&& right);
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr decltype(auto) operator+=(matrix<T,R,C>& left, const matrix<U,R,C>& right);
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr decltype(auto) operator-=(matrix<T,R,C>& left, const matrix<U,R,C>& right);
extern template class matrix<float,2,2>;
extern template class matrix<float,3,3>;
extern template class matrix<float,4,4>;
}
#include "mat.tpp"
#endif

View File

@@ -1,424 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_MAT_TPP
#define REXY_MAT_TPP
#include <cstdlib> //size_t
#include <cmath> //sin, cos, abs
#include <type_traits> //decay_t, declval
#include "detail/matrix.hpp"
#include "quat.hpp"
namespace math{
namespace detail{
template<class T>
static constexpr const T& min(const T& l, const T& r){
return l < r ? l : r;
}
}
template<Scalar T, size_t R, size_t C>
template<size_t... Ss>
constexpr matrix_base<T,R,C>::matrix_base(std::integer_sequence<size_type,Ss...>):
m_data{Ss...}{}
template<Scalar T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::matrix_base(void):
matrix_base(typename detail::default_initialization_matrix<Columns,Rows>::tuple{}){}
template<Scalar T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::matrix_base(detail::zero_initialize_t):
m_data{}{}
template<Scalar T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::matrix_base(detail::no_initialize_t){}
template<Scalar T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::matrix_base(value_type v){
for(size_type i = 0; i < Columns*Rows; ++i)
m_data[i] = v;
}
template<Scalar T, size_t R, size_t C>
template<Scalar... Args, std::enable_if_t<(std::is_convertible_v<Args,T> && ...),int>>
constexpr matrix_base<T,R,C>::matrix_base(Args&&... args):
m_data{static_cast<value_type>(std::forward<Args>(args))...}{}
template<Scalar T, size_t R, size_t C>
template<Scalar U>
constexpr matrix_base<T,R,C>::matrix_base(const matrix_base<U,Columns,Rows>& m){
using mat = matrix_base<U,Columns,Rows>;
for(typename mat::size_type i = 0; i < mat::Columns*mat::Rows; ++i)
m_data[i] = m.get(i);
}
template<Scalar T, size_t R, size_t C>
template<Scalar U, size_t TR, size_t TC>
constexpr matrix_base<T,R,C>& matrix_base<T,R,C>::operator=(const matrix_base<U,TR,TC>& m){
constexpr auto cols = detail::min(TC, C);
constexpr auto rws = detail::min(TR, R);
for(size_type i = 0;i < cols;++i){
for(size_type j = 0;j < rws;++j){
get(i, j) = m.get(i, j);
}
}
return *this;
}
template<Scalar T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::operator[](size_type x){
return detail::mat_ref_obj<value_type,Rows>{m_data, x};
}
template<Scalar T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::operator[](size_type x)const{
return detail::mat_ref_obj<const value_type,Rows>{m_data, x};
}
template<Scalar T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::get(size_type x, size_type y) -> reference{
return m_data[(x*Rows)+y];
}
template<Scalar T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::get(size_type x, size_type y)const -> const_reference{
return m_data[(x*Rows)+y];
}
template<Scalar T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::get(size_type i) -> reference{
return m_data[i];
}
template<Scalar T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::get(size_type i)const -> const_reference{
return m_data[i];
}
template<Scalar T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::columns(void)const -> size_type{
return Columns;
}
template<Scalar T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::rows(void)const -> size_type{
return Rows;
}
template<Scalar T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::size(void)const -> size_type{
return Columns*Rows;
}
template<Scalar T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::raw(void) -> pointer{
return m_data;
}
template<Scalar T, size_t R, size_t C>
constexpr auto matrix_base<T,R,C>::raw(void)const -> const_pointer{
return m_data;
}
template<Scalar T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::operator pointer(void){
return m_data;
}
template<Scalar T, size_t R, size_t C>
constexpr matrix_base<T,R,C>::operator const_pointer(void)const{
return m_data;
}
template<Scalar T, size_t R, size_t C>
template<size_t TR, size_t TC, std::enable_if_t<TR <= R && TC <= C,int>>
constexpr matrix<T,R,C>::matrix(const matrix_base<value_type,TR,TC>& other){
for(size_type i = 0;i < TC;++i){
for(size_type j = 0;j < TR;++j){
get(i, j) = other.get(i, j);
}
}
}
template<Scalar T, size_t R, size_t C>
template<Scalar U>
constexpr matrix<T,R,C>::matrix(const matrix<U,R,C>& other){
for(size_type i = 0;i < C;++i){
for(size_type j = 0;j < R;++j){
get(i, j) = other.get(i, j);
}
}
}
template<Scalar T, size_t R, size_t C>
template<Scalar U>
constexpr matrix<T,R,C>& matrix<T,R,C>::operator=(const matrix<U,R,C>& m){
base::operator=(m);
return *this;
}
template<Scalar T, size_t R>
constexpr matrix<T,R,R>::matrix(detail::id_initialize_t):
base(){}
template<Scalar T, size_t R>
template<size_t TR, size_t TC, std::enable_if_t<TR <= R && TC <= R,int>>
constexpr matrix<T,R,R>::matrix(const matrix_base<value_type,TR,TC>& other):
matrix(id_initialize)
{
for(size_type i = 0;i < TC;++i){
for(size_type j = 0;j < TR;++j){
get(i, j) = other.get(i, j);
}
}
}
template<Scalar T, size_t R>
template<Scalar U>
constexpr matrix<T,R,R>::matrix(const matrix<U,R,R>& other){
for(size_type i = 0;i < R;++i){
for(size_type j = 0;j < R;++j){
get(i, j) = other.get(i, j);
}
}
}
template<Scalar T, size_t R>
template<Scalar U>
constexpr matrix<T,R,R>& matrix<T,R,R>::operator=(const matrix<U,R,R>& m){
base::operator=(m);
return *this;
}
template<Scalar T, size_t R>
constexpr auto matrix<T,R,R>::determinate(void)const -> value_type{
return math::determinate(*this);
}
template<Scalar T, size_t R>
constexpr auto matrix<T,R,R>::trace(void)const -> value_type{
value_type sum = 0;
for(size_type i = 0; i < R; ++i){
sum += this->get(i, i);
}
return sum;
}
template<Scalar T, size_t R>
constexpr matrix<T,R,R> matrix<T,R,R>::transpose(void)const{
matrix m(no_initialize);
for(size_type i = 0; i < R; ++i){
for(size_type j = 0; j < R; ++j){
m.get(j, i) = this->get(i, j);
}
}
return m;
}
template<Scalar T, size_t R>
constexpr matrix<T,R,R> matrix<T,R,R>::inverse(void)const{
return math::inverse(*this);
}
template<Scalar T, size_t R>
constexpr T determinate(const matrix<T,R,R>& m){
return detail::determinate_helper<T,R>::perform(m);
}
template<Scalar T, size_t R>
constexpr matrix<T,R,R> inverse(const matrix<T,R,R>& m){
return detail::inverse_helper<T,R>::perform(m);
}
template<Scalar T>
matrix<T,2,2> rotation2d_pure(T angle){
return rotation2d_pure(std::sin(angle), std::cos(angle));
}
template<Scalar T>
constexpr matrix<T,2,2> rotation2d_pure(T sin, T cos){
return matrix<T,2,2>(cos, sin, -sin, cos);
}
template<Scalar T>
constexpr matrix<T,2,2> scale2d(T x, T y){
return matrix<T,2,2>(x, T{0}, T{0}, y);
}
template<Scalar T>
matrix<T,3,3> rotation2d(T angle){
return rotation2d(std::sin(angle), std::cos(angle));
}
template<Scalar T>
constexpr matrix<T,3,3> rotation2d(T sin, T cos){
return matrix<T,3,3>(cos, -sin, T{0},
sin, cos, T{0},
T{0}, T{0}, T{1});
}
template<Scalar T>
matrix<T,3,3> rotation2d(T x, T y, T z){
quaternion<T> q(x, y, z);
return q.to_mat3();
}
template<Scalar T>
constexpr matrix<T,4,4> rotation3d(T angle_x, T angle_y, T angle_z){
quaternion<T> q(angle_x, angle_y, angle_z);
return q.to_mat4();
}
template<Scalar T>
constexpr matrix<T,4,4> translation3d(T x, T y, T z){
return matrix<T,4,4>(T{1}, T{0}, T{0}, T{0},
T{0}, T{1}, T{0}, T{0},
T{0}, T{0}, T{1}, T{0},
x, y, z, T{1});
}
template<Scalar T>
constexpr matrix<T,4,4> scale3d(T x, T y, T z){
return matrix<T,4,4>(x, T{0}, T{0}, T{0},
T{0}, y, T{0}, T{0},
T{0}, T{0}, z, T{0},
T{0}, T{0}, T{0}, T{1});
}
template<Scalar T, Scalar U, size_t R, size_t C>
constexpr bool operator==(const matrix_base<T,R,C>& left, const matrix_base<U,R,C> right){
for(size_t i = 0; i < left.size(); ++i){
if(left.get(i) != right.get(i))
return false;
}
return true;
}
template<Scalar T, Scalar U, size_t R, size_t C>
constexpr bool operator!=(const matrix_base<T,R,C>& left, const matrix_base<U,R,C> right){
return !(left == right);
}
template<Scalar T, Scalar U, size_t R1, size_t C1, size_t C2>
constexpr auto operator*(const matrix<T,R1,C1>& left, const matrix<U,C1,C2>& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
matrix<res_t,R1,C2> res(zero_initialize);
size_t index = 0;
for(size_t i = 0; i < right.rows(); ++i){
for(size_t j = 0; j < left.columns(); ++j){
for(size_t k = 0; k < left.rows(); ++k){
res.get(index) += right.get(i, k) * left.get(k, j);
}
++index;
}
}
return res;
}
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr auto operator*(const matrix<T,R,C>& left, U&& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
matrix<res_t,R,C> res(no_initialize);
for(size_t i = 0; i < left.size(); ++i){
res.get(i) = left.get(i) * std::forward<U>(right);
}
return res;
}
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr auto operator*(U&& left, const matrix<T,R,C>& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
matrix<res_t,R,C> res(no_initialize);
for(size_t i = 0; i < right.size(); ++i){
res.get(i) = std::forward<U>(left) * right.get(i);
}
return res;
}
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr auto operator/(const matrix<T,R,C>& left, U&& right){
using res_t = decltype(std::declval<T>() / std::declval<U>());
matrix<res_t,R,C> res(no_initialize);
for(size_t i = 0; i < left.size(); ++i){
res.get(i) = left.get(i) / std::forward<U>(right);
}
return res;
}
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr auto operator+(const matrix<T,R,C>& left, const matrix<U,R,C>& right){
using res_t = decltype(std::declval<T>() + std::declval<U>());
matrix<res_t,R,C> res(no_initialize);
for(size_t i = 0; i < left.size(); ++i){
res.get(i) = left.get(i) + right.get(i);
}
return res;
}
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr auto operator-(const matrix<T,R,C>& left, const matrix<U,R,C>& right){
using res_t = decltype(std::declval<T>() - std::declval<U>());
matrix<res_t,R,C> res(no_initialize);
for(size_t i = 0; i < left.size(); ++i){
res.get(i) = left.get(i) - right.get(i);
}
return res;
}
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr auto operator-(const matrix<T,R,C>& left){
using res_t = decltype(-std::declval<U>());
matrix<res_t,R,C> res(no_initialize);
for(size_t i = 0; i < left.size(); ++i){
res.get(i) = -left.get(i);
}
return res;
}
template<Scalar T, size_t R, size_t C>
constexpr auto abs(const matrix_base<T,R,C>& left){
matrix<T,R,C> res(no_initialize);
for(size_t i = 0; i < left.size(); ++i){
res.get(i) = std::abs(left.get(i));
}
return res;
}
template<Scalar T, Scalar U, Scalar V, size_t R, size_t C>
constexpr bool fuzzy_eq(const matrix_base<T,R,C>& left, const matrix_base<U,R,C>& right, const V& epsilon){
for(size_t i = 0;i < left.size();++i){
if(std::abs(left.get(i) - right.get(i)) > epsilon)
return false;
}
return true;
}
template<Scalar T, Scalar U, Scalar V, size_t R, size_t C>
constexpr bool fuzzy_neq(const matrix_base<T,R,C>& left, const matrix_base<U,R,C>& right, const V& epsilon){
return !fuzzy_eq(left, right, epsilon);
}
template<Scalar T, Scalar U, size_t R>
constexpr decltype(auto) operator*=(matrix<T,R,R>& left, const matrix<U,R,R>& right){
//have to evaluate entire expression first since matrix multiplication depends on reusing many elements
//cannot be expression templatized, TODO
return (left = (left * right));
}
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr decltype(auto) operator*=(matrix<T,R,C>& left, U&& right){
for(size_t i = 0; i < left.size(); ++i){
left.get(i) = left.get(i) * std::forward<U>(right);
}
return left;
}
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr decltype(auto) operator/=(matrix<T,R,C>& left, U&& right){
for(size_t i = 0; i < left.size(); ++i){
left.get(i) = left.get(i) / std::forward<U>(right);
}
return left;
}
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr decltype(auto) operator+=(matrix<T,R,C>& left, const matrix<U,R,C>& right){
for(size_t i = 0; i < left.size(); ++i){
left.get(i) = left.get(i) + right.get(i);
}
return left;
}
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr decltype(auto) operator-=(matrix<T,R,C>& left, const matrix<U,R,C>& right){
for(size_t i = 0; i < left.size(); ++i){
left.get(i) = left.get(i) - right.get(i);
}
return left;
}
}
#endif

View File

@@ -1,31 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_MATH_HPP
#define REXY_MATH_HPP
//include this file to access all the math components easily
#include "fwd_declare.hpp"
#include "math_common.hpp"
#include "vec.hpp"
#include "mat.hpp"
#include "quat.hpp"
#include "projection.hpp"
#endif

View File

@@ -1,83 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_DETAIL_MATH_HPP
#define REXY_DETAIL_MATH_HPP
#include "fwd_declare.hpp"
namespace math{
namespace detail{
//sentinel classes saying how to initialize some math classes
struct zero_initialize_t {};
struct no_initialize_t {};
struct id_initialize_t {};
struct manual_initialize_t {};
}
//instantiation of sentinels
static inline constexpr detail::zero_initialize_t zero_initialize;
static inline constexpr detail::no_initialize_t no_initialize;
static inline constexpr detail::id_initialize_t id_initialize;
static inline constexpr detail::manual_initialize_t manual_initialize;
template<Scalar T>
static constexpr T pi(void){
return static_cast<T>(3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821);
}
template<Scalar T>
static constexpr T to_degrees(T t){
return (t * 180.0) / pi<T>();
}
template<Scalar T>
static constexpr T to_radians(T t){
return (t * pi<T>()) / 180.0;
}
template<Scalar T>
static constexpr T clamp(const T& t, const T& min, const T& max){
if(t < min)
return min;
if(t > max)
return max;
return t;
}
template<Scalar T>
static constexpr T clamp_min(const T& t, const T& min){
if(t < min)
return min;
return t;
}
template<Scalar T>
static constexpr T clamp_max(const T& t, const T& max){
if(t > max)
return max;
return t;
}
}
constexpr long double operator"" _rad(long double f){
return f;
}
constexpr long double operator"" _deg(long double f){
return math::to_radians(f);
}
#endif

View File

@@ -1,46 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_MATH_PROJECTION_HPP
#define OUR_DICK_MATH_PROJECTION_HPP
#include "mat.hpp"
#include "vec.hpp"
#include "math_common.hpp"
namespace math{
template<Scalar T>
matrix<T,4,4> fov_projection(T fov, T asp, T near, T far);
template<Scalar T>
matrix<T,4,4> fov_asymetric_projection(T fovl, T fovr, T fovb, T fovt, T asp, T near, T far);
template<Scalar T>
matrix<T,4,4> ortho_projection(T w, T h, T n, T f);
template<Scalar T>
matrix<T,4,4> ortho_asymetric_projection(T l, T r, T b, T t, T n, T f);
template<Scalar T>
vec3<T> project(const mat4<T>& viewproj_mat, const vec3<T>& world_coords, const vec4<T>& viewport);
template<Scalar T>
vec3<T> unproject(const mat4<T>& viewproj_mat, const vec3<T>& viewport_coords, const vec4<T>& viewport);
}
#include "projection.tpp"
#endif

View File

@@ -1,98 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_MATH_PROJECTION_TPP
#define OUR_DICK_MATH_PROJECTION_TPP
#include "mat.hpp"
#include "vec.hpp"
#include <cmath> //sin, cos, tan
namespace math{
template<Scalar T>
matrix<T,4,4> fov_projection(T fov, T asp, T near, T far){
T r = near * std::tan(fov / T{2.0});
return matrix<T,4,4>((near / r) / asp, T{0}, T{0}, T{0},
T{0}, (near / r), T{0}, T{0},
T{0}, T{0}, (far + near) / (near - far), -T{1},
T{0}, T{0}, (T{2} * near * far) / (near - far), T{0});
}
template<Scalar T>
matrix<T,4,4> fov_asymetric_projection(T fovl, T fovr, T fovb, T fovt, T asp, T n, T f){
T l = n * std::tan(fovl);
T r = n * std::tan(fovr);
T b = n * std::tan(fovb);
T t = n * std::tan(fovt);
return matrix<T,4,4>(((T{2} * n) / (r - l)) * asp, T{0}, T{0}, T{0},
T{0}, (T{2} * n) / (t - b), T{0}, T{0},
(r + l) / (r - l), (t + b) / (t - b), (f + n) / (n - f), -T{1},
T{0}, T{0}, (T{2} * n * f) / (n - f), T{0});
}
template<Scalar T>
matrix<T,4,4> ortho_projection(T w, T h, T n, T f){
return matrix<T,4,4>(T{2} / w, T{0}, T{0}, T{0},
T{0}, T{2} / h, T{0}, T{0},
T{0}, T{0}, T{1} / (n - f), T{0},
T{0}, T{0}, (n + f) / (n - f), T{1});
}
template<Scalar T>
matrix<T,4,4> ortho_asymetric_projection(T l, T r, T b, T t, T n, T f){
return matrix<T,4,4>(T{2} / (r - l), T{0}, T{0}, T{0},
T{0}, T{2} / (t - b), T{0}, T{0},
T{0}, T{0}, T{1} / (n - f), T{0},
(r + l) / (l - r), (t + b) / (b - t), (n + f) / (n - f), T{1});
}
template<Scalar T>
vec3<T> project(const mat4<T>& viewproj_mat, const vec3<T>& w_coords, const vec4<T>& viewport){
//project world coordinates to ndc coordinates
vec4<T> world_coords{w_coords[0], w_coords[1], w_coords[2], T{1.0}};
vec4<T> ndc_coords = viewproj_mat * world_coords;
//perspective_division
ndc_coords /= ndc_coords[3];
//project ndc coordinates to viewport coordinates
return vec3<T>{((ndc_coords[0] + T{1.0}) * viewport[2] * T{0.5}) + viewport[0],
((ndc_coords[1] + T{1.0}) * viewport[3] * T{0.5}) + viewport[1],
ndc_coords[2]
};
}
template<Scalar T>
vec3<T> unproject(const mat4<T>& viewproj_mat, const vec3<T>& viewport_coords, const vec4<T>& viewport){
//project viewport coordinates to ndc coordinates
vec4<T> ndc_coords{((viewport_coords[0] - viewport[0]) * T{2.0} / viewport[2]) - T{1.0},
((viewport_coords[1] - viewport[1]) * T{2.0} / viewport[3]) - T{1.0},
viewport_coords[2],
T{1.0}};
//project ndc coordinates to world coordinates
mat4<T> inv_viewproj_mat = viewproj_mat.inverse();
vec4<T> world_coords = inv_viewproj_mat * ndc_coords;
//perspective division
world_coords /= world_coords[3];
return {world_coords[0], world_coords[1], world_coords[2]};
}
}
#endif

View File

@@ -1,149 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_QUAT_HPP
#define REXY_QUAT_HPP
#include <cstdlib> //size_t
#include <utility> //pair
#include <type_traits> //is_same, is_arithmetic, integral_constant
#include "math_common.hpp"
#include "fwd_declare.hpp"
namespace math{
//( ͡° ͜ʖ ͡°)
template<Scalar T>
class quaternion
{
public:
using value_type = T;
using size_type = size_t;
using pointer = value_type*;
using const_pointer = const value_type*;
using reference = value_type&;
using const_reference = const value_type&;
private:
value_type m_data[4];
public:
constexpr quaternion(void);
//Construct from Euler angles
constexpr quaternion(detail::zero_initialize_t);
constexpr quaternion(detail::id_initialize_t);
constexpr quaternion(detail::no_initialize_t);
constexpr quaternion(detail::manual_initialize_t,
value_type w, value_type x,
value_type y, value_type z);
quaternion(const mat3<T>& rotmat);
quaternion(const mat4<T>& rotmat);
quaternion(value_type bank, value_type heading, value_type attitude);
quaternion(const vec3<value_type>& angles);
//Construct from axis-angle
quaternion(value_type angle, const vec3<value_type>& axis);
quaternion(value_type angle, value_type x, value_type y, value_type z);
//Copy ctor
constexpr quaternion(const quaternion&) = default;
constexpr quaternion(quaternion&&) = default;
~quaternion(void) = default;
//Assignment
constexpr quaternion& operator=(const quaternion&) = default;
constexpr quaternion& operator=(quaternion&&) = default;
//Direct array access
constexpr operator pointer(void);
constexpr operator const_pointer(void)const;
constexpr reference operator[](size_type i);
constexpr const_reference operator[](size_type i)const;
constexpr reference get(size_type i);
constexpr const_reference get(size_type i)const;
constexpr reference w(void);
constexpr const_reference w(void)const;
constexpr reference x(void);
constexpr const_reference x(void)const;
constexpr reference y(void);
constexpr const_reference y(void)const;
constexpr reference z(void);
constexpr const_reference z(void)const;
//Assign axis from angle-axis
void set_axis(value_type x, value_type y, value_type z);
void set_axis(const vec3<value_type>& axis);
vec3<value_type> get_axis(void)const;
void set_angle(value_type a);
value_type get_angle(void)const;
value_type norm(void)const;
quaternion conjugate(void)const;
quaternion inverse(void)const;
value_type magnitude(void)const;
quaternion normalize(void)const;
vec3<value_type> get_right(void)const;
vec3<value_type> get_up(void)const;
vec3<value_type> get_forward(void)const;
//Explicit Conversion1
vec3<value_type> to_vec3(void)const;
vec4<value_type> to_vec4(void)const;
mat3<value_type> to_mat3(void)const;
mat4<value_type> to_mat4(void)const;
vec3<value_type> to_euler_angles(void)const;
std::pair<value_type,vec3<value_type>> to_axis_angle(void)const;
};
template<Scalar T, Scalar U>
bool operator==(const quaternion<T>& left, const quaternion<U>& right);
template<Scalar T, Scalar U>
bool operator!=(const quaternion<T>& left, const quaternion<U>& right);
template<Scalar T>
auto operator-(const quaternion<T>& left);
template<Scalar T, Scalar U>
auto operator-(const quaternion<T>& left, const quaternion<U>& right);
template<Scalar T, Scalar U>
auto operator+(const quaternion<T>& left, const quaternion<U>& right);
template<Scalar T, Scalar U>
auto operator*(const quaternion<T>& left, const quaternion<U>& right);
template<Scalar T, Scalar U>
auto operator*(const quaternion<T>& left, const vec3<U>& right);
template<Scalar T, Scalar U>
auto operator*(const quaternion<T>& left, U&& right);
template<Scalar T, Scalar U>
auto operator/(const quaternion<T>& left, U&& right);
template<Scalar T, Scalar U>
decltype(auto) operator+=(quaternion<T>& left, const quaternion<U>& right);
template<Scalar T, Scalar U>
decltype(auto) operator-=(quaternion<T>& left, const quaternion<U>& right);
template<Scalar T, Scalar U>
decltype(auto) operator*=(quaternion<T>& left, const quaternion<U>& right);
template<Scalar T, Scalar U>
decltype(auto) operator*=(quaternion<T>& left, U&& right);
template<Scalar T, Scalar U>
decltype(auto) operator/=(quaternion<T>& left, U&& right);
extern template class quaternion<float>;
}
#include "quat.tpp"
#endif

View File

@@ -1,437 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_QUAT_TPP
#define REXY_QUAT_TPP
#include <cmath> //sin, cos, tan, sqrt, etc
#include "mat.hpp"
#include "vec.hpp"
namespace math{
template<Scalar T>
constexpr quaternion<T>::quaternion(void):
quaternion(id_initialize){}
template<Scalar T>
constexpr quaternion<T>::quaternion(detail::zero_initialize_t):
m_data{0, 0, 0, 0}{}
template<Scalar T>
constexpr quaternion<T>::quaternion(detail::id_initialize_t):
m_data{1, 0, 0, 0}{}
template<Scalar T>
constexpr quaternion<T>::quaternion(detail::no_initialize_t){}
template<Scalar T>
constexpr quaternion<T>::quaternion(detail::manual_initialize_t,
value_type w, value_type x,
value_type y, value_type z):
m_data{w, x, y, z}{}
template<Scalar T>
quaternion<T>::quaternion(const mat3<T>& rotmat){
auto tr = rotmat.trace();
if(tr > 0){
auto f = 0.5 / sqrt(tr + 1.0);
m_data[0] = 0.25 / f;
m_data[1] = (rotmat.get(5) - rotmat.get(7)) * f;
m_data[2] = (rotmat.get(6) - rotmat.get(2)) * f;
m_data[3] = (rotmat.get(1) - rotmat.get(3)) * f;
}else if((rotmat.get(0) > rotmat.get(4)) && (rotmat.get(0) > rotmat.get(8))){
auto f = sqrt(1.0 + rotmat.get(0) - rotmat.get(4) - rotmat.get(8)) * 2.0;
m_data[0] = (rotmat.get(5) - rotmat.get(7)) / f;
m_data[1] = f * 0.25;
m_data[2] = (rotmat.get(3) + rotmat.get(1)) / f;
m_data[3] = (rotmat.get(6) + rotmat.get(2)) / f;
}else if(rotmat.get(4) > rotmat.get(8)){
auto f = sqrt(1.0 + rotmat.get(4) - rotmat.get(0) - rotmat.get(8)) * 2.0;
m_data[0] = (rotmat.get(6) - rotmat.get(2)) / f;
m_data[1] = (rotmat.get(3) + rotmat.get(1)) / f;
m_data[2] = f * 0.25;
m_data[3] = (rotmat.get(7) + rotmat.get(5)) / f;
}else{
auto f = sqrt(1.0 + rotmat.get(8) - rotmat.get(0) - rotmat.get(4)) * 2.0;
m_data[0] = (rotmat.get(1) - rotmat.get(3)) / f;
m_data[1] = (rotmat.get(6) + rotmat.get(2)) / f;
m_data[2] = (rotmat.get(7) + rotmat.get(5)) / f;
m_data[3] = f * 0.25;
}
}
template<Scalar T>
quaternion<T>::quaternion(const mat4<T>& rotmat):
quaternion(mat3<T>{rotmat.get(0), rotmat.get(1), rotmat.get(2),
rotmat.get(4), rotmat.get(5), rotmat.get(6),
rotmat.get(8), rotmat.get(9), rotmat.get(10)}){}
template<Scalar T>
quaternion<T>::quaternion(value_type bank, value_type heading, value_type attitude){
bank /= value_type{2};
heading /= value_type{2};
attitude /= value_type{2};
value_type cos_heading = std::cos(heading);
value_type sin_heading = std::sin(heading);
value_type cos_attitude = std::cos(attitude);
value_type sin_attitude = std::sin(attitude);
value_type cos_bank = std::cos(bank);
value_type sin_bank = std::sin(bank);
m_data[0] = (cos_heading * cos_attitude * cos_bank) - (sin_heading * sin_attitude * sin_bank);
m_data[1] = (sin_heading * sin_attitude * cos_bank) + (cos_heading * cos_attitude * sin_bank);
m_data[2] = (sin_heading * cos_attitude * cos_bank) + (cos_heading * sin_attitude * sin_bank);
m_data[3] = (cos_heading * sin_attitude * cos_bank) - (sin_heading * cos_attitude * sin_bank);
}
template<Scalar T>
quaternion<T>::quaternion(const vec3<T>& angles):
quaternion(angles.x(), angles.y(), angles.z()){}
template<Scalar T>
quaternion<T>::quaternion(value_type angle, const vec3<value_type>& axis):
quaternion(angle, axis.x(), axis.y(), axis.z()){}
template<Scalar T>
quaternion<T>::quaternion(value_type angle, value_type x, value_type y, value_type z){
angle /= value_type{2.0};
value_type sin_angle = std::sin(angle);
m_data[0] = std::cos(angle);
m_data[1] = sin_angle * x;
m_data[2] = sin_angle * y;
m_data[3] = sin_angle * z;
}
template<Scalar T>
constexpr quaternion<T>::operator pointer(void){
return m_data;
}
template<Scalar T>
constexpr quaternion<T>::operator const_pointer(void)const{
return m_data;
}
template<Scalar T>
constexpr auto quaternion<T>::operator[](size_type i) -> reference{
return m_data[i];
}
template<Scalar T>
constexpr auto quaternion<T>::operator[](size_type i)const -> const_reference{
return m_data[i];
}
template<Scalar T>
constexpr auto quaternion<T>::get(size_type i) -> reference{
return m_data[i];
}
template<Scalar T>
constexpr auto quaternion<T>::get(size_type i)const -> const_reference{
return m_data[i];
}
template<Scalar T>
constexpr auto quaternion<T>::w(void) -> reference{
return m_data[0];
}
template<Scalar T>
constexpr auto quaternion<T>::w(void)const -> const_reference{
return m_data[0];
}
template<Scalar T>
constexpr auto quaternion<T>::x(void) -> reference{
return m_data[1];
}
template<Scalar T>
constexpr auto quaternion<T>::x(void)const -> const_reference{
return m_data[1];
}
template<Scalar T>
constexpr auto quaternion<T>::y(void) -> reference{
return m_data[2];
}
template<Scalar T>
constexpr auto quaternion<T>::y(void)const -> const_reference{
return m_data[2];
}
template<Scalar T>
constexpr auto quaternion<T>::z(void) -> reference{
return m_data[3];
}
template<Scalar T>
constexpr auto quaternion<T>::z(void)const -> const_reference{
return m_data[3];
}
template<Scalar T>
void quaternion<T>::set_axis(value_type x, value_type y, value_type z){
value_type sin_angle = std::sin(std::acos(m_data[0]));
m_data[1] = sin_angle * x;
m_data[2] = sin_angle * y;
m_data[3] = sin_angle * z;
}
template<Scalar T>
void quaternion<T>::set_axis(const vec3<value_type>& v){
set_axis(v.x(), v.y(), v.z());
}
template<Scalar T>
auto quaternion<T>::get_axis(void)const -> vec3<value_type>{
quaternion tmp(*this);
if(m_data[0] > value_type{1.0})
tmp = tmp.normalize();
value_type s = std::sqrt(1 - tmp.m_data[0] * tmp.m_data[0]);
if(s <= value_type{0.001})
return vec3<T>(1, 0, 0);
return vec3<T>(tmp.m_data[1] / s, tmp.m_data[2] / s, tmp.m_data[3] / s);
}
template<Scalar T>
void quaternion<T>::set_angle(value_type t){
t /= value_type{2.0};
value_type old_sin_angle = std::sin(std::acos(m_data[0]));
value_type sin_angle = std::sin(t);
m_data[0] = std::cos(t);
m_data[1] = (m_data[1] / old_sin_angle) * sin_angle;
m_data[2] = (m_data[2] / old_sin_angle) * sin_angle;
m_data[3] = (m_data[3] / old_sin_angle) * sin_angle;
}
template<Scalar T>
auto quaternion<T>::get_angle(void)const -> value_type{
return 2.0 * std::acos(m_data[0]);
}
template<Scalar T>
auto quaternion<T>::norm(void)const -> value_type{
return m_data[0] * m_data[0] + m_data[1] * m_data[1] + m_data[2] * m_data[2] + m_data[3] * m_data[3];
}
template<Scalar T>
quaternion<T> quaternion<T>::conjugate(void)const{
return quaternion(manual_initialize, m_data[0], -m_data[1], -m_data[2], -m_data[3]);
}
template<Scalar T>
quaternion<T> quaternion<T>::inverse(void)const{
return conjugate() / norm();
}
template<Scalar T>
auto quaternion<T>::magnitude(void)const -> value_type{
return std::sqrt(norm());
}
template<Scalar T>
quaternion<T> quaternion<T>::normalize(void)const{
value_type mag = magnitude();
return quaternion(manual_initialize, m_data[0] / mag, m_data[1] / mag, m_data[2] / mag, m_data[3] / mag);
}
template<Scalar T>
auto quaternion<T>::get_right(void)const -> vec3<value_type>{
return vec3<value_type>(1 - 2 * ((m_data[2] * m_data[2]) + (m_data[3] * m_data[3])),
2 * ((m_data[1] * m_data[2]) - (m_data[3] * m_data[0])),
2 * ((m_data[1] * m_data[3]) + (m_data[2] * m_data[0])));
}
template<Scalar T>
auto quaternion<T>::get_up(void)const -> vec3<value_type>{
return vec3<value_type>( 2 * ((m_data[1] * m_data[2]) + (m_data[3] * m_data[0])),
1 - 2 * ((m_data[1] * m_data[1]) + (m_data[3] * m_data[3])),
2 * ((m_data[2] * m_data[3]) - (m_data[1] * m_data[0])));
}
template<Scalar T>
auto quaternion<T>::get_forward(void)const -> vec3<value_type>{
return vec3<value_type>( 2 * ((m_data[1] * m_data[3]) - (m_data[2] * m_data[0])),
2 * ((m_data[2] * m_data[3]) + (m_data[1] * m_data[0])),
1 - 2 * ((m_data[1] * m_data[1]) + (m_data[2] * m_data[2])));
}
template<Scalar T>
auto quaternion<T>::to_vec3(void)const -> vec3<value_type>{
return vec3<value_type>(m_data[1], m_data[2], m_data[3]);
}
template<Scalar T>
auto quaternion<T>::to_vec4(void)const -> vec4<value_type>{
return vec4<value_type>(m_data[1], m_data[2], m_data[3]);
}
template<Scalar T>
auto quaternion<T>::to_mat3(void)const -> mat3<value_type>{
mat3<value_type> m;
value_type xx = m_data[1] * m_data[1];
value_type yy = m_data[2] * m_data[2];
value_type zz = m_data[3] * m_data[3];
value_type xy = m_data[1] * m_data[2];
value_type xz = m_data[1] * m_data[3];
value_type xw = m_data[1] * m_data[0];
value_type yz = m_data[2] * m_data[3];
value_type yw = m_data[2] * m_data[0];
value_type zw = m_data[3] * m_data[0];
m.get(0) = 1 - 2 * (yy + zz);
m.get(1) = 2 * (xy + zw);
m.get(2) = 2 * (xz - yw);
m.get(3) = 2 * (xy - zw);
m.get(4) = 1 - 2 * (xx + zz);
m.get(5) = 2 * (yz + xw);
m.get(6) = 2 * (xz + yw);
m.get(7) = 2 * (yz - xw);
m.get(8) = 1 - 2 * (xx + yy);
return m;
}
template<Scalar T>
auto quaternion<T>::to_mat4(void)const -> mat4<value_type>{
mat4<value_type> m;
value_type xx = m_data[1] * m_data[1];
value_type yy = m_data[2] * m_data[2];
value_type zz = m_data[3] * m_data[3];
value_type xy = m_data[1] * m_data[2];
value_type xz = m_data[1] * m_data[3];
value_type xw = m_data[1] * m_data[0];
value_type yz = m_data[2] * m_data[3];
value_type yw = m_data[2] * m_data[0];
value_type zw = m_data[3] * m_data[0];
m.get(0) = 1 - 2 * (yy + zz);
m.get(1) = 2 * (xy + zw);
m.get(2) = 2 * (xz - yw);
m.get(3) = 0;
m.get(4) = 2 * (xy - zw);
m.get(5) = 1 - 2 * (xx + zz);
m.get(6) = 2 * (yz + xw);
m.get(7) = 0;
m.get(8) = 2 * (xz + yw);
m.get(9) = 2 * (yz - xw);
m.get(10) = 1 - 2 * (xx + yy);
m.get(11) = 0;
m.get(12) = 0;
m.get(13) = 0;
m.get(14) = 0;
m.get(15) = 1;
return m;
}
template<Scalar T>
auto quaternion<T>::to_euler_angles(void)const -> vec3<value_type>{
value_type ww = m_data[0] * m_data[0];
value_type xx = m_data[1] * m_data[1];
value_type yy = m_data[2] * m_data[2];
value_type zz = m_data[3] * m_data[3];
value_type correction = ww + xx + yy + zz;
value_type test = m_data[1] * m_data[2] + m_data[3] * m_data[0];
if(test > 0.499 * correction){
return vec3<value_type>(0, 2 * std::atan2(m_data[1], m_data[0]), pi<value_type>() / 2.0);
}else if(test < -0.499 * correction){
return vec3<value_type>(0, -2 * std::atan2(m_data[1], m_data[0]), -pi<value_type>() / 2.0);
}
return vec3<value_type>(std::atan2((2 * m_data[1] * m_data[0]) - (2 * m_data[2] * m_data[3]), ww - xx + yy - zz),
std::atan2((2 * m_data[2] * m_data[0]) - (2 * m_data[1] * m_data[3]), xx - yy - zz + ww),
std::asin(2 * test / correction));
}
template<Scalar T>
auto quaternion<T>::to_axis_angle(void)const -> std::pair<value_type,vec3<value_type>>{
quaternion q(*this);
if(m_data[0] > 1.0)
q = q.normalize();
value_type s = std::sqrt(1 - q.m_data[0] * q.m_data[0]);
if(s <= value_type{0.001}){
return {2 * std::acos(q.m_data[0]), {1, 0, 0}};
}
return {2 * std::acos(q.m_data[0]), {q.m_data[1] / s, q.m_data[2] / s, q.m_data[3] / s}};
}
template<Scalar T, Scalar U>
bool operator==(const quaternion<T>& left, const quaternion<U>& right){
return left.w() == right.w() &&
left.x() == right.x() &&
left.y() == right.y() &&
left.z() == right.z();
}
template<Scalar T, Scalar U>
bool operator!=(const quaternion<T>& left, const quaternion<U>& right){
return !(left == right);
}
template<Scalar T>
auto operator-(const quaternion<T>& left){
using res_t = T;
return quaternion<res_t>(manual_initialize, -left.w(), -left.x(), -left.y(), -left.z());
}
template<Scalar T, Scalar U>
auto operator-(const quaternion<T>& left, const quaternion<U>& right){
using res_t = decltype(std::declval<T>() - std::declval<U>());
return quaternion<res_t>(manual_initialize, left.w() - right.w(), left.x() - right.x(),
left.y() - right.y(), left.z() - right.z());
}
template<Scalar T, Scalar U>
auto operator+(const quaternion<T>& left, const quaternion<U>& right){
using res_t = decltype(std::declval<T>() + std::declval<U>());
return quaternion<res_t>(manual_initialize, left.w() + right.w(), left.x() + right.x(),
left.y() + right.y(), left.z() + right.z());
}
template<Scalar T, Scalar U>
auto operator*(const quaternion<T>& left, const quaternion<U>& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
return quaternion<res_t>(manual_initialize,
(right.w() * left.w()) - (right.x() * left.x()) -
(right.y() * left.y()) - (right.z() * left.z()),
(right.w() * left.x()) + (right.x() * left.w()) +
(right.y() * left.z()) - (right.z() * left.y()),
(right.w() * left.y()) - (right.x() * left.z()) +
(right.y() * left.w()) + (right.z() * left.x()),
(right.w() * left.z()) + (right.x() * left.y()) -
(right.y() * left.x()) + (right.z() * left.w()));
}
template<Scalar T, Scalar U>
auto operator*(const quaternion<T>& left, const vec3<U>& right){
return left.to_mat3() * right;
}
template<Scalar T, Scalar U>
auto operator*(const quaternion<T>& left, U&& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
return quaternion<res_t>(manual_initialize, left.w() * right, left.x() * right, left.y() * right, left.z() * right);
}
template<Scalar T, Scalar U>
auto operator/(const quaternion<T>& left, U&& right){
using res_t = decltype(std::declval<T>() / std::declval<U>());
return quaternion<res_t>(manual_initialize, left.w() / right, left.x() / right, left.y() / right, left.z() / right);
}
template<Scalar T, Scalar U>
decltype(auto) operator+=(quaternion<T>& left, const quaternion<U>& right){
left.w() += right.w();
left.x() += right.x();
left.y() += right.y();
left.z() += right.z();
return left;
}
template<Scalar T, Scalar U>
decltype(auto) operator-=(quaternion<T>& left, const quaternion<U>& right){
left.w() -= right.w();
left.x() -= right.x();
left.y() -= right.y();
left.z() -= right.z();
return left;
}
template<Scalar T, Scalar U>
decltype(auto) operator*=(quaternion<T>& left, const quaternion<U>& right){
left = left * right;
return left;
}
template<Scalar T, Scalar U>
decltype(auto) operator*=(quaternion<T>& left, U&& right){
left.w() *= right;
left.x() *= right;
left.y() *= right;
left.z() *= right;
return left;
}
template<Scalar T, Scalar U>
decltype(auto) operator/=(quaternion<T>& left, U&& right){
left.w() /= right;
left.x() /= right;
left.y() /= right;
left.z() /= right;
return left;
}
}
#endif

View File

@@ -1,128 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_VEC_HPP
#define REXY_VEC_HPP
#include "mat.hpp"
#include "math_common.hpp"
namespace math{
//class representing vectors
//inherit from matrix base because it also shared matrix attributes
template<Scalar T, size_t R>
class vector : public matrix_base<T,R,1>
{
private:
using base = matrix_base<T,R,1>;
public:
using value_type = typename base::value_type;
using size_type = typename base::size_type;
using pointer = typename base::pointer;
using const_pointer = typename base::const_pointer;
using reference = typename base::reference;
using const_reference = typename base::const_reference;
public:
using base::base;
template<size_t TR,Scalar... Args,std::enable_if_t<TR <= R && (std::is_convertible_v<Args,T> && ...),int> = 0>
constexpr vector(const vector<T,TR>& other, Args&&... args);
template<Scalar U>
constexpr vector(const vector<U,R>& other);
constexpr vector(const vector&) = default;
constexpr vector(vector&&) = default;
~vector(void) = default;
//Assignement
constexpr vector& operator=(const vector&) = default;
constexpr vector& operator=(vector&&) = default;
template<Scalar U, size_t TR>
constexpr vector& operator=(const vector<U,TR>& m);
constexpr reference operator[](size_type i);
constexpr const_reference operator[](size_type i)const;
constexpr reference x(void);
constexpr const_reference x(void)const;
template<Scalar U = T>
constexpr reference y(void);
template<Scalar U = T>
constexpr const_reference y(void)const;
template<Scalar U = T>
constexpr reference z(void);
template<Scalar U = T>
constexpr const_reference z(void)const;
template<Scalar U = T>
constexpr reference w(void);
template<Scalar U = T>
constexpr const_reference w(void)const;
value_type magnitude(void)const;
vector normalize(void);
protected:
template<Scalar U, Scalar... Args>
constexpr void assign_(size_type offset, U&& u, Args&&... args);
};
template<Scalar T>
constexpr auto perp(const vector<T,2>& v);
template<Scalar T, Scalar U, size_t R1, size_t R2>
constexpr auto perp(const vector<T,R1>& left, const vector<U,R2>& right);
template<Scalar T, Scalar U>
constexpr auto cross(const vector<T,3>& left, const vector<U,3>& right);
template<Scalar T, size_t R>
constexpr auto magnitude(const vector<T,R>& v);
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr auto operator*(const matrix<U,R,C>& left, const vector<T,C>& right);
template<Scalar T, Scalar U, size_t R>
constexpr auto operator*(const vector<T,R>& left, const vector<U,R>& right);
template<Scalar T, Scalar U, size_t R>
constexpr auto operator*(const vector<T,R>& left, U&& right);
template<Scalar T, Scalar U, size_t R>
constexpr auto operator*(U&& left, const vector<T,R>& right);
template<Scalar T, Scalar U, size_t R>
constexpr auto operator/(const vector<T,R>& left, U&& right);
template<Scalar T, Scalar U, size_t R>
constexpr auto operator+(const vector<T,R>& left, const vector<U,R>& right);
template<Scalar T, Scalar U, size_t R>
constexpr auto operator-(const vector<T,R>& left, const vector<U,R>& right);
template<Scalar T, Scalar U, size_t R>
constexpr auto operator-(const vector<T,R>& left);
template<Scalar T, Scalar U, size_t R>
constexpr decltype(auto) operator*=(vector<T,R>& left, U&& right);
template<Scalar T, Scalar U, size_t R>
constexpr decltype(auto) operator/=(vector<T,R>& left, U&& right);
template<Scalar T, Scalar U, size_t R>
constexpr decltype(auto) operator+=(vector<T,R>& left, const vector<U,R>& right);
template<Scalar T, Scalar U, size_t R>
constexpr decltype(auto) operator-=(vector<T,R>& left, const vector<U,R>& right);
extern template class vector<float,2>;
extern template class vector<float,3>;
extern template class vector<float,4>;
}
#include "vec.tpp"
#endif

View File

@@ -1,254 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2020 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REXY_VEC_TPP
#define REXY_VEC_TPP
#include <cmath> //sqrt
namespace math{
template<Scalar T, size_t R>
template<size_t TR,Scalar... Args,std::enable_if_t<TR <= R && (std::is_convertible_v<Args,T> && ...),int>>
constexpr vector<T,R>::vector(const vector<T,TR>& other, Args&&... args){
static_assert(sizeof...(args) + TR <= R);
size_type i = 0;
for(;i < TR;++i){
this->m_data[i] = other[i];
}
if constexpr(sizeof...(args) > 0){
assign_(i, std::forward<Args>(args)...);
}
}
template<Scalar T, size_t R>
template<Scalar U>
constexpr vector<T,R>::vector(const vector<U,R>& other){
for(size_type i = 0;i < R;++i){
this->m_data[i] = other[i];
}
}
template<Scalar T, size_t R>
template<Scalar U, Scalar... Args>
constexpr void vector<T,R>::assign_(size_type offset, U&& u, Args&&... args){
this->m_data[offset] = std::forward<U>(u);
if constexpr(sizeof...(args) > 0){
assign_(offset + 1, std::forward<Args>(args)...);
}
}
template<Scalar T, size_t R>
template<Scalar U, size_t TR>
constexpr vector<T,R>& vector<T,R>::operator=(const vector<U,TR>& m){
base::operator=(m);
return *this;
}
template<Scalar T, size_t R>
constexpr auto vector<T,R>::operator[](size_type i) -> reference{
return this->m_data[i];
}
template<Scalar T, size_t R>
constexpr auto vector<T,R>::operator[](size_type i)const -> const_reference{
return this->m_data[i];
}
template<Scalar T, size_t R>
constexpr auto vector<T,R>::x(void) -> reference{
return this->m_data[0];
}
template<Scalar T, size_t R>
constexpr auto vector<T,R>::x(void)const -> const_reference{
return this->m_data[0];
}
template<Scalar T, size_t R>
template<Scalar U>
constexpr auto vector<T,R>::y(void) -> reference{
static_assert(R > 1, "Vector does not contain a 2nd element");
return this->m_data[1];
}
template<Scalar T, size_t R>
template<Scalar U>
constexpr auto vector<T,R>::y(void)const -> const_reference{
static_assert(R > 1, "Vector does not contain a 2nd element");
return this->m_data[1];
}
template<Scalar T, size_t R>
template<Scalar U>
constexpr auto vector<T,R>::z(void) -> reference{
static_assert(R > 2, "Vector does not contain a 3rd element");
return this->m_data[2];
}
template<Scalar T, size_t R>
template<Scalar U>
constexpr auto vector<T,R>::z(void)const -> const_reference{
static_assert(R > 2, "Vector does not contain a 3rd element");
return this->m_data[2];
}
template<Scalar T, size_t R>
template<Scalar U>
constexpr auto vector<T,R>::w(void) -> reference{
static_assert(R > 3, "Vector does not contain a 4th element");
return this->m_data[3];
}
template<Scalar T, size_t R>
template<Scalar U>
constexpr auto vector<T,R>::w(void)const -> const_reference{
static_assert(R > 3, "Vector does not contain a 4th element");
return this->m_data[3];
}
template<Scalar T, size_t R>
auto vector<T,R>::magnitude(void)const -> value_type{
value_type sum = 0;
for(size_type i = 0;i < R;++i){
sum += (this->m_data[i] * this->m_data[i]);
}
return sqrt(sum);
}
template<Scalar T, size_t R>
vector<T,R> vector<T,R>::normalize(void){
return (*this) / magnitude();
}
template<Scalar T>
constexpr auto perp(const vector<T,2>& v){
return vec2<T>(-v[1], v[0]);
}
template<Scalar T, Scalar U, size_t R1, size_t R2>
constexpr auto perp(const vector<T,R1>& left, const vector<U,R2>& right){
return (left[0] * right[1]) - (left[1] * right[0]);
}
template<Scalar T, Scalar U>
constexpr auto cross(const vector<T,3>& left, const vector<U,3>& right){
using res_t = decltype(left[0] * right[0]);
return vec3<res_t>((left[1] * right[2]) - (left[2] * right[1]),
(left[2] * right[0]) - (left[0] * right[2]),
(left[0] * right[1]) - (left[1] * right[0]));
}
template<Scalar T, size_t R>
constexpr auto magnitude(const vector<T,R>& v){
return v.magnitude();
}
template<Scalar T, Scalar U, size_t C, size_t R>
constexpr auto operator*(const matrix<U,R,C>& left, const vector<T,C>& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
vector<res_t,R> res(zero_initialize);
size_t index = 0;
//columns == rows
for(size_t i = 0; i < R; ++i){
for(size_t k = 0; k < C; ++k){
res.get(index) += left.get(k, i) * right[k];
}
++index;
}
return res;
}
template<Scalar T, Scalar U, size_t R>
constexpr auto operator*(const vector<T,R>& left, const vector<U,R>& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
res_t res = 0;
for(size_t i = 0; i < R; ++i){
res += left[i] * right[i];
}
return res;
}
template<Scalar T, Scalar U, size_t R>
constexpr auto operator*(const vector<T,R>& left, U&& right){
using res_t = decltype(std::declval<T>() * std::declval<U>());
vector<res_t,R> res(zero_initialize);
for(size_t i = 0; i < R; ++i){
res[i] = left[i] * std::forward<U>(right);
}
return res;
}
template<Scalar T, Scalar U, size_t R>
constexpr auto operator*(U&& left, const vector<T,R>& right){
using res_t = decltype(std::declval<U>() * std::declval<T>());
vector<res_t,R> res(zero_initialize);
for(size_t i = 0; i < R; ++i){
res[i] = std::forward<U>(left) * right[i];
}
return res;
}
template<Scalar T, Scalar U, size_t R>
constexpr auto operator/(const vector<T,R>& left, U&& right){
using res_t = decltype(std::declval<T>() / std::declval<U>());
vector<res_t,R> res(zero_initialize);
for(size_t i = 0; i < R; ++i){
res[i] = left[i] / std::forward<U>(right);
}
return res;
}
template<Scalar T, Scalar U, size_t R>
constexpr auto operator+(const vector<T,R>& left, const vector<U,R>& right){
using res_t = decltype(std::declval<T>() + std::declval<U>());
vector<res_t,R> res(zero_initialize);
for(size_t i = 0; i < R; ++i){
res[i] = left[i] + right[i];
}
return res;
}
template<Scalar T, Scalar U, size_t R>
constexpr auto operator-(const vector<T,R>& left, const vector<U,R>& right){
using res_t = decltype(std::declval<T>() - std::declval<U>());
vector<res_t,R> res(zero_initialize);
for(size_t i = 0; i < R; ++i){
res[i] = left[i] - right[i];
}
return res;
}
template<Scalar T, Scalar U, size_t R>
constexpr auto operator-(const vector<T,R>& left){
using res_t = decltype(-std::declval<U>());
vector<res_t,R> res(zero_initialize);
for(size_t i = 0; i < R; ++i){
res[i] = -left[i];
}
return res;
}
template<Scalar T, Scalar U, size_t R>
constexpr decltype(auto) operator*=(vector<T,R>& left, U&& right){
for(size_t i = 0; i < R; ++i){
left[i] *= right;
}
return left;
}
template<Scalar T, Scalar U, size_t R>
constexpr decltype(auto) operator/=(vector<T,R>& left, U&& right){
for(size_t i = 0; i < R; ++i){
left[i] /= right;
}
return left;
}
template<Scalar T, Scalar U, size_t R>
constexpr decltype(auto) operator+=(vector<T,R>& left, const vector<U,R>& right){
for(size_t i = 0; i < R; ++i){
left[i] += right[i];
}
return left;
}
template<Scalar T, Scalar U, size_t R>
constexpr decltype(auto) operator-=(vector<T,R>& left, const vector<U,R>& right){
for(size_t i = 0; i < R; ++i){
left[i] -= right[i];
}
return left;
}
}
#endif

View File

@@ -19,7 +19,7 @@
#ifndef OUR_DICK_BOARD_HPP
#define OUR_DICK_BOARD_HPP
#include "math/vec.hpp"
#include <rml/vec.hpp>
#include "config.hpp"
#include <memory> //unique_ptr, shared_ptr
@@ -42,7 +42,7 @@ public:
};
private:
math::vec4f m_color_filter;
rml::vec4f m_color_filter;
public:
state value = state::BLANK;
@@ -50,8 +50,8 @@ public:
new_tile(void);
new_tile(state start_value);
void set_color(const math::vec4f& color);
const math::vec4f& get_color(void)const;
void set_color(const rml::vec4f& color);
const rml::vec4f& get_color(void)const;
};
class new_board : public wip::gfx::renderable, public egn::object
@@ -78,7 +78,7 @@ public:
new_tile::state check_winner(void)const;
bool is_full(void)const;
int click_collision_cheat(const math::vec3f&)const;
int click_collision_cheat(const rml::vec3f&)const;
void set_tile(int index, new_tile::state value);
new_tile& get_tile(int index);
const new_tile& get_tile(int index)const;

View File

@@ -22,7 +22,7 @@
#include "gfx/ogl/shader_program.hpp"
#include "gfx/ogl/vao.hpp"
#include "gfx/ogl/vbo.hpp"
#include "math/math.hpp"
#include <rml/math.hpp>
#include "basic_framebuffer.hpp"
#include "wip/renderer.hpp"
@@ -36,8 +36,8 @@ class main_renderer
{
private:
struct vertex{
math::vec2f pos;
math::vec2f tex_coord;
rml::vec2f pos;
rml::vec2f tex_coord;
};
static constexpr vertex s_vertices[] = {
{{-1.0f, 1.0f}, {0.0f, 1.0f}},
@@ -60,11 +60,11 @@ private:
public:
main_renderer(wip::gfx::renderer& res, int width, int height);
void set_vp_matrix(const math::mat4f& vp);
void set_vp_matrix(const rml::mat4f& vp);
void render(scene&);
gfx::ogl::texture& color_buffer(void);
void resize_viewport(int width, int height);
const math::vec4f& get_viewport(void)const;
const rml::vec4f& get_viewport(void)const;
};

View File

@@ -23,7 +23,7 @@
#include "main_renderer.hpp"
#include "egn/camera.hpp"
#include "math/vec.hpp"
#include <rml/vec.hpp>
#include "board.hpp"
class play_state : public egn::game_state_iface
@@ -46,7 +46,7 @@ public:
void render(void)override;
private:
math::vec3f project_screen_to_world_(const math::vec3f& screen);
rml::vec3f project_screen_to_world_(const rml::vec3f& screen);
};
#endif

View File

@@ -22,7 +22,7 @@
#include "gfx/ogl/vbo.hpp"
#include "gfx/ogl/vao.hpp"
#include "gfx/ogl/texture.hpp"
#include "math/math.hpp"
#include <rml/math.hpp>
#include "gfx/ogl/shader_program.hpp"
#include "wip/renderer.hpp"
@@ -37,8 +37,8 @@ class screen_renderer
{
private:
struct vertex{
math::vec2f pos;
math::vec2f tex_coord;
rml::vec2f pos;
rml::vec2f tex_coord;
};
static constexpr vertex s_vertices[] = {
{{-1.0f, 1.0f}, {0.0f, 1.0f}},

View File

@@ -19,7 +19,7 @@
#ifndef OUR_DICK_GRAPHICS_WIP_OGL_MATERIAL_HPP
#define OUR_DICK_GRAPHICS_WIP_OGL_MATERIAL_HPP
#include "math/vec.hpp"
#include <rml/vec.hpp>
#include "gfx/ogl/shader_program.hpp"
#include "gfx/ogl/texture.hpp"
@@ -32,9 +32,9 @@ namespace wip::gfx::ogl{
public:
std::shared_ptr<::gfx::ogl::shader_program> shader;
std::shared_ptr<::gfx::ogl::texture> diffuse_texture;
math::vec4f diffuse;
math::vec4f specular;
math::vec4f ambient;
rml::vec4f diffuse;
rml::vec4f specular;
rml::vec4f ambient;
float shininess;
material(const std::shared_ptr<::gfx::ogl::shader_program>& sh);

View File

@@ -21,8 +21,8 @@
#include "gfx/resource_container.hpp"
#include "math/vec.hpp"
#include "math/mat.hpp"
#include <rml/vec.hpp>
#include <rml/mat.hpp>
#include "gfx/ogl/ubo.hpp"
#include "ogl_resource_manager.hpp"
@@ -37,8 +37,8 @@ namespace wip::gfx::ogl{
using container_type = resource_manager::container_type<T>;
protected:
::gfx::ogl::ubo<math::mat4f> m_camera_uniform;
::gfx::ogl::ubo<math::mat4f> m_model_uniform;
::gfx::ogl::ubo<rml::mat4f> m_camera_uniform;
::gfx::ogl::ubo<rml::mat4f> m_model_uniform;
public:
renderer(void) = default;
@@ -49,9 +49,9 @@ namespace wip::gfx::ogl{
renderer& operator=(const renderer&) = default;
renderer& operator=(renderer&&) = default;
void set_viewport(const math::vec4f& vp);
void set_model_matrix(const math::mat4f& mat);
void set_camera(const math::mat4f& view, const math::mat4f& proj);
void set_viewport(const rml::vec4f& vp);
void set_model_matrix(const rml::mat4f& mat);
void set_camera(const rml::mat4f& view, const rml::mat4f& proj);
void bind_default_surface(void);
void clear_current_surface(void);

View File

@@ -19,13 +19,13 @@
#ifndef OUR_DICK_GRAPHICS_WIP_VERTEX_HPP
#define OUR_DICK_GRAPHICS_WIP_VERTEX_HPP
#include "math/vec.hpp"
#include <rml/vec.hpp>
namespace wip::gfx{
struct vertex{
math::vec3f position;
math::vec2f tex_coords;
rml::vec3f position;
rml::vec2f tex_coords;
};
}

View File

@@ -26,7 +26,8 @@ DEPDIR::=$(OBJDIR)/dep
LIBDIRS::=lib
INCLUDE_DIRS::=include
CFLAGS::=-std=c18 -Wall -pedantic -Wextra
CXXFLAGS::=-std=c++20 -Wall -pedantic -Wextra -fno-rtti -fno-exceptions $(shell pkg-config --cflags freetype2)
CXXFLAGS::=-std=c++20 -Wall -pedantic -Wextra -fno-rtti -fno-exceptions
PKGS::=freetype2 librml librexy
DEBUG_CFLAGS::=
DEBUG_CXXFLAGS::=-DOUR_DICK_DEBUG=2
EXT::=cpp
@@ -147,8 +148,8 @@ endif
#add dependency tracking and include directories
INTERNAL_COMPILERFLAGS=-c $(foreach dir,$(INCLUDE_DIRS),-I"$(dir)") -MMD -MP -MF"$(DEPDIR)/$(notdir $(patsubst %.o,%.d,$@))"
INTERNAL_LINKFLAGS=$(foreach dir,$(LIBDIRS),-L"$(dir)")
INTERNAL_COMPILERFLAGS=-c $(foreach dir,$(INCLUDE_DIRS),-I"$(dir)") $(foreach pkg,$(PKGS),$(shell pkg-config --cflags "$(pkg)")) -MMD -MP -MF"$(DEPDIR)/$(notdir $(patsubst %.o,%.d,$@))"
INTERNAL_LINKFLAGS=$(foreach dir,$(LIBDIRS),-L"$(dir)") $(foreach pkg,$(PKGS),$(shell pkg-config --libs "$(pkg)"))
INTERNAL_SOURCES::=$(SOURCES) $(foreach source,$(SOURCE_DIRS),$(foreach ext,$(EXT),$(wildcard $(source)/*.$(ext))))
OBJECTS::=$(addprefix $(OBJDIR)/,$(subst \,.,$(subst /,.,$(addsuffix .o,$(INTERNAL_SOURCES)))))
ALL_COMPILEFLAGS=$(COMPILER_FLAGS) $(INTERNAL_COMPILERFLAGS)

View File

@@ -20,7 +20,7 @@
namespace egn{
aabb::aabb(const math::vec3<float>& p1, const math::vec3<float>& p2):
aabb::aabb(const rml::vec3<float>& p1, const rml::vec3<float>& p2):
point1(p1.x(), p1.y(), p1.z()),
point2(p2.x(), p2.y(), p2.z()){}
sphere::sphere(float r):

View File

@@ -18,30 +18,30 @@
#include "egn/camera.hpp"
#include "config.hpp"
#include "math/projection.hpp"
#include <rml/projection.hpp>
namespace egn{
camera_iface::camera_iface(const math::mat4f& proj, float n, float f):
camera_iface::camera_iface(const rml::mat4f& proj, float n, float f):
m_projection_matrix(proj),
m_near(n), m_far(f){}
void camera_iface::set_position(const math::vec3f& pos){
void camera_iface::set_position(const rml::vec3f& pos){
object::set_position(pos);
m_update_flag |= VIEW_UPDATE;
}
void camera_iface::set_orientation(const math::quat_f& orient){
void camera_iface::set_orientation(const rml::quat_f& orient){
object::set_orientation(orient);
m_update_flag |= VIEW_UPDATE;
}
const math::mat4f& camera_iface::get_projection_matrix(void)const{
const rml::mat4f& camera_iface::get_projection_matrix(void)const{
if(m_update_flag & PROJ_UPDATE){
recalc_projection_matrix();
m_update_flag ^= PROJ_UPDATE;
}
return m_projection_matrix;
}
const math::mat4f& camera_iface::get_view_matrix(void)const{
const rml::mat4f& camera_iface::get_view_matrix(void)const{
if(m_update_flag & VIEW_UPDATE){
recalc_view_matrix();
m_update_flag ^= VIEW_UPDATE;
@@ -74,7 +74,7 @@ namespace egn{
ortho_camera::ortho_camera(float w, float h, float n, float f):
camera_iface(math::ortho_projection(w, h, n, f), n, f),
camera_iface(rml::ortho_projection(w, h, n, f), n, f),
m_width(w),
m_height(h){}
@@ -100,7 +100,7 @@ namespace egn{
void ortho_camera::recalc_projection_matrix(void)const{
rexy::debug::verbose::print("Rebuilding orthographic projection matrix\n");
m_projection_matrix = math::ortho_projection(m_width, m_height, m_near, m_far);
m_projection_matrix = rml::ortho_projection(m_width, m_height, m_near, m_far);
}
flat_camera::flat_camera(float w, float h):

View File

@@ -37,7 +37,7 @@ namespace egn{
}
static math::vec3f lineseg_point_proj(const line_segment& l, const math::vec3f& r){
static rml::vec3f lineseg_point_proj(const line_segment& l, const rml::vec3f& r){
/*
C (the point)
.
@@ -59,8 +59,8 @@ namespace egn{
dist = |C - L(b)|
*/
math::vec3f ab = (l.point2 - l.point1);
math::vec3f ac = (r - l.point1);
rml::vec3f ab = (l.point2 - l.point1);
rml::vec3f ac = (r - l.point1);
//check if point is within the line segment
//don't need to divide b by (ab * ab) to check if it's less than 0
@@ -77,18 +77,18 @@ namespace egn{
b = b / ab2;
//calculate the point using the parametric equation for the line
math::vec3f pb = l.point1 + (ab * b);
rml::vec3f pb = l.point1 + (ab * b);
return pb;
}
static math::vec3f rectangle_point_coplanar_proj(const rectangle& l, const math::vec3f& r){
static rml::vec3f rectangle_point_coplanar_proj(const rectangle& l, const rml::vec3f& r){
//r MUST be coplanar with l
//r = a
//l.point1 = b
//l.point2 = c
//l.point3 = d
//l.point4 = e
math::vec3f cb = l.point2 - l.point1;
math::vec3f eb = l.point4 - l.point1;
rml::vec3f cb = l.point2 - l.point1;
rml::vec3f eb = l.point4 - l.point1;
//apply the cb vector to 2 points along the primary i axis of the plane defined by the rectangle
//compare that to the result of the application of the cb vector on the input point
@@ -108,7 +108,7 @@ namespace egn{
//contained within the rectangle. Otherwise, we must project the point onto the rectangle's border.
//If not in the rectangle, we can have 1 or 2 candidate edges to project onto. We want the closest one
//to the input point.
//math::vec3f cand1, cand2;
//rml::vec3f cand1, cand2;
/*
now we divide the plane into a voronoi diagram where each region is closest
@@ -201,28 +201,28 @@ namespace egn{
return false;
}
bool check_collision(const sphere& l, const sphere& r, float epsilon){
return math::fuzzy_eq(l.point1, r.point1, l.radius + r.radius + epsilon);
return rml::fuzzy_eq(l.point1, r.point1, l.radius + r.radius + epsilon);
}
bool check_collision(const sphere& l, const aabb& r, float epsilon){
return check_collision(r, l, epsilon);
}
bool check_collision(const sphere& l, const line_segment& r, float epsilon){
return math::fuzzy_eq(l.point1 - lineseg_point_proj(r, l.point1), math::vec3f(math::zero_initialize), l.radius + epsilon);
return rml::fuzzy_eq(l.point1 - lineseg_point_proj(r, l.point1), rml::vec3f(rml::zero_initialize), l.radius + epsilon);
}
bool check_collision(const sphere& l, const rectangle& r, float epsilon){
//see comments in check_collision(rectangle, point) for explanation
math::vec3f normal = math::cross(r.point2 - r.point1, r.point3 - r.point2);
rml::vec3f normal = rml::cross(r.point2 - r.point1, r.point3 - r.point2);
float n2 = normal * normal;
math::vec3f d = l.point1 - r.point1;
rml::vec3f d = l.point1 - r.point1;
math::vec3f projected_point = l.point1 - (((normal * d) / n2) * normal);
rml::vec3f projected_point = l.point1 - (((normal * d) / n2) * normal);
math::vec3f proj_dist = l.point1 - rectangle_point_coplanar_proj(r, projected_point);
rml::vec3f proj_dist = l.point1 - rectangle_point_coplanar_proj(r, projected_point);
return (proj_dist * proj_dist) <= ((l.radius + epsilon) * (l.radius + epsilon));
}
bool check_collision(const sphere& l, const point& r, float epsilon){
return math::fuzzy_eq(l.point1, r, l.radius + epsilon);
return rml::fuzzy_eq(l.point1, r, l.radius + epsilon);
}
bool check_collision(const line_segment& l, const line_segment& r, float epsilon){
//A lot more math in this one than I'd like to put in comments. Check these sites:
@@ -234,10 +234,10 @@ namespace egn{
//starting lines. Make sure these points are within the line segment and return true if the
//length of our newly found segment is within epsilon of 0
//Do note that floating point precision really starts taking a toll at this stage of complexity
math::vec3f v21 = l.point2 - l.point1; //u
math::vec3f v43 = r.point2 - r.point1; //v
math::vec3f v13 = l.point1 - r.point1; //w
math::vec3f zero = math::vec3f(math::zero_initialize);
rml::vec3f v21 = l.point2 - l.point1; //u
rml::vec3f v43 = r.point2 - r.point1; //v
rml::vec3f v13 = l.point1 - r.point1; //w
rml::vec3f zero = rml::vec3f(rml::zero_initialize);
if(v43 == zero && v21 == zero){
return check_collision(l.point1, r.point1);
@@ -298,10 +298,10 @@ namespace egn{
mua = (std::abs(mua_num) < epsilon ? 0 : mua_num / mua_den);
mub = (std::abs(mub_num) < epsilon ? 0 : mub_num / mub_den);
math::vec3f p1 = l.point1 + (mua * v21);
math::vec3f p2 = r.point1 + (mub * v43);
rml::vec3f p1 = l.point1 + (mua * v21);
rml::vec3f p2 = r.point1 + (mub * v43);
return math::fuzzy_eq(p2 - p1, zero, epsilon);
return rml::fuzzy_eq(p2 - p1, zero, epsilon);
}
bool check_collision(const line_segment& l, const sphere& r, float epsilon){
return check_collision(r, l, epsilon);
@@ -316,7 +316,7 @@ namespace egn{
return false;
}
bool check_collision(const line_segment& l, const point& r, float epsilon){
return math::fuzzy_eq(r - lineseg_point_proj(l, r), math::vec3f(math::zero_initialize), epsilon);
return rml::fuzzy_eq(r - lineseg_point_proj(l, r), rml::vec3f(rml::zero_initialize), epsilon);
}
bool check_collision(const rectangle& l, const rectangle& r, float epsilon){
(void)l;
@@ -335,21 +335,21 @@ namespace egn{
}
bool check_collision(const rectangle& l, const point& r, float epsilon){
//get a normal vector for the rectangle
math::vec3f normal = math::cross(l.point2 - l.point1, l.point3 - l.point2);
rml::vec3f normal = rml::cross(l.point2 - l.point1, l.point3 - l.point2);
float n2 = normal * normal;
math::vec3f d = r - l.point1;
rml::vec3f d = r - l.point1;
//Project the point onto the plane defined by the rectangle
math::vec3f projected_point = r - (((normal * d) / n2) * normal);
rml::vec3f projected_point = r - (((normal * d) / n2) * normal);
//find the nearest point on the rectangle to the newly created coplanar point and see if it's within
//epsilon of the original point
math::vec3f proj_dist = r - rectangle_point_coplanar_proj(l, projected_point);
rml::vec3f proj_dist = r - rectangle_point_coplanar_proj(l, projected_point);
return (proj_dist * proj_dist) <= (epsilon * epsilon); //avoid square root
}
bool check_collision(const point& l, const point& r, float epsilon){
return math::fuzzy_eq(l, r, epsilon);
return rml::fuzzy_eq(l, r, epsilon);
}
bool check_collision(const point& l, const aabb& r, float epsilon){
return check_collision(r, l, epsilon);

View File

@@ -17,7 +17,7 @@
*/
#include "egn/font.hpp"
#include "math/vec.hpp"
#include <rml/vec.hpp>
#include <cmath> //sqrt, round
#include <utility> //move
#include <memory>
@@ -47,7 +47,7 @@ namespace egn{
font_character& font_atlas::operator[](int character){
return m_atlas_data[character];
}
math::vec2<size_t> font_atlas::glyph_size(void)const{
rml::vec2<size_t> font_atlas::glyph_size(void)const{
return {m_requested_width, m_requested_height};
}
@@ -82,7 +82,7 @@ namespace egn{
}
font_character calculate_character(FT_Face face, size_t atlas_w, size_t atlas_h, size_t atlas_x, size_t atlas_y){
const math::vec2<int> dest_size = {face->glyph->metrics.width >> 6, face->glyph->metrics.height >> 6};
const rml::vec2<int> dest_size = {face->glyph->metrics.width >> 6, face->glyph->metrics.height >> 6};
const float ratio_w = 1.0f / atlas_w;
const float ratio_h = 1.0f / atlas_h;
const float left = ratio_w * atlas_x;
@@ -105,7 +105,7 @@ namespace egn{
src += pitch;
}
}
void font::generate_atlas_piece_impl_(gfx::ogl::texture& atlas, font_atlas::map_type& metadata, math::vec2<size_t>& target_pos, const atlas_meta& info, unsigned char* data_buffer, const std::pair<int,int>& range){
void font::generate_atlas_piece_impl_(gfx::ogl::texture& atlas, font_atlas::map_type& metadata, rml::vec2<size_t>& target_pos, const atlas_meta& info, unsigned char* data_buffer, const std::pair<int,int>& range){
const auto& [atlas_width, atlas_height, max_glyph_width, max_glyph_height] = info;
const auto format = (m_depth == 3) ? GL_RGB : GL_RED;
const int freetype_load_flags = FT_LOAD_RENDER | ((m_depth == 3) ? FT_LOAD_TARGET_LCD : 0);
@@ -117,7 +117,7 @@ namespace egn{
continue;
}
auto& bitmap = m_face->glyph->bitmap;
const math::vec2<size_t> out_size = {bitmap.width / m_depth, bitmap.rows};
const rml::vec2<size_t> out_size = {bitmap.width / m_depth, bitmap.rows};
if(target_pos.x() + out_size.x() > atlas_width){
target_pos.x() = 0;
target_pos.y() += max_glyph_height;

View File

@@ -91,7 +91,7 @@ namespace egn{
m_event_queue.emplace(input_event{input_event::type::RESIZE, glfwGetTime(), 0, 0, 0, (double)width, (double)height});
}
math::vec2<double> game::get_mouse_pos(void)const{
rml::vec2<double> game::get_mouse_pos(void)const{
return m_window.get_cursor_pos();
}

View File

@@ -21,57 +21,57 @@
namespace egn{
object::object(const math::vec3f& position):
object::object(const rml::vec3f& position):
m_position(position){}
object::object(const math::vec3f& position, const math::quat_f& orientation):
object::object(const rml::vec3f& position, const rml::quat_f& orientation):
m_position(position),
m_orientation(orientation){}
void object::translate(const math::vec3f& distance){
void object::translate(const rml::vec3f& distance){
set_position(m_position + distance);
}
void object::rotate(const math::quat_f& distance){
void object::rotate(const rml::quat_f& distance){
set_orientation(m_orientation * distance);
}
void object::scale(const math::vec3f& distance){
set_scale(math::vec3f{m_scale[0] * distance[0],
void object::scale(const rml::vec3f& distance){
set_scale(rml::vec3f{m_scale[0] * distance[0],
m_scale[1] * distance[1],
m_scale[2] * distance[2]});
}
void object::look_at(const math::vec3f& targ, const math::vec3f& up){
math::vec3f front((m_position - targ).normalize());
math::vec3f right(math::cross(up, front));
math::vec3f true_up(math::cross(front, right));
set_orientation(math::quat_f{math::mat3f{right[0], true_up[0], front[0],
void object::look_at(const rml::vec3f& targ, const rml::vec3f& up){
rml::vec3f front((m_position - targ).normalize());
rml::vec3f right(rml::cross(up, front));
rml::vec3f true_up(rml::cross(front, right));
set_orientation(rml::quat_f{rml::mat3f{right[0], true_up[0], front[0],
right[1], true_up[1], front[1],
right[2], true_up[2], front[2]}});
}
void object::set_position(const math::vec3f& pos){
void object::set_position(const rml::vec3f& pos){
m_update_flag |= (TRANSLATION_UPDATE | BOUNDING_VOLUME_UPDATE);
m_position = pos;
}
void object::set_orientation(const math::quat_f& orient){
void object::set_orientation(const rml::quat_f& orient){
m_update_flag |= (ROTATION_UPDATE | BOUNDING_VOLUME_UPDATE);
m_orientation = orient;
}
void object::set_scale(const math::vec3f& scale){
void object::set_scale(const rml::vec3f& scale){
m_update_flag |= (SCALE_UPDATE | BOUNDING_VOLUME_UPDATE);
m_scale = scale;
}
const math::mat4f& object::model_matrix(void)const{
const rml::mat4f& object::model_matrix(void)const{
if(m_update_flag & (SCALE_UPDATE | ROTATION_UPDATE | TRANSLATION_UPDATE)){
recalc_model_matrix();
m_update_flag &= (~(SCALE_UPDATE | ROTATION_UPDATE | TRANSLATION_UPDATE));
}
return m_model_matrix;
}
const math::vec3f& object::position(void)const{
const rml::vec3f& object::position(void)const{
return m_position;
}
const math::vec3f& object::scale(void)const{
const rml::vec3f& object::scale(void)const{
return m_scale;
}
const math::quat_f& object::orientation(void)const{
const rml::quat_f& object::orientation(void)const{
return m_orientation;
}

View File

@@ -56,7 +56,7 @@ namespace gfx::ogl{
return true;
}
void fbo::clear_color_buffer(const math::vec4f& color){
void fbo::clear_color_buffer(const rml::vec4f& color){
glClearNamedFramebufferfv(m_buffer, GL_COLOR, 0, &color[0]);
}
void fbo::clear_depth_buffer(GLfloat value){
@@ -80,12 +80,12 @@ namespace gfx::ogl{
}
void fbo::set_viewport(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2){
m_vp_coords = math::vec4f{x1, y1, x2, y2};
m_vp_coords = rml::vec4f{x1, y1, x2, y2};
}
void fbo::apply_viewport(void)const{
glViewport(m_vp_coords.x(), m_vp_coords.y(), m_vp_coords.z(), m_vp_coords.w());
}
const math::vec4f& fbo::get_viewport(void)const{
const rml::vec4f& fbo::get_viewport(void)const{
return m_vp_coords;
}

View File

@@ -131,18 +131,18 @@ namespace gfx::ogl{
glGetUniformfv(m_shader_id, m_location, &ret);
return ret;
}
math::vec2f uniform::get_vec2(void)const{
math::vec2f ret;
rml::vec2f uniform::get_vec2(void)const{
rml::vec2f ret;
glGetUniformfv(m_shader_id, m_location, ret);
return ret;
}
math::vec3f uniform::get_vec3(void)const{
math::vec3f ret;
rml::vec3f uniform::get_vec3(void)const{
rml::vec3f ret;
glGetUniformfv(m_shader_id, m_location, ret);
return ret;
}
math::vec4f uniform::get_vec4(void)const{
math::vec4f ret;
rml::vec4f uniform::get_vec4(void)const{
rml::vec4f ret;
glGetUniformfv(m_shader_id, m_location, ret);
return ret;
}
@@ -152,18 +152,18 @@ namespace gfx::ogl{
glGetUniformdv(m_shader_id, m_location, &ret);
return ret;
}
math::vec2d uniform::get_dvec2(void)const{
math::vec2d ret;
rml::vec2d uniform::get_dvec2(void)const{
rml::vec2d ret;
glGetUniformdv(m_shader_id, m_location, ret);
return ret;
}
math::vec3d uniform::get_dvec3(void)const{
math::vec3d ret;
rml::vec3d uniform::get_dvec3(void)const{
rml::vec3d ret;
glGetUniformdv(m_shader_id, m_location, ret);
return ret;
}
math::vec4d uniform::get_dvec4(void)const{
math::vec4d ret;
rml::vec4d uniform::get_dvec4(void)const{
rml::vec4d ret;
glGetUniformdv(m_shader_id, m_location, ret);
return ret;
}
@@ -173,18 +173,18 @@ namespace gfx::ogl{
glGetUniformiv(m_shader_id, m_location, &ret);
return ret;
}
math::vec2i uniform::get_ivec2(void)const{
math::vec2i ret;
rml::vec2i uniform::get_ivec2(void)const{
rml::vec2i ret;
glGetUniformiv(m_shader_id, m_location, ret);
return ret;
}
math::vec3i uniform::get_ivec3(void)const{
math::vec3i ret;
rml::vec3i uniform::get_ivec3(void)const{
rml::vec3i ret;
glGetUniformiv(m_shader_id, m_location, ret);
return ret;
}
math::vec4i uniform::get_ivec4(void)const{
math::vec4i ret;
rml::vec4i uniform::get_ivec4(void)const{
rml::vec4i ret;
glGetUniformiv(m_shader_id, m_location, ret);
return ret;
}
@@ -194,18 +194,18 @@ namespace gfx::ogl{
glGetUniformuiv(m_shader_id, m_location, &ret);
return ret;
}
math::vec2u uniform::get_uvec2(void)const{
math::vec2u ret;
rml::vec2u uniform::get_uvec2(void)const{
rml::vec2u ret;
glGetUniformuiv(m_shader_id, m_location, ret);
return ret;
}
math::vec3u uniform::get_uvec3(void)const{
math::vec3u ret;
rml::vec3u uniform::get_uvec3(void)const{
rml::vec3u ret;
glGetUniformuiv(m_shader_id, m_location, ret);
return ret;
}
math::vec4u uniform::get_uvec4(void)const{
math::vec4u ret;
rml::vec4u uniform::get_uvec4(void)const{
rml::vec4u ret;
glGetUniformuiv(m_shader_id, m_location, ret);
return ret;
}
@@ -215,110 +215,110 @@ namespace gfx::ogl{
glGetUniformiv(m_shader_id, m_location, &ret);
return static_cast<GLboolean>(ret);
}
math::vec2i uniform::get_bvec2(void)const{
math::vec2i ret;
rml::vec2i uniform::get_bvec2(void)const{
rml::vec2i ret;
glGetUniformiv(m_shader_id, m_location, ret);
return ret;
}
math::vec3i uniform::get_bvec3(void)const{
math::vec3i ret;
rml::vec3i uniform::get_bvec3(void)const{
rml::vec3i ret;
glGetUniformiv(m_shader_id, m_location, ret);
return ret;
}
math::vec4i uniform::get_bvec4(void)const{
math::vec4i ret;
rml::vec4i uniform::get_bvec4(void)const{
rml::vec4i ret;
glGetUniformiv(m_shader_id, m_location, ret);
return ret;
}
math::mat2f uniform::get_mat2(void)const{
math::mat2f ret;
rml::mat2f uniform::get_mat2(void)const{
rml::mat2f ret;
glGetUniformfv(m_shader_id, m_location, ret);
return ret;
}
math::mat3f uniform::get_mat3(void)const{
math::mat3f ret;
rml::mat3f uniform::get_mat3(void)const{
rml::mat3f ret;
glGetUniformfv(m_shader_id, m_location, ret);
return ret;
}
math::mat4f uniform::get_mat4(void)const{
math::mat4f ret;
rml::mat4f uniform::get_mat4(void)const{
rml::mat4f ret;
glGetUniformfv(m_shader_id, m_location, ret);
return ret;
}
math::matrix<GLfloat,2,3> uniform::get_mat2x3(void)const{
math::matrix<GLfloat,2,3> ret;
rml::matrix<float,2,3> uniform::get_mat2x3(void)const{
rml::matrix<GLfloat,2,3> ret;
glGetUniformfv(m_shader_id, m_location, ret);
return ret;
}
math::matrix<GLfloat,2,4> uniform::get_mat2x4(void)const{
math::matrix<GLfloat,2,4> ret;
rml::matrix<float,2,4> uniform::get_mat2x4(void)const{
rml::matrix<float,2,4> ret;
glGetUniformfv(m_shader_id, m_location, ret);
return ret;
}
math::matrix<GLfloat,3,2> uniform::get_mat3x2(void)const{
math::matrix<GLfloat,3,2> ret;
rml::matrix<float,3,2> uniform::get_mat3x2(void)const{
rml::matrix<float,3,2> ret;
glGetUniformfv(m_shader_id, m_location, ret);
return ret;
}
math::matrix<GLfloat,3,4> uniform::get_mat3x4(void)const{
math::matrix<GLfloat,3,4> ret;
rml::matrix<float,3,4> uniform::get_mat3x4(void)const{
rml::matrix<float,3,4> ret;
glGetUniformfv(m_shader_id, m_location, ret);
return ret;
}
math::matrix<GLfloat,4,2> uniform::get_mat4x2(void)const{
math::matrix<GLfloat,4,2> ret;
rml::matrix<float,4,2> uniform::get_mat4x2(void)const{
rml::matrix<float,4,2> ret;
glGetUniformfv(m_shader_id, m_location, ret);
return ret;
}
math::matrix<GLfloat,4,3> uniform::get_mat4x3(void)const{
math::matrix<GLfloat,4,3> ret;
rml::matrix<float,4,3> uniform::get_mat4x3(void)const{
rml::matrix<float,4,3> ret;
glGetUniformfv(m_shader_id, m_location, ret);
return ret;
}
math::mat2d uniform::get_dmat2(void)const{
math::mat2d ret;
rml::mat2d uniform::get_dmat2(void)const{
rml::mat2d ret;
glGetUniformdv(m_shader_id, m_location, ret);
return ret;
}
math::mat3d uniform::get_dmat3(void)const{
math::mat3d ret;
rml::mat3d uniform::get_dmat3(void)const{
rml::mat3d ret;
glGetUniformdv(m_shader_id, m_location, ret);
return ret;
}
math::mat4d uniform::get_dmat4(void)const{
math::mat4d ret;
rml::mat4d uniform::get_dmat4(void)const{
rml::mat4d ret;
glGetUniformdv(m_shader_id, m_location, ret);
return ret;
}
math::matrix<GLdouble,2,3> uniform::get_dmat2x3(void)const{
math::matrix<GLdouble,2,3> ret;
rml::matrix<double,2,3> uniform::get_dmat2x3(void)const{
rml::matrix<double,2,3> ret;
glGetUniformdv(m_shader_id, m_location, ret);
return ret;
}
math::matrix<GLdouble,2,4> uniform::get_dmat2x4(void)const{
math::matrix<GLdouble,2,4> ret;
rml::matrix<double,2,4> uniform::get_dmat2x4(void)const{
rml::matrix<double,2,4> ret;
glGetUniformdv(m_shader_id, m_location, ret);
return ret;
}
math::matrix<GLdouble,3,2> uniform::get_dmat3x2(void)const{
math::matrix<GLdouble,3,2> ret;
rml::matrix<double,3,2> uniform::get_dmat3x2(void)const{
rml::matrix<double,3,2> ret;
glGetUniformdv(m_shader_id, m_location, ret);
return ret;
}
math::matrix<GLdouble,3,4> uniform::get_dmat3x4(void)const{
math::matrix<GLdouble,3,4> ret;
rml::matrix<double,3,4> uniform::get_dmat3x4(void)const{
rml::matrix<double,3,4> ret;
glGetUniformdv(m_shader_id, m_location, ret);
return ret;
}
math::matrix<GLdouble,4,2> uniform::get_dmat4x2(void)const{
math::matrix<GLdouble,4,2> ret;
rml::matrix<double,4,2> uniform::get_dmat4x2(void)const{
rml::matrix<double,4,2> ret;
glGetUniformdv(m_shader_id, m_location, ret);
return ret;
}
math::matrix<GLdouble,4,3> uniform::get_dmat4x3(void)const{
math::matrix<GLdouble,4,3> ret;
rml::matrix<double,4,3> uniform::get_dmat4x3(void)const{
rml::matrix<double,4,3> ret;
glGetUniformdv(m_shader_id, m_location, ret);
return ret;
}
@@ -371,17 +371,17 @@ namespace gfx::ogl{
glProgramUniform1i(m_shader_id, m_location, tex_unit);
}
void uniform::set(const vec2f& v){
void uniform::set(const rml::vec2f& v){
glProgramUniform2fv(m_shader_id, m_location, 1, v);
}
void uniform::set(const vec3f& v){
void uniform::set(const rml::vec3f& v){
glProgramUniform3fv(m_shader_id, m_location, 1, v);
}
void uniform::set(const vec4f& v){
void uniform::set(const rml::vec4f& v){
glProgramUniform4fv(m_shader_id, m_location, 1, v);
}
void uniform::set(GLsizei count, const vec2f* v_arr){
void uniform::set(GLsizei count, const rml::vec2f* v_arr){
if constexpr(sizeof(v_arr[0]) == sizeof(GLfloat[2])){
glProgramUniform2fv(m_shader_id, m_location, count, reinterpret_cast<const GLfloat*>(v_arr));
}else{
@@ -394,7 +394,7 @@ namespace gfx::ogl{
glProgramUniform2fv(m_shader_id, m_location, count, arr.get());
}
}
void uniform::set(GLsizei count, const vec3f* v_arr){
void uniform::set(GLsizei count, const rml::vec3f* v_arr){
if constexpr(sizeof(v_arr[0]) == sizeof(GLfloat[3])){
glProgramUniform3fv(m_shader_id, m_location, count, reinterpret_cast<const GLfloat*>(v_arr));
}else{
@@ -408,7 +408,7 @@ namespace gfx::ogl{
glProgramUniform3fv(m_shader_id, m_location, count, arr.get());
}
}
void uniform::set(GLsizei count, const vec4f* v_arr){
void uniform::set(GLsizei count, const rml::vec4f* v_arr){
if constexpr(sizeof(v_arr[0]) == sizeof(GLfloat[4])){
glProgramUniform4fv(m_shader_id, m_location, count, reinterpret_cast<const GLfloat*>(v_arr));
}else{
@@ -437,17 +437,17 @@ namespace gfx::ogl{
glProgramUniform4fv(m_shader_id, m_location, count, v_arr);
}
void uniform::set(const vec2<GLint>& v){
void uniform::set(const rml::vec2i& v){
glProgramUniform2iv(m_shader_id, m_location, 1, v);
}
void uniform::set(const vec3<GLint>& v){
void uniform::set(const rml::vec3i& v){
glProgramUniform3iv(m_shader_id, m_location, 1, v);
}
void uniform::set(const vec4<GLint>& v){
void uniform::set(const rml::vec4i& v){
glProgramUniform4iv(m_shader_id, m_location, 1, v);
}
void uniform::set(GLsizei count, const vec2<GLint>* v_arr){
void uniform::set(GLsizei count, const rml::vec2i* v_arr){
if constexpr(sizeof(v_arr[0]) == sizeof(GLint[2])){
glProgramUniform2iv(m_shader_id, m_location, count, reinterpret_cast<const GLint*>(v_arr));
}else{
@@ -460,7 +460,7 @@ namespace gfx::ogl{
glProgramUniform2iv(m_shader_id, m_location, count, arr.get());
}
}
void uniform::set(GLsizei count, const vec3<GLint>* v_arr){
void uniform::set(GLsizei count, const rml::vec3i* v_arr){
if constexpr(sizeof(v_arr[0]) == sizeof(GLint[3])){
glProgramUniform3iv(m_shader_id, m_location, count, reinterpret_cast<const GLint*>(v_arr));
}else{
@@ -474,7 +474,7 @@ namespace gfx::ogl{
glProgramUniform3iv(m_shader_id, m_location, count, arr.get());
}
}
void uniform::set(GLsizei count, const vec4<GLint>* v_arr){
void uniform::set(GLsizei count, const rml::vec4i* v_arr){
if constexpr(sizeof(v_arr[0]) == sizeof(GLint[4])){
glProgramUniform4iv(m_shader_id, m_location, count, reinterpret_cast<const GLint*>(v_arr));
}else{
@@ -503,17 +503,17 @@ namespace gfx::ogl{
glProgramUniform4iv(m_shader_id, m_location, count, v_arr);
}
void uniform::set(const vec2<GLuint>& v){
void uniform::set(const rml::vec2u& v){
glProgramUniform2uiv(m_shader_id, m_location, 1, v);
}
void uniform::set(const vec3<GLuint>& v){
void uniform::set(const rml::vec3u& v){
glProgramUniform3uiv(m_shader_id, m_location, 1, v);
}
void uniform::set(const vec4<GLuint>& v){
void uniform::set(const rml::vec4u& v){
glProgramUniform4uiv(m_shader_id, m_location, 1, v);
}
void uniform::set(GLsizei count, const vec2<GLuint>* v_arr){
void uniform::set(GLsizei count, const rml::vec2u* v_arr){
if constexpr(sizeof(v_arr[0]) == sizeof(GLuint[2])){
glProgramUniform2uiv(m_shader_id, m_location, count, reinterpret_cast<const GLuint*>(v_arr));
}else{
@@ -526,7 +526,7 @@ namespace gfx::ogl{
glProgramUniform2uiv(m_shader_id, m_location, count, arr.get());
}
}
void uniform::set(GLsizei count, const vec3<GLuint>* v_arr){
void uniform::set(GLsizei count, const rml::vec3u* v_arr){
if constexpr(sizeof(v_arr[0]) == sizeof(GLuint[3])){
glProgramUniform3uiv(m_shader_id, m_location, count, reinterpret_cast<const GLuint*>(v_arr));
}else{
@@ -540,7 +540,7 @@ namespace gfx::ogl{
glProgramUniform3uiv(m_shader_id, m_location, count, arr.get());
}
}
void uniform::set(GLsizei count, const vec4<GLuint>* v_arr){
void uniform::set(GLsizei count, const rml::vec4u* v_arr){
if constexpr(sizeof(v_arr[0]) == sizeof(GLuint[4])){
glProgramUniform4uiv(m_shader_id, m_location, count, reinterpret_cast<const GLuint*>(v_arr));
}else{
@@ -569,17 +569,17 @@ namespace gfx::ogl{
glProgramUniform4uiv(m_shader_id, m_location, count, v_arr);
}
void uniform::set(const mat2f& m){
void uniform::set(const rml::mat2f& m){
glProgramUniformMatrix2fv(m_shader_id, m_location, 1, GL_FALSE, m);
}
void uniform::set(const mat3f& m){
void uniform::set(const rml::mat3f& m){
glProgramUniformMatrix3fv(m_shader_id, m_location, 1, GL_FALSE, m);
}
void uniform::set(const mat4f& m){
void uniform::set(const rml::mat4f& m){
glProgramUniformMatrix4fv(m_shader_id, m_location, 1, GL_FALSE, m);
}
void uniform::set(GLsizei count, const mat2f* m_arr){
void uniform::set(GLsizei count, const rml::mat2f* m_arr){
if constexpr(sizeof(m_arr[0]) == sizeof(GLfloat[4])){
glProgramUniformMatrix2fv(m_shader_id, m_location, count, GL_FALSE, reinterpret_cast<const GLfloat*>(m_arr));
}else{
@@ -594,7 +594,7 @@ namespace gfx::ogl{
glProgramUniformMatrix2fv(m_shader_id, m_location, count, GL_FALSE, arr.get());
}
}
void uniform::set(GLsizei count, const mat3f* m_arr){
void uniform::set(GLsizei count, const rml::mat3f* m_arr){
if constexpr(sizeof(m_arr[0]) == sizeof(GLfloat[9])){
glProgramUniformMatrix3fv(m_shader_id, m_location, count, GL_FALSE, reinterpret_cast<const GLfloat*>(m_arr));
}else{
@@ -614,7 +614,7 @@ namespace gfx::ogl{
glProgramUniformMatrix3fv(m_shader_id, m_location, count, GL_FALSE, arr.get());
}
}
void uniform::set(GLsizei count, const mat4f* m_arr){
void uniform::set(GLsizei count, const rml::mat4f* m_arr){
if constexpr(sizeof(m_arr[0]) == sizeof(GLfloat[16])){
glProgramUniformMatrix4fv(m_shader_id, m_location, count, GL_FALSE, reinterpret_cast<const GLfloat*>(m_arr));
}else{

View File

@@ -149,8 +149,8 @@ namespace gfx::ogl{
glGetTextureParameteriv(m_tex_id, GL_TEXTURE_MIN_FILTER, &filter);
return static_cast<minfilter>(filter);
}
math::vec4<GLfloat> texture_base::get_border_color(void)const{
math::vec4<GLfloat> color;
rml::vec4<GLfloat> texture_base::get_border_color(void)const{
rml::vec4<GLfloat> color;
glGetTextureParameterfv(m_tex_id, GL_TEXTURE_BORDER_COLOR, color);
return color;
}

View File

@@ -330,7 +330,7 @@ static void enable_opengl_debug_context(void){
m_title = nullptr;
}
void window::set_size(const math::vec2i& v){
void window::set_size(const rml::vec2i& v){
set_size(v.x(), v.y());
}
void window::set_size(int w, int h){
@@ -345,7 +345,7 @@ static void enable_opengl_debug_context(void){
void window::set_title(const char* t){
glfwSetWindowTitle(m_window, t);
}
void window::set_pos(const math::vec2i& v){
void window::set_pos(const rml::vec2i& v){
set_pos(v.x(), v.y());
}
void window::set_pos(int x, int y){
@@ -405,8 +405,8 @@ static void enable_opengl_debug_context(void){
}
math::vec2i window::get_size(void)const{
math::vec2i retval;
rml::vec2i window::get_size(void)const{
rml::vec2i retval;
glfwGetWindowSize(m_window, &retval.x(), &retval.y());
return retval;
}
@@ -417,8 +417,8 @@ static void enable_opengl_debug_context(void){
return get_size().y();
}
math::vec2i window::get_pos(void)const{
math::vec2i retval;
rml::vec2i window::get_pos(void)const{
rml::vec2i retval;
glfwGetWindowPos(m_window, &retval.x(), &retval.y());
return retval;
}
@@ -428,8 +428,8 @@ static void enable_opengl_debug_context(void){
int window::get_posy(void)const{
return get_pos().y();
}
math::vec2i window::get_context_version(void)const{
return math::vec2i{get_context_vmaj(), get_context_vmin()};
rml::vec2i window::get_context_version(void)const{
return rml::vec2i{get_context_vmaj(), get_context_vmin()};
}
int window::get_context_vmaj(void)const{
return glfwGetWindowAttrib(m_window, GLFW_CONTEXT_VERSION_MAJOR);
@@ -441,8 +441,8 @@ static void enable_opengl_debug_context(void){
return m_swap_interval;
}
math::vec2d window::get_cursor_pos(void)const{
math::vec2d retval;
rml::vec2d window::get_cursor_pos(void)const{
rml::vec2d retval;
glfwGetCursorPos(m_window, &retval.x(), &retval.y());
return retval;
}

View File

@@ -27,7 +27,7 @@
#include "ttt/tic_tac_toe.hpp"
#include "egn/font.hpp"
#include "math/debug.hpp"
#include <rml/debug.hpp>
int main(){
srand(time(NULL));

View File

@@ -1,28 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "math/mat.hpp"
#include "math/fwd_declare.hpp"
namespace math{
template class matrix<float,2,2>;
template class matrix<float,3,3>;
template class matrix<float,4,4>;
}

View File

@@ -1,26 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "math/quat.hpp"
#include "math/fwd_declare.hpp"
namespace math{
template class quaternion<float>;
}

View File

@@ -1,28 +0,0 @@
/**
This file is a part of our_dick
Copyright (C) 2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "math/vec.hpp"
#include "math/fwd_declare.hpp"
namespace math{
template class vector<float,2>;
template class vector<float,3>;
template class vector<float,4>;
}

View File

@@ -23,10 +23,10 @@ new_tile::new_tile(state start_value):
value(start_value){}
void new_tile::set_color(const math::vec4f& color){
void new_tile::set_color(const rml::vec4f& color){
m_color_filter = color;
}
const math::vec4f& new_tile::get_color(void)const{
const rml::vec4f& new_tile::get_color(void)const{
return m_color_filter;
}
@@ -65,15 +65,15 @@ bool new_board::is_full(void)const{
}
return true;
}
int new_board::click_collision_cheat(const math::vec3f& unproj_3)const{
math::vec4f unproj_4 = {unproj_3[0], unproj_3[1], unproj_3[2], 1};
math::vec4f mod_coord = model_matrix().inverse() * unproj_4;
int new_board::click_collision_cheat(const rml::vec3f& unproj_3)const{
rml::vec4f unproj_4 = {unproj_3[0], unproj_3[1], unproj_3[2], 1};
rml::vec4f mod_coord = model_matrix().inverse() * unproj_4;
mod_coord /= mod_coord[3];
math::vec3f projected1 = {mod_coord[0], mod_coord[1], mod_coord[2]};
rml::vec3f projected1 = {mod_coord[0], mod_coord[1], mod_coord[2]};
for(size_t i = 0;i < 9;++i){
const new_tile& sq = m_tiles[i];
const math::vec3f& sq_pos = sq.position();
const rml::vec3f& sq_pos = sq.position();
if((projected1.x() > (sq_pos.x() - 1.0f) && projected1.x() < (sq_pos.x() + 1.0f)) &&
(projected1.y() > (sq_pos.y() - 1.0f) && projected1.y() < (sq_pos.y() + 1.0f)))
{

View File

@@ -42,12 +42,12 @@ main_renderer::main_renderer(wip::gfx::renderer& res, int width, int height):
rexy::debug::print_error("%s\n", m_square_shader->get_error().c_str());
}
m_square_shader->get_uniform("vp_mat").set(math::mat4f{});
m_square_shader->get_uniform("vp_mat").set(rml::mat4f{});
vert = res.shader_stages().emplace_value("screen_shader_vert", screen_shader::vertex_shader_text, gfx::ogl::shader_stage::type::VERTEX).first;
frag = res.shader_stages().emplace_value("screen_shader_frag", screen_shader::fragment_shader_text, gfx::ogl::shader_stage::type::FRAGMENT).first;
m_screen_shader = res.shader_programs().emplace_value("screen_shader", *vert, *frag).first;
m_screen_shader->get_uniform("vp_mat").set(math::mat4f{});
m_screen_shader->get_uniform("vp_mat").set(rml::mat4f{});
m_vao.bind_buffer(m_vbo, 0, 0, sizeof(vertex));
auto attrib = m_vao.get_attribute(0);
@@ -62,7 +62,7 @@ main_renderer::main_renderer(wip::gfx::renderer& res, int width, int height):
resize_viewport(width, height);
}
void main_renderer::set_vp_matrix(const math::mat4f& vp){
void main_renderer::set_vp_matrix(const rml::mat4f& vp){
m_square_shader->get_uniform("vp_mat").set(vp);
}
void main_renderer::render(scene&){
@@ -101,6 +101,6 @@ void main_renderer::resize_viewport(int width, int height){
data[4].tex_coord = {x2, y2};
data[5].tex_coord = {x1, y2};
}
const math::vec4f& main_renderer::get_viewport(void)const{
const rml::vec4f& main_renderer::get_viewport(void)const{
return m_fb.get_viewport();
}

View File

@@ -21,7 +21,7 @@
#include "ttt/pause_state.hpp"
#include "gfx/ogl/gl_include.hpp" //TODO: separate key definitions from GLFW
#include "egn/image.hpp" //TODO: move image to engine namespace
#include "math/math.hpp"
#include <rml/math.hpp>
#include "config.hpp"
#include "egn/game.hpp"
#include "ttt/board.hpp"
@@ -68,16 +68,16 @@ void play_state::enter(){
}
void play_state::leave(){}
math::vec3f play_state::project_screen_to_world_(const math::vec3f& screen){
const math::vec4f& viewport = m_main_renderer.get_viewport();
const math::vec3f vp_coords{screen.x() - viewport[0], viewport[3] - (screen.y() - viewport[1]), screen.z()};
const math::mat4f vp_mat = m_main_camera.get_projection_matrix() * m_main_camera.get_view_matrix();
return math::unproject(vp_mat, vp_coords, viewport);
rml::vec3f play_state::project_screen_to_world_(const rml::vec3f& screen){
const rml::vec4f& viewport = m_main_renderer.get_viewport();
const rml::vec3f vp_coords{screen.x() - viewport[0], viewport[3] - (screen.y() - viewport[1]), screen.z()};
const rml::mat4f vp_mat = m_main_camera.get_projection_matrix() * m_main_camera.get_view_matrix();
return rml::unproject(vp_mat, vp_coords, viewport);
}
math::vec4f tile_color(const new_tile& t, bool mouseclick){
static constexpr math::vec4f teal = {0, 1, 1, 0.1};
static constexpr math::vec4f green = {0, 1, 0, 0.1};
rml::vec4f tile_color(const new_tile& t, bool mouseclick){
static constexpr rml::vec4f teal = {0, 1, 1, 0.1};
static constexpr rml::vec4f green = {0, 1, 0, 0.1};
if(t.value == new_tile::state::BLANK && mouseclick){
return green;
}
@@ -105,10 +105,10 @@ void play_state::handle_input(const egn::input_event& ev){
m_main_renderer.resize_viewport(ev.x, ev.y);
renderer().set_viewport({0, 0, ev.x, ev.y});
}else if(ev.ev_type == egn::input_event::type::MOUSE_MOVE){
math::vec3f projected1 = project_screen_to_world_({ev.x, ev.y, 1.0f});
rml::vec3f projected1 = project_screen_to_world_({ev.x, ev.y, 1.0f});
//TODO actual 3D ray picking
//math::vec3f projected2 = project_screen_to_world_({ev.x, ev.y, -1.0f});
//rml::vec3f projected2 = project_screen_to_world_({ev.x, ev.y, -1.0f});
int new_index = m_board->click_collision_cheat(projected1);

View File

@@ -25,7 +25,7 @@
#include "egn/font.hpp"
#include "ttt/font_shader.hpp"
#include "math/debug.hpp"
#include <rml/debug.hpp>
screen_renderer::screen_renderer(wip::gfx::renderer& res, int width, int height, const std::shared_ptr<gfx::ogl::texture>& base_tex):
m_vbo(s_vertices, sizeof(s_vertices), gfx::ogl::buffer::usage::DYNAMIC_DRAW),

View File

@@ -21,13 +21,13 @@
namespace wip::gfx::ogl{
void renderer::set_viewport(const math::vec4f& vp){
void renderer::set_viewport(const rml::vec4f& vp){
glViewport(vp.x(), vp.y(), vp.z(), vp.w());
}
void renderer::set_model_matrix(const math::mat4f& mat){
void renderer::set_model_matrix(const rml::mat4f& mat){
m_model_uniform.set<0>(mat);
}
void renderer::set_camera(const math::mat4f& view, const math::mat4f& proj){
void renderer::set_camera(const rml::mat4f& view, const rml::mat4f& proj){
m_camera_uniform.set<0>(proj * view);
}
void renderer::bind_default_surface(void){

View File

@@ -23,6 +23,7 @@
#include "config.hpp"
namespace wip::gfx::ogl{
[[maybe_unused]]
static constexpr shader_stage::type map_type(shader_type in){
using in_type = shader_type;
using out_type = shader_stage::type;
@@ -39,6 +40,7 @@ namespace wip::gfx::ogl{
return out_type::VERTEX;
};
}
[[maybe_unused]]
static constexpr shader_type map_type(shader_stage::type in){
using in_type = shader_stage::type;
using out_type = shader_type;
@@ -55,6 +57,7 @@ namespace wip::gfx::ogl{
return out_type::VERTEX;
};
}
[[maybe_unused]]
static constexpr ::gfx::ogl::buffer::usage map_type(buffer_type in){
using in_type = buffer_type;
using out_type = ::gfx::ogl::buffer::usage;

View File

@@ -18,7 +18,7 @@
#include "wip/square.hpp"
#include "math/mat.hpp"
#include <rml/mat.hpp>
namespace wip{
@@ -31,7 +31,7 @@ namespace wip{
}
void square::render(gfx::renderer& r, gfx::draw_command&){
//TODO: all render code should be handled in the mesh; it is tied to the render api whereas instances shouldn't be
r.set_model_matrix(math::mat4f(math::id_initialize));
r.set_model_matrix(rml::mat4f(rml::id_initialize));
m_mesh->render(r);
}