diff --git a/include/engine/base_types.hpp b/include/engine/base_types.hpp
new file mode 100644
index 0000000..a15d7d0
--- /dev/null
+++ b/include/engine/base_types.hpp
@@ -0,0 +1,64 @@
+/**
+ 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 .
+*/
+
+#ifndef OUR_DICK_ENGINE_BASE_TYPES_HPP
+#define OUR_DICK_ENGINE_BASE_TYPES_HPP
+
+#include "math/vec.hpp"
+
+namespace egn{
+
+ class line
+ {
+ public:
+ math::vec3 point1;
+ math::vec3 point2;
+ };
+
+ class aabb
+ {
+ public:
+ math::vec3 point1 = {};
+ math::vec3 point2 = {};
+ public:
+ aabb() = default;
+ aabb(const math::vec3& p1, const math::vec3& p2);
+ aabb(const aabb&) = default;
+ aabb(aabb&&) = default;
+ ~aabb() = default;
+ aabb& operator=(const aabb&) = default;
+ aabb& operator=(aabb&&) = default;
+ };
+ class aabs
+ {
+ public:
+ math::vec3 point = {};
+ float radius = 0.0f;
+ public:
+ aabs() = default;
+ aabs(float r);
+ aabs(const aabs&) = default;
+ aabs(aabs&&) = default;
+ ~aabs() = default;
+ aabs& operator=(const aabs&) = default;
+ aabs& operator=(aabs&&) = default;
+ };
+
+}
+
+#endif
diff --git a/include/engine/camera.hpp b/include/engine/camera.hpp
index 31301d3..a1f5812 100644
--- a/include/engine/camera.hpp
+++ b/include/engine/camera.hpp
@@ -25,7 +25,7 @@
namespace egn{
- class camera_iface : public object
+ class camera_iface : public object_base
{
protected:
enum update{
diff --git a/include/engine/object.hpp b/include/engine/object.hpp
index fb72cc1..4f91aa3 100644
--- a/include/engine/object.hpp
+++ b/include/engine/object.hpp
@@ -21,10 +21,11 @@
#include "graphics/gl_include.hpp" //GLfloat
#include "math/math.hpp"
+#include "base_types.hpp"
namespace egn{
- class object
+ class object_base
{
protected:
enum update{
@@ -32,6 +33,7 @@ namespace egn{
SCALE_UPDATE = 1,
TRANSLATION_UPDATE = 2,
ROTATION_UPDATE = 4,
+ BOUNDING_VOLUME_UPDATE = 8,
};
protected:
math::vec3 m_position; //track current positon in world space
@@ -41,15 +43,15 @@ namespace egn{
mutable int m_update_flag = NO_UPDATE; //whether or not to update the matrix upon access
public:
- object() = default;
- explicit object(const math::vec3& position);
- object(const math::vec3& position, const math::quaternion& orientation);
- object(const object&) = default;
- object(object&&) = default;
- virtual ~object() = default;
+ object_base() = default;
+ explicit object_base(const math::vec3& position);
+ object_base(const math::vec3& position, const math::quaternion& orientation);
+ object_base(const object_base&) = default;
+ object_base(object_base&&) = default;
+ virtual ~object_base() = default;
- object& operator=(const object&) = default;
- object& operator=(object&&) = default;
+ object_base& operator=(const object_base&) = default;
+ object_base& operator=(object_base&&) = default;
void translate(const math::vec3& distance);
void rotate(const math::quaternion& distance);
@@ -69,6 +71,67 @@ namespace egn{
void recalc_model_matrix()const;
};
+ class aabb_object : virtual public object_base
+ {
+ protected:
+ aabb m_model_bounding_box; //model coordinate bounding volume
+ mutable aabb m_world_bounding_box; //world coordinate bounding volume
+ public:
+ using object_base::object_base;
+ using object_base::operator=;
+ aabb_object(const math::vec3& position,
+ const math::vec3& aabb_p1, const math::vec3& aabb_p2);
+ aabb_object(const math::vec3& position, const math::quaternion& orientation,
+ const math::vec3& aabb_p1, const math::vec3& aabb_p2);
+ aabb_object() = default;
+ aabb_object(const aabb_object&) = default;
+ aabb_object(aabb_object&&) = default;
+ ~aabb_object() = default;
+ aabb_object& operator=(const aabb_object&) = default;
+ aabb_object& operator=(aabb_object&&) = default;
+
+ const aabb& get_model_bounding_box()const;
+ const aabb& get_bounding_box()const;
+ };
+ class aabs_object : virtual public object_base
+ {
+ protected:
+ aabs m_model_bounding_sphere; //model coordinate bounding volume
+ mutable aabs m_world_bounding_sphere; //world coordinate bounding volume
+ public:
+ using object_base::object_base;
+ using object_base::operator=;
+ aabs_object(const math::vec3& position, float aabs_r);
+ aabs_object(const math::vec3& position, const math::quaternion& orientation,
+ float aabs_r);
+ aabs_object() = default;
+ aabs_object(const aabs_object&) = default;
+ aabs_object(aabs_object&&) = default;
+ ~aabs_object() = default;
+ aabs_object& operator=(const aabs_object&) = default;
+ aabs_object& operator=(aabs_object&&) = default;
+
+ const aabs& get_model_bounding_sphere()const;
+ const aabs& get_bounding_sphere()const;
+ };
+
+ bool check_collision(const aabb_object& l, const aabb_object& r);
+ bool check_collision(const aabb_object& l, const aabs_object& r);
+ bool check_collision(const aabs_object& l, const aabb_object& r);
+ bool check_collision(const aabs_object& l, const aabs_object& r);
+ bool check_collision(const aabb_object& o, const math::vec3& point);
+ bool check_collision(const aabs_object& o, const math::vec3& point);
+ bool check_collision(const aabb_object& o, const line& l);
+ bool check_collision(const aabs_object& o, const line& l);
+ bool check_collision(const aabb& l, const aabb& r);
+ bool check_collision(const aabb& l, const aabs& r);
+ bool check_collision(const aabs& l, const aabb& r);
+ bool check_collision(const aabs& l, const aabs& r);
+ bool check_collision(const aabb& l, const math::vec3& point);
+ bool check_collision(const aabs& l, const math::vec3& point);
+ bool check_collision(const aabb& o, const line& l);
+ bool check_collision(const aabs& o, const line& l);
+
}
#endif
diff --git a/include/renderable.hpp b/include/renderable.hpp
index 2c73fba..7ec624c 100644
--- a/include/renderable.hpp
+++ b/include/renderable.hpp
@@ -19,17 +19,17 @@
#ifndef OUR_DICK_RENDERABLE_HPP
#define OUR_DICK_RENDERABLE_HPP
-#include "engine/object.hpp"
#include "graphics/shader_program.hpp"
+#include "engine/object.hpp"
-class renderable_iface : public egn::object
+class renderable_iface : virtual public egn::object_base
{
public:
- using egn::object::object;
- using egn::object::operator=;
virtual ~renderable_iface() = default;
virtual void render(gfx::shader_program&) = 0;
};
+class aabb_renderable : public renderable_iface, public egn::aabb_object{};
+class aabs_renderable : public renderable_iface, public egn::aabb_object{};
#endif
diff --git a/include/square.hpp b/include/square.hpp
index a45379b..4145f21 100644
--- a/include/square.hpp
+++ b/include/square.hpp
@@ -24,10 +24,11 @@
#include "graphics/material.hpp"
#include "graphics/shader_program.hpp"
#include "renderable.hpp"
+#include "engine/object.hpp"
gfx::unified_mesh square_mesh(const gfx::material& blank, const gfx::material& o, const gfx::material& x);
-class square : public renderable_iface
+class square : public aabb_renderable
{
public:
enum class value{
diff --git a/include/util/minmax.hpp b/include/util/minmax.hpp
index f05cf83..d01c316 100644
--- a/include/util/minmax.hpp
+++ b/include/util/minmax.hpp
@@ -37,20 +37,26 @@ namespace util{
}
};
- template
- static constexpr T max(const T& left, const T& right){
+ template
+ static constexpr const T& max(const T& left, const T& right, Args&&... args){
+ if constexpr(sizeof...(args) > 0){
+ return left > right ? max(left, std::forward(args)...) : max(right, std::forward(args)...);
+ }
return left > right ? left : right;
}
- template
- static constexpr T min(const T& left, const T& right){
+ template
+ static constexpr const T& min(const T& left, const T& right, Args&&... args){
+ if constexpr(sizeof...(args) > 0){
+ return left < right ? min(left, std::forward(args)...) : min(right, std::forward(args)...);
+ }
return left < right ? left : right;
}
template
- static constexpr T max(const T& left, const T& right, Compare cmp){
+ static constexpr T maxc(const T& left, const T& right, Compare cmp){
return cmp(left, right) ? left : right;
}
template
- static constexpr T min(const T& left, const T& right, Compare cmp){
+ static constexpr T minc(const T& left, const T& right, Compare cmp){
return cmp(left, right) ? left : right;
}
diff --git a/src/engine/base_types.cpp b/src/engine/base_types.cpp
new file mode 100644
index 0000000..9d6f954
--- /dev/null
+++ b/src/engine/base_types.cpp
@@ -0,0 +1,30 @@
+/**
+ 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 .
+*/
+
+#include "engine/base_types.hpp"
+
+namespace egn{
+
+ aabb::aabb(const math::vec3& p1, const math::vec3& p2):
+ point1(p1),
+ point2(p2){}
+
+
+ aabs::aabs(float r):
+ radius(r){}
+}
diff --git a/src/engine/camera.cpp b/src/engine/camera.cpp
index 599a8aa..c065a90 100644
--- a/src/engine/camera.cpp
+++ b/src/engine/camera.cpp
@@ -27,11 +27,11 @@ namespace egn{
m_near(n), m_far(f){}
void camera_iface::set_position(const math::vec3& pos){
- object::set_position(pos);
+ object_base::set_position(pos);
m_update_flag |= VIEW_UPDATE;
}
void camera_iface::set_orientation(const math::quaternion& orient){
- object::set_orientation(orient);
+ object_base::set_orientation(orient);
m_update_flag |= VIEW_UPDATE;
}
const math::mat4& camera_iface::get_projection_matrix()const{
diff --git a/src/engine/object.cpp b/src/engine/object.cpp
index 624a408..c8908c0 100644
--- a/src/engine/object.cpp
+++ b/src/engine/object.cpp
@@ -18,27 +18,28 @@
#include "engine/object.hpp"
#include "config.hpp"
+#include "util/minmax.hpp"
namespace egn{
- object::object(const math::vec3& position):
+ object_base::object_base(const math::vec3& position):
m_position(position){}
- object::object(const math::vec3& position, const math::quaternion& orientation):
+ object_base::object_base(const math::vec3& position, const math::quaternion& orientation):
m_position(position),
m_orientation(orientation){}
- void object::translate(const math::vec3& distance){
+ void object_base::translate(const math::vec3& distance){
set_position(m_position + distance);
}
- void object::rotate(const math::quaternion& distance){
+ void object_base::rotate(const math::quaternion& distance){
set_orientation(m_orientation * distance);
}
- void object::scale(const math::vec3& distance){
+ void object_base::scale(const math::vec3& distance){
set_scale(math::vec3{m_scale[0] * distance[0],
m_scale[1] * distance[1],
m_scale[2] * distance[2]});
}
- void object::look_at(const math::vec3& targ, const math::vec3& up){
+ void object_base::look_at(const math::vec3& targ, const math::vec3& up){
math::vec3 front((m_position - targ).normalize());
math::vec3 right(math::cross(up, front));
math::vec3 true_up(math::cross(front, right));
@@ -46,36 +47,36 @@ namespace egn{
right[1], true_up[1], front[1],
right[2], true_up[2], front[2]}});
}
- void object::set_position(const math::vec3& pos){
- m_update_flag |= TRANSLATION_UPDATE;
+ void object_base::set_position(const math::vec3& pos){
+ m_update_flag |= (TRANSLATION_UPDATE | BOUNDING_VOLUME_UPDATE);
m_position = pos;
}
- void object::set_orientation(const math::quaternion& orient){
- m_update_flag |= ROTATION_UPDATE;
+ void object_base::set_orientation(const math::quaternion& orient){
+ m_update_flag |= (ROTATION_UPDATE | BOUNDING_VOLUME_UPDATE);
m_orientation = orient;
}
- void object::set_scale(const math::vec3& scale){
- m_update_flag |= SCALE_UPDATE;
+ void object_base::set_scale(const math::vec3& scale){
+ m_update_flag |= (SCALE_UPDATE | BOUNDING_VOLUME_UPDATE);
m_scale = scale;
}
- const math::mat4& object::get_model_matrix()const{
+ const math::mat4& object_base::get_model_matrix()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::vec3& object::get_position()const{
+ const math::vec3& object_base::get_position()const{
return m_position;
}
- const math::vec3& object::get_scale()const{
+ const math::vec3& object_base::get_scale()const{
return m_scale;
}
- const math::quaternion& object::get_orientation()const{
+ const math::quaternion& object_base::get_orientation()const{
return m_orientation;
}
- void object::recalc_model_matrix()const{
+ void object_base::recalc_model_matrix()const{
debug_print_verbose("Rebuilding model matrix\n");
m_model_matrix = m_orientation.to_mat4();
m_model_matrix.get(3, 0) = m_position[0];
@@ -83,4 +84,53 @@ namespace egn{
m_model_matrix.get(3, 2) = m_position[2];
}
+ aabb_object::aabb_object(const math::vec3& position,
+ const math::vec3& aabb_p1, const math::vec3& aabb_p2):
+ object_base(position),
+ m_model_bounding_box(aabb_p1, aabb_p2),
+ m_world_bounding_box(m_model_bounding_box){}
+ aabb_object::aabb_object(const math::vec3& position, const math::quaternion& orientation,
+ const math::vec3& aabb_p1, const math::vec3& aabb_p2):
+ object_base(position, orientation),
+ m_model_bounding_box(aabb_p1, aabb_p2),
+ m_world_bounding_box(m_model_bounding_box){}
+ const aabb& aabb_object::get_model_bounding_box()const{
+ return m_model_bounding_box;
+ }
+ const aabb& aabb_object::get_bounding_box()const{
+ if(m_update_flag){
+ recalc_model_matrix();
+ m_world_bounding_box.point1 = m_model_matrix * math::vec4(m_model_bounding_box.point1, 1.0f);
+ m_world_bounding_box.point2 = m_model_matrix * math::vec4(m_model_bounding_box.point2, 1.0f);
+ m_update_flag &= ~BOUNDING_VOLUME_UPDATE;
+ }
+ return m_world_bounding_box;
+ }
+
+ aabs_object::aabs_object(const math::vec3& position, float aabs_r):
+ object_base(position),
+ m_model_bounding_sphere(aabs_r),
+ m_world_bounding_sphere(m_model_bounding_sphere){}
+ aabs_object::aabs_object(const math::vec3& position, const math::quaternion& orientation,
+ float aabs_r):
+ object_base(position, orientation),
+ m_model_bounding_sphere(aabs_r),
+ m_world_bounding_sphere(m_model_bounding_sphere){}
+ const aabs& aabs_object::get_model_bounding_sphere()const{
+ return m_model_bounding_sphere;
+ }
+ const aabs& aabs_object::get_bounding_sphere()const{
+ if(m_update_flag){
+ math::mat4 t_mat{1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ m_position.x(), m_position.y(), m_position.z(), 1};
+ m_world_bounding_sphere.point = t_mat * math::vec4(m_model_bounding_sphere.point, 1.0f);
+ m_world_bounding_sphere.radius *= util::max(m_scale.x(), m_scale.y(), m_scale.z());
+ m_update_flag &= ~BOUNDING_VOLUME_UPDATE;
+ }
+ return m_world_bounding_sphere;
+ }
+
+
}