summaryrefslogtreecommitdiff
path: root/src/candy_gear/vector_4d.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/candy_gear/vector_4d.cpp')
-rw-r--r--src/candy_gear/vector_4d.cpp479
1 files changed, 479 insertions, 0 deletions
diff --git a/src/candy_gear/vector_4d.cpp b/src/candy_gear/vector_4d.cpp
new file mode 100644
index 0000000..b44b612
--- /dev/null
+++ b/src/candy_gear/vector_4d.cpp
@@ -0,0 +1,479 @@
+/*
+ * Copyright 2022-2024 Frederico de Oliveira Linhares
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "vector_4d.hpp"
+
+#include <memory>
+
+#include <glm/vec4.hpp>
+#include <mruby/array.h>
+
+#include "vector_3d.hpp"
+#include "view_2d.hpp"
+
+namespace
+{
+
+constexpr bool
+align_vertically(const float a_x, const float a_width,
+ const float b_x, const float b_width)
+{
+ return a_x <= b_x + b_width && a_x + a_width >= b_x;
+}
+
+constexpr bool
+align_horizontally(const float a_y, const float a_height,
+ const float b_y, const float b_height)
+{
+ return a_y <= b_y + b_height && a_y + a_height >= b_y;
+}
+
+}
+
+void
+cg_free_vector_4d(mrb_state *mrb, void* obj)
+{
+ auto ptr = static_cast<std::shared_ptr<glm::vec4>*>(obj);
+
+ ptr->~shared_ptr();
+ mrb_free(mrb, ptr);
+}
+
+const struct mrb_data_type cg_vector_4d_type = {
+ "CG_Vector4D", cg_free_vector_4d};
+
+static mrb_value
+cg_cVector4D_initialize(mrb_state *mrb, mrb_value self)
+{
+ mrb_float x = 0.0f;
+ mrb_float y = 0.0f;
+ mrb_float w = 0.0f;
+ mrb_float h = 0.0f;
+ std::shared_ptr<glm::vec4> *ptr;
+
+ mrb_get_args(mrb, "|ffff", &x, &y, &w, &h);
+ ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+ if(ptr) mrb_free(mrb, ptr);
+ ptr = (std::shared_ptr<glm::vec4>*)mrb_malloc(
+ mrb, sizeof(std::shared_ptr<glm::vec4>));
+
+ new(ptr)std::shared_ptr<glm::vec4>(std::make_shared<glm::vec4>(x, y, w, h));
+
+ mrb_data_init(self, ptr, &cg_vector_4d_type);
+ return self;
+}
+
+mrb_value
+cg_cVector4D_get_x(mrb_state *mrb, mrb_value self)
+{
+ std::shared_ptr<glm::vec4> *ptr =
+ (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ return mrb_float_value(mrb, (*ptr)->x);
+}
+
+mrb_value
+cg_cVector4D_get_y(mrb_state *mrb, mrb_value self)
+{
+ auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ return mrb_float_value(mrb, (*ptr)->y);
+}
+
+mrb_value
+cg_cVector4D_get_w(mrb_state *mrb, mrb_value self)
+{
+ auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ return mrb_float_value(mrb, (*ptr)->z);
+}
+
+mrb_value
+cg_cVector4D_get_h(mrb_state *mrb, mrb_value self)
+{
+ auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ return mrb_float_value(mrb, (*ptr)->w);
+}
+
+mrb_value
+cg_cVector4D_get_xy(mrb_state *mrb, mrb_value self)
+{
+ auto *ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ mrb_value array = mrb_ary_new_capa(mrb, 2);
+ mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->x));
+ mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->y));
+
+ return array;
+}
+
+mrb_value
+cg_cVector4D_get_xw(mrb_state *mrb, mrb_value self)
+{
+ auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ mrb_value array = mrb_ary_new_capa(mrb, 2);
+ mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->x));
+ mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->z));
+
+ return array;
+}
+
+mrb_value
+cg_cVector4D_get_xh(mrb_state *mrb, mrb_value self)
+{
+ auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ mrb_value array = mrb_ary_new_capa(mrb, 2);
+ mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->x));
+ mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->w));
+
+ return array;
+}
+
+mrb_value
+cg_cVector4D_get_yw(mrb_state *mrb, mrb_value self)
+{
+ auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ mrb_value array = mrb_ary_new_capa(mrb, 2);
+ mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->y));
+ mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->z));
+
+ return array;
+}
+
+mrb_value
+cg_cVector4D_get_yh(mrb_state *mrb, mrb_value self)
+{
+ auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ mrb_value array = mrb_ary_new_capa(mrb, 2);
+ mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->y));
+ mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->w));
+
+ return array;
+}
+
+mrb_value
+cg_cVector4D_get_wh(mrb_state *mrb, mrb_value self)
+{
+ auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ mrb_value array = mrb_ary_new_capa(mrb, 2);
+ mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->z));
+ mrb_ary_push(mrb, array, mrb_float_value(mrb, (*ptr)->w));
+
+ return array;
+}
+
+static mrb_value
+cg_cVector4D_set_x(mrb_state *mrb, mrb_value self)
+{
+ mrb_float x;
+ auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ mrb_get_args(mrb, "f", &x);
+ (*ptr)->x = x;
+
+ return self;
+}
+
+static mrb_value
+cg_cVector4D_set_y(mrb_state *mrb, mrb_value self)
+{
+ mrb_float y;
+ auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ mrb_get_args(mrb, "f", &y);
+ (*ptr)->y = y;
+
+ return self;
+}
+
+static mrb_value
+cg_cVector4D_set_w(mrb_state *mrb, mrb_value self)
+{
+ mrb_float w;
+ auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ mrb_get_args(mrb, "f", &w);
+ (*ptr)->z = w;
+
+ return self;
+}
+
+static mrb_value
+cg_cVector4D_set_h(mrb_state *mrb, mrb_value self)
+{
+ mrb_float h;
+ auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ mrb_get_args(mrb, "f", &h);
+ (*ptr)->w = h;
+
+ return self;
+}
+
+static mrb_value
+cg_cVector4D_set_xy(mrb_state *mrb, mrb_value self)
+{
+ mrb_float x, y;
+ auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ mrb_get_args(mrb, "ff", &x, &y);
+ (*ptr)->x = x;
+ (*ptr)->y = y;
+
+ return self;
+}
+
+static mrb_value
+cg_cVector4D_set_xw(mrb_state *mrb, mrb_value self)
+{
+ mrb_float x, w;
+ auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ mrb_get_args(mrb, "ff", &x, &w);
+ (*ptr)->x = x;
+ (*ptr)->z = w;
+
+ return self;
+}
+
+static mrb_value
+cg_cVector4D_set_xh(mrb_state *mrb, mrb_value self)
+{
+ mrb_float x, h;
+ auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ mrb_get_args(mrb, "ff", &x, &h);
+ (*ptr)->x = x;
+ (*ptr)->w = h;
+
+ return self;
+}
+
+static mrb_value
+cg_cVector4D_set_yw(mrb_state *mrb, mrb_value self)
+{
+ mrb_float y, w;
+ auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ mrb_get_args(mrb, "ff", &y, &w);
+ (*ptr)->y = y;
+ (*ptr)->z = w;
+
+ return self;
+}
+
+static mrb_value
+cg_cVector4D_set_yh(mrb_state *mrb, mrb_value self)
+{
+ mrb_float y, h;
+ auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ mrb_get_args(mrb, "ff", &y, &h);
+ (*ptr)->x = y;
+ (*ptr)->w = h;
+
+ return self;
+}
+
+static mrb_value
+cg_cVector4D_set_wh(mrb_state *mrb, mrb_value self)
+{
+ mrb_float w, h;
+ auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ mrb_get_args(mrb, "ff", &w, &h);
+ (*ptr)->z = w;
+ (*ptr)->w = h;
+
+ return self;
+}
+
+static mrb_value
+cg_cVector4D_align_vertically(mrb_state *mrb, mrb_value self)
+{
+ std::shared_ptr<glm::vec4> *ptr, *that;
+
+ mrb_get_args(mrb, "d", &that, &cg_vector_4d_type);
+ ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ return mrb_bool_value(
+ align_vertically((*ptr)->x, (*ptr)->z, (*that)->x, (*that)->z));
+}
+
+static mrb_value
+cg_cVector4D_align_horizontally(mrb_state *mrb, mrb_value self)
+{
+ std::shared_ptr<glm::vec4> *ptr, *that;
+
+ mrb_get_args(mrb, "d", &that, &cg_vector_4d_type);
+ ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ return mrb_bool_value(
+ align_horizontally((*ptr)->y, (*ptr)->w, (*that)->y, (*that)->w));
+}
+
+static mrb_value
+cg_cVector4D_collide(mrb_state *mrb, mrb_value self)
+{
+ std::shared_ptr<glm::vec4> *ptr, *that;
+
+ mrb_get_args(mrb, "d", &that, &cg_vector_4d_type);
+ ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ return mrb_bool_value(
+ align_vertically((*ptr)->x, (*ptr)->z, (*that)->x, (*that)->z) &&
+ align_horizontally((*ptr)->y, (*ptr)->w, (*that)->y, (*that)->w));
+}
+
+static mrb_value
+cg_cVector4D_draw_rectangle(mrb_state *mrb, mrb_value self)
+{
+ mrb_value view_value;
+ BluCat::GRA::View2D *view_2d;
+ std::shared_ptr<glm::vec3> *color;
+ auto ptr = (std::shared_ptr<glm::vec4>*)DATA_PTR(self);
+
+ mrb_get_args(mrb, "od", &view_value, &color, &cg_vector_3d_type);
+
+ view_2d = cg_cView_to_view_2d(mrb, view_value);
+
+ glm::vec4 position(
+ (*ptr)->x, (*ptr)->y, (*ptr)->x + (*ptr)->z, (*ptr)->y + (*ptr)->w);
+ BluCat::GRA::Rectangle rect{position, (**color)};
+ auto &rectangles = view_2d->rectangles_to_draw[
+ BluCat::INT::core.vk_swapchain->current_frame];
+ rectangles.push_back(rect);
+
+ return self;
+}
+
+void
+cg_vector_4d_init(mrb_state *mrb)
+{
+ struct RClass *cg_m, *cg_cVector4D;
+
+ cg_m = mrb_module_get(mrb, "CandyGear");
+ cg_cVector4D = mrb_define_class_under(
+ mrb, cg_m, "Vector4D", mrb->object_class);
+ MRB_SET_INSTANCE_TT(cg_cVector4D, MRB_TT_DATA);
+ mrb_define_method(
+ mrb, cg_cVector4D, "initialize", cg_cVector4D_initialize,
+ MRB_ARGS_NONE()|MRB_ARGS_OPT(4));
+
+ mrb_define_method(
+ mrb, cg_cVector4D, "x", cg_cVector4D_get_x, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cVector4D, "y", cg_cVector4D_get_y, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cVector4D, "w", cg_cVector4D_get_w, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cVector4D, "h", cg_cVector4D_get_h, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cVector4D, "r", cg_cVector4D_get_x, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cVector4D, "g", cg_cVector4D_get_y, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cVector4D, "b", cg_cVector4D_get_w, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cVector4D, "a", cg_cVector4D_get_h, MRB_ARGS_NONE());
+
+ mrb_define_method(
+ mrb, cg_cVector4D, "xy", cg_cVector4D_get_xy, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cVector4D, "xw", cg_cVector4D_get_xw, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cVector4D, "xh", cg_cVector4D_get_xh, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cVector4D, "yw", cg_cVector4D_get_yw, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cVector4D, "yh", cg_cVector4D_get_yh, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cVector4D, "wh", cg_cVector4D_get_wh, MRB_ARGS_NONE());
+
+ mrb_define_method(
+ mrb, cg_cVector4D, "rg", cg_cVector4D_get_xy, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cVector4D, "rb", cg_cVector4D_get_xw, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cVector4D, "ra", cg_cVector4D_get_xh, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cVector4D, "gb", cg_cVector4D_get_yw, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cVector4D, "ga", cg_cVector4D_get_yh, MRB_ARGS_NONE());
+ mrb_define_method(
+ mrb, cg_cVector4D, "ba", cg_cVector4D_get_wh, MRB_ARGS_NONE());
+
+ mrb_define_method(
+ mrb, cg_cVector4D, "x=", cg_cVector4D_set_x, MRB_ARGS_REQ(1));
+ mrb_define_method(
+ mrb, cg_cVector4D, "y=", cg_cVector4D_set_y, MRB_ARGS_REQ(1));
+ mrb_define_method(
+ mrb, cg_cVector4D, "w=", cg_cVector4D_set_w, MRB_ARGS_REQ(1));
+ mrb_define_method(
+ mrb, cg_cVector4D, "h=", cg_cVector4D_set_h, MRB_ARGS_REQ(1));
+ mrb_define_method(
+ mrb, cg_cVector4D, "r=", cg_cVector4D_set_x, MRB_ARGS_REQ(1));
+ mrb_define_method(
+ mrb, cg_cVector4D, "g=", cg_cVector4D_set_y, MRB_ARGS_REQ(1));
+ mrb_define_method(
+ mrb, cg_cVector4D, "b=", cg_cVector4D_set_w, MRB_ARGS_REQ(1));
+ mrb_define_method(
+ mrb, cg_cVector4D, "a=", cg_cVector4D_set_h, MRB_ARGS_REQ(1));
+
+ mrb_define_method(
+ mrb, cg_cVector4D, "set_xy", cg_cVector4D_set_xy, MRB_ARGS_REQ(2));
+ mrb_define_method(
+ mrb, cg_cVector4D, "set_xw", cg_cVector4D_set_xw, MRB_ARGS_REQ(2));
+ mrb_define_method(
+ mrb, cg_cVector4D, "set_xh", cg_cVector4D_set_xh, MRB_ARGS_REQ(2));
+ mrb_define_method(
+ mrb, cg_cVector4D, "set_yw", cg_cVector4D_set_yw, MRB_ARGS_REQ(2));
+ mrb_define_method(
+ mrb, cg_cVector4D, "set_yh", cg_cVector4D_set_yh, MRB_ARGS_REQ(2));
+ mrb_define_method(
+ mrb, cg_cVector4D, "set_wh", cg_cVector4D_set_wh, MRB_ARGS_REQ(2));
+
+ mrb_define_method(
+ mrb, cg_cVector4D, "set_rg", cg_cVector4D_set_xy, MRB_ARGS_REQ(2));
+ mrb_define_method(
+ mrb, cg_cVector4D, "set_rb", cg_cVector4D_set_xw, MRB_ARGS_REQ(2));
+ mrb_define_method(
+ mrb, cg_cVector4D, "set_ra", cg_cVector4D_set_xh, MRB_ARGS_REQ(2));
+ mrb_define_method(
+ mrb, cg_cVector4D, "set_gb", cg_cVector4D_set_yw, MRB_ARGS_REQ(2));
+ mrb_define_method(
+ mrb, cg_cVector4D, "set_ga", cg_cVector4D_set_yh, MRB_ARGS_REQ(2));
+ mrb_define_method(
+ mrb, cg_cVector4D, "set_ba", cg_cVector4D_set_wh, MRB_ARGS_REQ(2));
+
+ mrb_define_method(
+ mrb, cg_cVector4D, "align_vertically?", cg_cVector4D_align_vertically,
+ MRB_ARGS_REQ(1));
+ mrb_define_method(
+ mrb, cg_cVector4D, "align_horizontally?",
+ cg_cVector4D_align_horizontally, MRB_ARGS_REQ(1));
+ mrb_define_method(
+ mrb, cg_cVector4D, "collide?", cg_cVector4D_collide, MRB_ARGS_REQ(1));
+ mrb_define_method(
+ mrb, cg_cVector4D, "draw_rectangle", cg_cVector4D_draw_rectangle,
+ MRB_ARGS_REQ(2));
+}