/* * Copyright 2022 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 "vector3d.hpp" #include #include #include "rotation3d.hpp" void cg_free_vector3d(mrb_state *mrb, void* obj) { auto ptr = static_cast*>(obj); ptr->~shared_ptr(); mrb_free(mrb, ptr); } const struct mrb_data_type cg_vector3d_type = { "CG_Vector3D", cg_free_vector3d}; static mrb_value cg_cVector3D_initialize(mrb_state *mrb, mrb_value self) { mrb_float x = 0.0f; mrb_float y = 0.0f; mrb_float z = 0.0f; std::shared_ptr *ptr; mrb_get_args(mrb, "|fff", &x, &y, &z); ptr = (std::shared_ptr*)DATA_PTR(self); if(ptr) mrb_free(mrb, ptr); ptr = (std::shared_ptr*)mrb_malloc( mrb, sizeof(std::shared_ptr)); new(ptr)std::shared_ptr(std::make_shared(x, y, z)); mrb_data_init(self, ptr, &cg_vector3d_type); return self; } mrb_value cg_cVector3D_get_x(mrb_state *mrb, mrb_value self) { std::shared_ptr *ptr = (std::shared_ptr*)DATA_PTR(self); return mrb_float_value(mrb, (*ptr)->x); } mrb_value cg_cVector3D_get_y(mrb_state *mrb, mrb_value self) { std::shared_ptr *ptr = (std::shared_ptr*)DATA_PTR(self); return mrb_float_value(mrb, (*ptr)->y); } mrb_value cg_cVector3D_get_z(mrb_state *mrb, mrb_value self) { std::shared_ptr *ptr = (std::shared_ptr*)DATA_PTR(self); return mrb_float_value(mrb, (*ptr)->z); } static mrb_value cg_cVector3D_set_x(mrb_state *mrb, mrb_value self) { mrb_float x; std::shared_ptr *ptr = (std::shared_ptr*)DATA_PTR(self); mrb_get_args(mrb, "f", &x); (*ptr)->x = x; return self; } static mrb_value cg_cVector3D_set_y(mrb_state *mrb, mrb_value self) { mrb_float y; std::shared_ptr *ptr = (std::shared_ptr*)DATA_PTR(self); mrb_get_args(mrb, "f", &y); (*ptr)->y = y; return self; } static mrb_value cg_cVector3D_set_z(mrb_state *mrb, mrb_value self) { mrb_float z; std::shared_ptr *ptr = (std::shared_ptr*)DATA_PTR(self); mrb_get_args(mrb, "f", &z); (*ptr)->z = z; return self; } static mrb_value cg_cVector3D_translate(mrb_state *mrb, mrb_value self) { std::shared_ptr *ptr = (std::shared_ptr*)DATA_PTR(self); std::shared_ptr *direction, *rotation; mrb_get_args( mrb, "dd", &direction, &cg_vector3d_type, &rotation, &cg_rotation3d_type); glm::mat4 matrix{1.0f}; glm::vec4 vec{(**direction), 1.0f}; matrix = glm::rotate(matrix, (*rotation)->y, glm::vec3{0.0f, 1.0f, 0.0f}); matrix = glm::rotate(matrix, (*rotation)->x, glm::vec3{1.0f, 0.0f, 0.0f}); matrix = glm::rotate(matrix, (*rotation)->z, glm::vec3{0.0f, 0.0f, 1.0f}); vec = matrix * vec; (*ptr)->x += vec.x; (*ptr)->y += vec.y; (*ptr)->z += vec.z; return self; } void cg_vector3d_init(mrb_state *mrb) { struct RClass *cg_m, *cg_cVector3D; cg_m = mrb_module_get(mrb, "CandyGear"); cg_cVector3D = mrb_define_class_under( mrb, cg_m, "Vector3D", mrb->object_class); MRB_SET_INSTANCE_TT(cg_cVector3D, MRB_TT_DATA); mrb_define_method( mrb, cg_cVector3D, "initialize", cg_cVector3D_initialize, MRB_ARGS_NONE()|MRB_ARGS_OPT(3)); mrb_define_method( mrb, cg_cVector3D, "x", cg_cVector3D_get_x, MRB_ARGS_NONE()); mrb_define_method( mrb, cg_cVector3D, "y", cg_cVector3D_get_y, MRB_ARGS_NONE()); mrb_define_method( mrb, cg_cVector3D, "z", cg_cVector3D_get_z, MRB_ARGS_NONE()); mrb_define_method( mrb, cg_cVector3D, "x=", cg_cVector3D_set_x, MRB_ARGS_REQ(1)); mrb_define_method( mrb, cg_cVector3D, "y=", cg_cVector3D_set_y, MRB_ARGS_REQ(1)); mrb_define_method( mrb, cg_cVector3D, "z=", cg_cVector3D_set_z, MRB_ARGS_REQ(1)); mrb_define_method( mrb, cg_cVector3D, "translate", cg_cVector3D_translate, MRB_ARGS_REQ(2)); }