diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/AABB.cpp | 604 | ||||
-rw-r--r-- | src/core/Array.cpp | 226 | ||||
-rw-r--r-- | src/core/Basis.cpp | 710 | ||||
-rw-r--r-- | src/core/CameraMatrix.cpp | 655 | ||||
-rw-r--r-- | src/core/Color.cpp | 655 | ||||
-rw-r--r-- | src/core/Dictionary.cpp | 110 | ||||
-rw-r--r-- | src/core/GodotGlobal.cpp | 208 | ||||
-rw-r--r-- | src/core/NodePath.cpp | 114 | ||||
-rw-r--r-- | src/core/Plane.cpp | 203 | ||||
-rw-r--r-- | src/core/PoolArrays.cpp | 571 | ||||
-rw-r--r-- | src/core/Quat.cpp | 352 | ||||
-rw-r--r-- | src/core/Rect2.cpp | 313 | ||||
-rw-r--r-- | src/core/String.cpp | 522 | ||||
-rw-r--r-- | src/core/Transform.cpp | 305 | ||||
-rw-r--r-- | src/core/Transform2D.cpp | 332 | ||||
-rw-r--r-- | src/core/Variant.cpp | 381 | ||||
-rw-r--r-- | src/core/class_db.cpp | 312 | ||||
-rw-r--r-- | src/core/error_macros.cpp (renamed from src/core/Vector3.cpp) | 92 | ||||
-rw-r--r-- | src/core/memory.cpp (renamed from src/core/TagDB.cpp) | 49 | ||||
-rw-r--r-- | src/core/method_bind.cpp | 120 | ||||
-rw-r--r-- | src/core/object.cpp (renamed from src/core/RID.cpp) | 53 | ||||
-rw-r--r-- | src/gen/.gitignore | 2 | ||||
-rw-r--r-- | src/godot.cpp (renamed from src/core/Vector2.cpp) | 84 | ||||
-rw-r--r-- | src/variant/char_string.cpp | 267 | ||||
-rw-r--r-- | src/variant/variant.cpp | 749 |
25 files changed, 1521 insertions, 6468 deletions
diff --git a/src/core/AABB.cpp b/src/core/AABB.cpp deleted file mode 100644 index 81ac164..0000000 --- a/src/core/AABB.cpp +++ /dev/null @@ -1,604 +0,0 @@ -/*************************************************************************/ -/* AABB.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "AABB.hpp" -#include "Plane.hpp" -#include "Vector3.hpp" - -#include <algorithm> - -namespace godot { - -bool AABB::intersects(const AABB &p_aabb) const { - if (position.x >= (p_aabb.position.x + p_aabb.size.x)) - return false; - if ((position.x + size.x) <= p_aabb.position.x) - return false; - if (position.y >= (p_aabb.position.y + p_aabb.size.y)) - return false; - if ((position.y + size.y) <= p_aabb.position.y) - return false; - if (position.z >= (p_aabb.position.z + p_aabb.size.z)) - return false; - if ((position.z + size.z) <= p_aabb.position.z) - return false; - - return true; -} - -bool AABB::intersects_inclusive(const AABB &p_aabb) const { - if (position.x > (p_aabb.position.x + p_aabb.size.x)) - return false; - if ((position.x + size.x) < p_aabb.position.x) - return false; - if (position.y > (p_aabb.position.y + p_aabb.size.y)) - return false; - if ((position.y + size.y) < p_aabb.position.y) - return false; - if (position.z > (p_aabb.position.z + p_aabb.size.z)) - return false; - if ((position.z + size.z) < p_aabb.position.z) - return false; - - return true; -} - -bool AABB::encloses(const AABB &p_aabb) const { - Vector3 src_min = position; - Vector3 src_max = position + size; - Vector3 dst_min = p_aabb.position; - Vector3 dst_max = p_aabb.position + p_aabb.size; - - return ( - (src_min.x <= dst_min.x) && - (src_max.x > dst_max.x) && - (src_min.y <= dst_min.y) && - (src_max.y > dst_max.y) && - (src_min.z <= dst_min.z) && - (src_max.z > dst_max.z)); -} - -Vector3 AABB::get_support(const Vector3 &p_normal) const { - Vector3 half_extents = size * 0.5; - Vector3 ofs = position + half_extents; - - return Vector3( - (p_normal.x > 0) ? -half_extents.x : half_extents.x, - (p_normal.y > 0) ? -half_extents.y : half_extents.y, - (p_normal.z > 0) ? -half_extents.z : half_extents.z) + - ofs; -} - -Vector3 AABB::get_endpoint(int p_point) const { - switch (p_point) { - case 0: - return Vector3(position.x, position.y, position.z); - case 1: - return Vector3(position.x, position.y, position.z + size.z); - case 2: - return Vector3(position.x, position.y + size.y, position.z); - case 3: - return Vector3(position.x, position.y + size.y, position.z + size.z); - case 4: - return Vector3(position.x + size.x, position.y, position.z); - case 5: - return Vector3(position.x + size.x, position.y, position.z + size.z); - case 6: - return Vector3(position.x + size.x, position.y + size.y, position.z); - case 7: - return Vector3(position.x + size.x, position.y + size.y, position.z + size.z); - }; - - ERR_FAIL_V(Vector3()); -} - -bool AABB::intersects_convex_shape(const Plane *p_planes, int p_plane_count) const { - Vector3 half_extents = size * 0.5; - Vector3 ofs = position + half_extents; - - for (int i = 0; i < p_plane_count; i++) { - const Plane &p = p_planes[i]; - Vector3 point( - (p.normal.x > 0) ? -half_extents.x : half_extents.x, - (p.normal.y > 0) ? -half_extents.y : half_extents.y, - (p.normal.z > 0) ? -half_extents.z : half_extents.z); - point += ofs; - if (p.is_point_over(point)) - return false; - } - - return true; -} - -bool AABB::has_point(const Vector3 &p_point) const { - if (p_point.x < position.x) - return false; - if (p_point.y < position.y) - return false; - if (p_point.z < position.z) - return false; - if (p_point.x > position.x + size.x) - return false; - if (p_point.y > position.y + size.y) - return false; - if (p_point.z > position.z + size.z) - return false; - - return true; -} - -void AABB::expand_to(const Vector3 &p_vector) { - Vector3 begin = position; - Vector3 end = position + size; - - if (p_vector.x < begin.x) - begin.x = p_vector.x; - if (p_vector.y < begin.y) - begin.y = p_vector.y; - if (p_vector.z < begin.z) - begin.z = p_vector.z; - - if (p_vector.x > end.x) - end.x = p_vector.x; - if (p_vector.y > end.y) - end.y = p_vector.y; - if (p_vector.z > end.z) - end.z = p_vector.z; - - position = begin; - size = end - begin; -} - -void AABB::project_range_in_plane(const Plane &p_plane, real_t &r_min, real_t &r_max) const { - Vector3 half_extents(size.x * 0.5, size.y * 0.5, size.z * 0.5); - Vector3 center(position.x + half_extents.x, position.y + half_extents.y, position.z + half_extents.z); - - real_t length = p_plane.normal.abs().dot(half_extents); - real_t distance = p_plane.distance_to(center); - r_min = distance - length; - r_max = distance + length; -} - -real_t AABB::get_longest_axis_size() const { - real_t max_size = size.x; - - if (size.y > max_size) { - max_size = size.y; - } - - if (size.z > max_size) { - max_size = size.z; - } - - return max_size; -} - -real_t AABB::get_shortest_axis_size() const { - real_t max_size = size.x; - - if (size.y < max_size) { - max_size = size.y; - } - - if (size.z < max_size) { - max_size = size.z; - } - - return max_size; -} - -bool AABB::smits_intersect_ray(const Vector3 &from, const Vector3 &dir, real_t t0, real_t t1) const { - real_t divx = 1.0 / dir.x; - real_t divy = 1.0 / dir.y; - real_t divz = 1.0 / dir.z; - - Vector3 upbound = position + size; - real_t tmin, tmax, tymin, tymax, tzmin, tzmax; - if (dir.x >= 0) { - tmin = (position.x - from.x) * divx; - tmax = (upbound.x - from.x) * divx; - } else { - tmin = (upbound.x - from.x) * divx; - tmax = (position.x - from.x) * divx; - } - if (dir.y >= 0) { - tymin = (position.y - from.y) * divy; - tymax = (upbound.y - from.y) * divy; - } else { - tymin = (upbound.y - from.y) * divy; - tymax = (position.y - from.y) * divy; - } - if ((tmin > tymax) || (tymin > tmax)) - return false; - if (tymin > tmin) - tmin = tymin; - if (tymax < tmax) - tmax = tymax; - if (dir.z >= 0) { - tzmin = (position.z - from.z) * divz; - tzmax = (upbound.z - from.z) * divz; - } else { - tzmin = (upbound.z - from.z) * divz; - tzmax = (position.z - from.z) * divz; - } - if ((tmin > tzmax) || (tzmin > tmax)) - return false; - if (tzmin > tmin) - tmin = tzmin; - if (tzmax < tmax) - tmax = tzmax; - return ((tmin < t1) && (tmax > t0)); -} - -void AABB::grow_by(real_t p_amount) { - position.x -= p_amount; - position.y -= p_amount; - position.z -= p_amount; - size.x += 2.0 * p_amount; - size.y += 2.0 * p_amount; - size.z += 2.0 * p_amount; -} - -real_t AABB::get_area() const { - return size.x * size.y * size.z; -} - -bool AABB::operator==(const AABB &p_rval) const { - return ((position == p_rval.position) && (size == p_rval.size)); -} -bool AABB::operator!=(const AABB &p_rval) const { - return ((position != p_rval.position) || (size != p_rval.size)); -} - -void AABB::merge_with(const AABB &p_aabb) { - Vector3 beg_1, beg_2; - Vector3 end_1, end_2; - Vector3 min, max; - - beg_1 = position; - beg_2 = p_aabb.position; - end_1 = Vector3(size.x, size.y, size.z) + beg_1; - end_2 = Vector3(p_aabb.size.x, p_aabb.size.y, p_aabb.size.z) + beg_2; - - min.x = (beg_1.x < beg_2.x) ? beg_1.x : beg_2.x; - min.y = (beg_1.y < beg_2.y) ? beg_1.y : beg_2.y; - min.z = (beg_1.z < beg_2.z) ? beg_1.z : beg_2.z; - - max.x = (end_1.x > end_2.x) ? end_1.x : end_2.x; - max.y = (end_1.y > end_2.y) ? end_1.y : end_2.y; - max.z = (end_1.z > end_2.z) ? end_1.z : end_2.z; - - position = min; - size = max - min; -} - -AABB AABB::intersection(const AABB &p_aabb) const { - Vector3 src_min = position; - Vector3 src_max = position + size; - Vector3 dst_min = p_aabb.position; - Vector3 dst_max = p_aabb.position + p_aabb.size; - - Vector3 min, max; - - if (src_min.x > dst_max.x || src_max.x < dst_min.x) - return AABB(); - else { - min.x = (src_min.x > dst_min.x) ? src_min.x : dst_min.x; - max.x = (src_max.x < dst_max.x) ? src_max.x : dst_max.x; - } - - if (src_min.y > dst_max.y || src_max.y < dst_min.y) - return AABB(); - else { - min.y = (src_min.y > dst_min.y) ? src_min.y : dst_min.y; - max.y = (src_max.y < dst_max.y) ? src_max.y : dst_max.y; - } - - if (src_min.z > dst_max.z || src_max.z < dst_min.z) - return AABB(); - else { - min.z = (src_min.z > dst_min.z) ? src_min.z : dst_min.z; - max.z = (src_max.z < dst_max.z) ? src_max.z : dst_max.z; - } - - return AABB(min, max - min); -} - -bool AABB::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip, Vector3 *r_normal) const { - Vector3 c1, c2; - Vector3 end = position + size; - real_t near = -1e20; - real_t far = 1e20; - int axis = 0; - - for (int i = 0; i < 3; i++) { - if (p_dir[i] == 0) { - if ((p_from[i] < position[i]) || (p_from[i] > end[i])) { - return false; - } - } else { // ray not parallel to planes in this direction - c1[i] = (position[i] - p_from[i]) / p_dir[i]; - c2[i] = (end[i] - p_from[i]) / p_dir[i]; - - if (c1[i] > c2[i]) { - std::swap(c1, c2); - } - if (c1[i] > near) { - near = c1[i]; - axis = i; - } - if (c2[i] < far) { - far = c2[i]; - } - if ((near > far) || (far < 0)) { - return false; - } - } - } - - if (r_clip) - *r_clip = c1; - if (r_normal) { - *r_normal = Vector3(); - (*r_normal)[axis] = p_dir[axis] ? -1 : 1; - } - - return true; -} - -bool AABB::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_clip, Vector3 *r_normal) const { - real_t min = 0, max = 1; - int axis = 0; - real_t sign = 0; - - for (int i = 0; i < 3; i++) { - real_t seg_from = p_from[i]; - real_t seg_to = p_to[i]; - real_t box_begin = position[i]; - real_t box_end = box_begin + size[i]; - real_t cmin, cmax; - real_t csign; - - if (seg_from < seg_to) { - if (seg_from > box_end || seg_to < box_begin) - return false; - real_t length = seg_to - seg_from; - cmin = (seg_from < box_begin) ? ((box_begin - seg_from) / length) : 0; - cmax = (seg_to > box_end) ? ((box_end - seg_from) / length) : 1; - csign = -1.0; - - } else { - if (seg_to > box_end || seg_from < box_begin) - return false; - real_t length = seg_to - seg_from; - cmin = (seg_from > box_end) ? (box_end - seg_from) / length : 0; - cmax = (seg_to < box_begin) ? (box_begin - seg_from) / length : 1; - csign = 1.0; - } - - if (cmin > min) { - min = cmin; - axis = i; - sign = csign; - } - if (cmax < max) - max = cmax; - if (max < min) - return false; - } - - Vector3 rel = p_to - p_from; - - if (r_normal) { - Vector3 normal; - normal[axis] = sign; - *r_normal = normal; - } - - if (r_clip) - *r_clip = p_from + rel * min; - - return true; -} - -bool AABB::intersects_plane(const Plane &p_plane) const { - Vector3 points[8] = { - Vector3(position.x, position.y, position.z), - Vector3(position.x, position.y, position.z + size.z), - Vector3(position.x, position.y + size.y, position.z), - Vector3(position.x, position.y + size.y, position.z + size.z), - Vector3(position.x + size.x, position.y, position.z), - Vector3(position.x + size.x, position.y, position.z + size.z), - Vector3(position.x + size.x, position.y + size.y, position.z), - Vector3(position.x + size.x, position.y + size.y, position.z + size.z), - }; - - bool over = false; - bool under = false; - - for (int i = 0; i < 8; i++) { - if (p_plane.distance_to(points[i]) > 0) - over = true; - else - under = true; - } - - return under && over; -} - -Vector3 AABB::get_longest_axis() const { - Vector3 axis(1, 0, 0); - real_t max_size = size.x; - - if (size.y > max_size) { - axis = Vector3(0, 1, 0); - max_size = size.y; - } - - if (size.z > max_size) { - axis = Vector3(0, 0, 1); - max_size = size.z; - } - - return axis; -} -int AABB::get_longest_axis_index() const { - int axis = 0; - real_t max_size = size.x; - - if (size.y > max_size) { - axis = 1; - max_size = size.y; - } - - if (size.z > max_size) { - axis = 2; - max_size = size.z; - } - - return axis; -} - -Vector3 AABB::get_shortest_axis() const { - Vector3 axis(1, 0, 0); - real_t max_size = size.x; - - if (size.y < max_size) { - axis = Vector3(0, 1, 0); - max_size = size.y; - } - - if (size.z < max_size) { - axis = Vector3(0, 0, 1); - max_size = size.z; - } - - return axis; -} -int AABB::get_shortest_axis_index() const { - int axis = 0; - real_t max_size = size.x; - - if (size.y < max_size) { - axis = 1; - max_size = size.y; - } - - if (size.z < max_size) { - axis = 2; - max_size = size.z; - } - - return axis; -} - -AABB AABB::merge(const AABB &p_with) const { - AABB aabb = *this; - aabb.merge_with(p_with); - return aabb; -} -AABB AABB::expand(const Vector3 &p_vector) const { - AABB aabb = *this; - aabb.expand_to(p_vector); - return aabb; -} -AABB AABB::grow(real_t p_by) const { - AABB aabb = *this; - aabb.grow_by(p_by); - return aabb; -} - -void AABB::get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const { - ERR_FAIL_INDEX(p_edge, 12); - switch (p_edge) { - case 0: { - r_from = Vector3(position.x + size.x, position.y, position.z); - r_to = Vector3(position.x, position.y, position.z); - } break; - case 1: { - r_from = Vector3(position.x + size.x, position.y, position.z + size.z); - r_to = Vector3(position.x + size.x, position.y, position.z); - } break; - case 2: { - r_from = Vector3(position.x, position.y, position.z + size.z); - r_to = Vector3(position.x + size.x, position.y, position.z + size.z); - - } break; - case 3: { - r_from = Vector3(position.x, position.y, position.z); - r_to = Vector3(position.x, position.y, position.z + size.z); - - } break; - case 4: { - r_from = Vector3(position.x, position.y + size.y, position.z); - r_to = Vector3(position.x + size.x, position.y + size.y, position.z); - } break; - case 5: { - r_from = Vector3(position.x + size.x, position.y + size.y, position.z); - r_to = Vector3(position.x + size.x, position.y + size.y, position.z + size.z); - } break; - case 6: { - r_from = Vector3(position.x + size.x, position.y + size.y, position.z + size.z); - r_to = Vector3(position.x, position.y + size.y, position.z + size.z); - - } break; - case 7: { - r_from = Vector3(position.x, position.y + size.y, position.z + size.z); - r_to = Vector3(position.x, position.y + size.y, position.z); - - } break; - case 8: { - r_from = Vector3(position.x, position.y, position.z + size.z); - r_to = Vector3(position.x, position.y + size.y, position.z + size.z); - - } break; - case 9: { - r_from = Vector3(position.x, position.y, position.z); - r_to = Vector3(position.x, position.y + size.y, position.z); - - } break; - case 10: { - r_from = Vector3(position.x + size.x, position.y, position.z); - r_to = Vector3(position.x + size.x, position.y + size.y, position.z); - - } break; - case 11: { - r_from = Vector3(position.x + size.x, position.y, position.z + size.z); - r_to = Vector3(position.x + size.x, position.y + size.y, position.z + size.z); - - } break; - } -} - -AABB::operator String() const { - return String() + position + " - " + size; -} - -} // namespace godot diff --git a/src/core/Array.cpp b/src/core/Array.cpp deleted file mode 100644 index 9768387..0000000 --- a/src/core/Array.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/*************************************************************************/ -/* Array.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "Array.hpp" -#include "GodotGlobal.hpp" -#include "Variant.hpp" - -#include <cstdlib> - -namespace godot { - -class Object; - -Array::Array() { - godot::api->godot_array_new(&_godot_array); -} - -Array::Array(const Array &other) { - godot::api->godot_array_new_copy(&_godot_array, &other._godot_array); -} - -Array &Array::operator=(const Array &other) { - godot::api->godot_array_destroy(&_godot_array); - godot::api->godot_array_new_copy(&_godot_array, &other._godot_array); - return *this; -} - -Array::Array(const PoolByteArray &a) { - godot::api->godot_array_new_pool_byte_array(&_godot_array, (godot_pool_byte_array *)&a); -} - -Array::Array(const PoolIntArray &a) { - godot::api->godot_array_new_pool_int_array(&_godot_array, (godot_pool_int_array *)&a); -} - -Array::Array(const PoolRealArray &a) { - godot::api->godot_array_new_pool_real_array(&_godot_array, (godot_pool_real_array *)&a); -} - -Array::Array(const PoolStringArray &a) { - godot::api->godot_array_new_pool_string_array(&_godot_array, (godot_pool_string_array *)&a); -} - -Array::Array(const PoolVector2Array &a) { - godot::api->godot_array_new_pool_vector2_array(&_godot_array, (godot_pool_vector2_array *)&a); -} - -Array::Array(const PoolVector3Array &a) { - godot::api->godot_array_new_pool_vector3_array(&_godot_array, (godot_pool_vector3_array *)&a); -} - -Array::Array(const PoolColorArray &a) { - godot::api->godot_array_new_pool_color_array(&_godot_array, (godot_pool_color_array *)&a); -} - -Variant &Array::operator[](const int idx) { - godot_variant *v = godot::api->godot_array_operator_index(&_godot_array, idx); - // We assume it's ok to reinterpret because the value is a pointer whose data is already owned by the array, - // so can return a reference without constructing a Variant - return *reinterpret_cast<Variant *>(v); -} - -const Variant &Array::operator[](const int idx) const { - // Yes, I'm casting away the const... you can hate me now. - // since the result is - godot_variant *v = godot::api->godot_array_operator_index((godot_array *)&_godot_array, idx); - return *reinterpret_cast<const Variant *>(v); -} - -void Array::append(const Variant &v) { - godot::api->godot_array_append(&_godot_array, (godot_variant *)&v); -} - -void Array::clear() { - godot::api->godot_array_clear(&_godot_array); -} - -int Array::count(const Variant &v) { - return godot::api->godot_array_count(&_godot_array, (godot_variant *)&v); -} - -bool Array::empty() const { - return godot::api->godot_array_empty(&_godot_array); -} - -void Array::erase(const Variant &v) { - godot::api->godot_array_erase(&_godot_array, (godot_variant *)&v); -} - -Variant Array::front() const { - godot_variant v = godot::api->godot_array_front(&_godot_array); - return Variant(v); -} - -Variant Array::back() const { - godot_variant v = godot::api->godot_array_back(&_godot_array); - return Variant(v); -} - -int Array::find(const Variant &what, const int from) const { - return godot::api->godot_array_find(&_godot_array, (godot_variant *)&what, from); -} - -int Array::find_last(const Variant &what) const { - return godot::api->godot_array_find_last(&_godot_array, (godot_variant *)&what); -} - -bool Array::has(const Variant &what) const { - return godot::api->godot_array_has(&_godot_array, (godot_variant *)&what); -} - -uint32_t Array::hash() const { - return godot::api->godot_array_hash(&_godot_array); -} - -void Array::insert(const int pos, const Variant &value) { - godot::api->godot_array_insert(&_godot_array, pos, (godot_variant *)&value); -} - -void Array::invert() { - godot::api->godot_array_invert(&_godot_array); -} - -Variant Array::pop_back() { - godot_variant v = godot::api->godot_array_pop_back(&_godot_array); - return Variant(v); -} - -Variant Array::pop_front() { - godot_variant v = godot::api->godot_array_pop_front(&_godot_array); - return Variant(v); -} - -void Array::push_back(const Variant &v) { - godot::api->godot_array_push_back(&_godot_array, (godot_variant *)&v); -} - -void Array::push_front(const Variant &v) { - godot::api->godot_array_push_front(&_godot_array, (godot_variant *)&v); -} - -void Array::remove(const int idx) { - godot::api->godot_array_remove(&_godot_array, idx); -} - -int Array::size() const { - return godot::api->godot_array_size(&_godot_array); -} - -void Array::resize(const int size) { - godot::api->godot_array_resize(&_godot_array, size); -} - -int Array::rfind(const Variant &what, const int from) const { - return godot::api->godot_array_rfind(&_godot_array, (godot_variant *)&what, from); -} - -void Array::sort() { - godot::api->godot_array_sort(&_godot_array); -} - -void Array::sort_custom(Object *obj, const String &func) { - godot::api->godot_array_sort_custom(&_godot_array, (godot_object *)obj, (godot_string *)&func); -} - -int Array::bsearch(const Variant &value, const bool before) { - return godot::api->godot_array_bsearch(&_godot_array, (godot_variant *)&value, before); -} - -int Array::bsearch_custom(const Variant &value, const Object *obj, - const String &func, const bool before) { - return godot::api->godot_array_bsearch_custom(&_godot_array, (godot_variant *)&value, - (godot_object *)obj, (godot_string *)&func, before); -} - -Array Array::duplicate(const bool deep) const { - godot_array arr = godot::core_1_1_api->godot_array_duplicate(&_godot_array, deep); - return Array(arr); -} - -Variant Array::max() const { - godot_variant v = godot::core_1_1_api->godot_array_max(&_godot_array); - return Variant(v); -} - -Variant Array::min() const { - godot_variant v = godot::core_1_1_api->godot_array_min(&_godot_array); - return Variant(v); -} - -void Array::shuffle() { - godot::core_1_1_api->godot_array_shuffle(&_godot_array); -} - -Array::~Array() { - godot::api->godot_array_destroy(&_godot_array); -} - -} // namespace godot diff --git a/src/core/Basis.cpp b/src/core/Basis.cpp deleted file mode 100644 index da5f71f..0000000 --- a/src/core/Basis.cpp +++ /dev/null @@ -1,710 +0,0 @@ -/*************************************************************************/ -/* Basis.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "Basis.hpp" -#include "Defs.hpp" -#include "Quat.hpp" -#include "Vector3.hpp" - -#include <algorithm> - -namespace godot { - -const Basis Basis::IDENTITY = Basis(); -const Basis Basis::FLIP_X = Basis(-1, 0, 0, 0, 1, 0, 0, 0, 1); -const Basis Basis::FLIP_Y = Basis(1, 0, 0, 0, -1, 0, 0, 0, 1); -const Basis Basis::FLIP_Z = Basis(1, 0, 0, 0, 1, 0, 0, 0, -1); - -Basis::Basis(const Vector3 &row0, const Vector3 &row1, const Vector3 &row2) { - elements[0] = row0; - elements[1] = row1; - elements[2] = row2; -} - -Basis::Basis(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) { - set(xx, xy, xz, yx, yy, yz, zx, zy, zz); -} - -Basis::Basis() { - elements[0][0] = 1; - elements[0][1] = 0; - elements[0][2] = 0; - elements[1][0] = 0; - elements[1][1] = 1; - elements[1][2] = 0; - elements[2][0] = 0; - elements[2][1] = 0; - elements[2][2] = 1; -} - -#define cofac(row1, col1, row2, col2) \ - (elements[row1][col1] * elements[row2][col2] - elements[row1][col2] * elements[row2][col1]) - -void Basis::invert() { - real_t co[3] = { - cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1) - }; - real_t det = elements[0][0] * co[0] + - elements[0][1] * co[1] + - elements[0][2] * co[2]; - - ERR_FAIL_COND(det == 0); - - real_t s = 1.0 / det; - - set(co[0] * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s, - co[1] * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s, - co[2] * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s); -} -#undef cofac - -bool Basis::isequal_approx(const Basis &a, const Basis &b) const { - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - if ((::fabs(a.elements[i][j] - b.elements[i][j]) < CMP_EPSILON) == false) - return false; - } - } - - return true; -} - -bool Basis::is_orthogonal() const { - Basis id; - Basis m = (*this) * transposed(); - - return isequal_approx(id, m); -} - -bool Basis::is_rotation() const { - return ::fabs(determinant() - 1) < CMP_EPSILON && is_orthogonal(); -} - -void Basis::transpose() { - std::swap(elements[0][1], elements[1][0]); - std::swap(elements[0][2], elements[2][0]); - std::swap(elements[1][2], elements[2][1]); -} - -Basis Basis::inverse() const { - Basis b = *this; - b.invert(); - return b; -} - -Basis Basis::transposed() const { - Basis b = *this; - b.transpose(); - return b; -} - -real_t Basis::determinant() const { - return elements[0][0] * (elements[1][1] * elements[2][2] - elements[2][1] * elements[1][2]) - - elements[1][0] * (elements[0][1] * elements[2][2] - elements[2][1] * elements[0][2]) + - elements[2][0] * (elements[0][1] * elements[1][2] - elements[1][1] * elements[0][2]); -} - -Vector3 Basis::get_axis(int p_axis) const { - // get actual basis axis (elements is transposed for performance) - return Vector3(elements[0][p_axis], elements[1][p_axis], elements[2][p_axis]); -} -void Basis::set_axis(int p_axis, const Vector3 &p_value) { - // get actual basis axis (elements is transposed for performance) - elements[0][p_axis] = p_value.x; - elements[1][p_axis] = p_value.y; - elements[2][p_axis] = p_value.z; -} - -void Basis::rotate(const Vector3 &p_axis, real_t p_phi) { - *this = rotated(p_axis, p_phi); -} - -Basis Basis::rotated(const Vector3 &p_axis, real_t p_phi) const { - return Basis(p_axis, p_phi) * (*this); -} - -void Basis::scale(const Vector3 &p_scale) { - elements[0][0] *= p_scale.x; - elements[0][1] *= p_scale.x; - elements[0][2] *= p_scale.x; - elements[1][0] *= p_scale.y; - elements[1][1] *= p_scale.y; - elements[1][2] *= p_scale.y; - elements[2][0] *= p_scale.z; - elements[2][1] *= p_scale.z; - elements[2][2] *= p_scale.z; -} - -Basis Basis::scaled(const Vector3 &p_scale) const { - Basis b = *this; - b.scale(p_scale); - return b; -} - -Vector3 Basis::get_scale() const { - // We are assuming M = R.S, and performing a polar decomposition to extract R and S. - // FIXME: We eventually need a proper polar decomposition. - // As a cheap workaround until then, to ensure that R is a proper rotation matrix with determinant +1 - // (such that it can be represented by a Quat or Euler angles), we absorb the sign flip into the scaling matrix. - // As such, it works in conjuction with get_rotation(). - real_t det_sign = determinant() > 0 ? 1 : -1; - return det_sign * Vector3( - Vector3(elements[0][0], elements[1][0], elements[2][0]).length(), - Vector3(elements[0][1], elements[1][1], elements[2][1]).length(), - Vector3(elements[0][2], elements[1][2], elements[2][2]).length()); -} - -// TODO: implement this directly without using quaternions to make it more efficient -Basis Basis::slerp(Basis b, float t) const { - ERR_FAIL_COND_V(!is_rotation(), Basis()); - ERR_FAIL_COND_V(!b.is_rotation(), Basis()); - Quat from(*this); - Quat to(b); - return Basis(from.slerp(to, t)); -} - -// get_euler_xyz returns a vector containing the Euler angles in the format -// (a1,a2,a3), where a3 is the angle of the first rotation, and a1 is the last -// (following the convention they are commonly defined in the literature). -// -// The current implementation uses XYZ convention (Z is the first rotation), -// so euler.z is the angle of the (first) rotation around Z axis and so on, -// -// And thus, assuming the matrix is a rotation matrix, this function returns -// the angles in the decomposition R = X(a1).Y(a2).Z(a3) where Z(a) rotates -// around the z-axis by a and so on. -Vector3 Basis::get_euler_xyz() const { - // Euler angles in XYZ convention. - // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix - // - // rot = cy*cz -cy*sz sy - // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx - // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy - - Vector3 euler; - - ERR_FAIL_COND_V(is_rotation() == false, euler); - - real_t sy = elements[0][2]; - if (sy < 1.0) { - if (sy > -1.0) { - // is this a pure Y rotation? - if (elements[1][0] == 0.0 && elements[0][1] == 0.0 && elements[1][2] == 0 && elements[2][1] == 0 && elements[1][1] == 1) { - // return the simplest form (human friendlier in editor and scripts) - euler.x = 0; - euler.y = atan2(elements[0][2], elements[0][0]); - euler.z = 0; - } else { - euler.x = ::atan2(-elements[1][2], elements[2][2]); - euler.y = ::asin(sy); - euler.z = ::atan2(-elements[0][1], elements[0][0]); - } - } else { - euler.x = -::atan2(elements[0][1], elements[1][1]); - euler.y = -Math_PI / 2.0; - euler.z = 0.0; - } - } else { - euler.x = ::atan2(elements[0][1], elements[1][1]); - euler.y = Math_PI / 2.0; - euler.z = 0.0; - } - return euler; -} - -// set_euler_xyz expects a vector containing the Euler angles in the format -// (ax,ay,az), where ax is the angle of rotation around x axis, -// and similar for other axes. -// The current implementation uses XYZ convention (Z is the first rotation). -void Basis::set_euler_xyz(const Vector3 &p_euler) { - real_t c, s; - - c = ::cos(p_euler.x); - s = ::sin(p_euler.x); - Basis xmat(1.0, 0.0, 0.0, 0.0, c, -s, 0.0, s, c); - - c = ::cos(p_euler.y); - s = ::sin(p_euler.y); - Basis ymat(c, 0.0, s, 0.0, 1.0, 0.0, -s, 0.0, c); - - c = ::cos(p_euler.z); - s = ::sin(p_euler.z); - Basis zmat(c, -s, 0.0, s, c, 0.0, 0.0, 0.0, 1.0); - - //optimizer will optimize away all this anyway - *this = xmat * (ymat * zmat); -} - -// get_euler_yxz returns a vector containing the Euler angles in the YXZ convention, -// as in first-Z, then-X, last-Y. The angles for X, Y, and Z rotations are returned -// as the x, y, and z components of a Vector3 respectively. -Vector3 Basis::get_euler_yxz() const { - // Euler angles in YXZ convention. - // See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix - // - // rot = cy*cz+sy*sx*sz cz*sy*sx-cy*sz cx*sy - // cx*sz cx*cz -sx - // cy*sx*sz-cz*sy cy*cz*sx+sy*sz cy*cx - - Vector3 euler; - - ERR_FAIL_COND_V(is_rotation() == false, euler); - - real_t m12 = elements[1][2]; - - if (m12 < 1) { - if (m12 > -1) { - // is this a pure X rotation? - if (elements[1][0] == 0 && elements[0][1] == 0 && elements[0][2] == 0 && elements[2][0] == 0 && elements[0][0] == 1) { - // return the simplest form (human friendlier in editor and scripts) - euler.x = atan2(-m12, elements[1][1]); - euler.y = 0; - euler.z = 0; - } else { - euler.x = asin(-m12); - euler.y = atan2(elements[0][2], elements[2][2]); - euler.z = atan2(elements[1][0], elements[1][1]); - } - } else { // m12 == -1 - euler.x = Math_PI * 0.5; - euler.y = -atan2(-elements[0][1], elements[0][0]); - euler.z = 0; - } - } else { // m12 == 1 - euler.x = -Math_PI * 0.5; - euler.y = -atan2(-elements[0][1], elements[0][0]); - euler.z = 0; - } - - return euler; -} - -// set_euler_yxz expects a vector containing the Euler angles in the format -// (ax,ay,az), where ax is the angle of rotation around x axis, -// and similar for other axes. -// The current implementation uses YXZ convention (Z is the first rotation). -void Basis::set_euler_yxz(const Vector3 &p_euler) { - real_t c, s; - - c = ::cos(p_euler.x); - s = ::sin(p_euler.x); - Basis xmat(1.0, 0.0, 0.0, 0.0, c, -s, 0.0, s, c); - - c = ::cos(p_euler.y); - s = ::sin(p_euler.y); - Basis ymat(c, 0.0, s, 0.0, 1.0, 0.0, -s, 0.0, c); - - c = ::cos(p_euler.z); - s = ::sin(p_euler.z); - Basis zmat(c, -s, 0.0, s, c, 0.0, 0.0, 0.0, 1.0); - - //optimizer will optimize away all this anyway - *this = ymat * xmat * zmat; -} - -// transposed dot products -real_t Basis::tdotx(const Vector3 &v) const { - return elements[0][0] * v[0] + elements[1][0] * v[1] + elements[2][0] * v[2]; -} -real_t Basis::tdoty(const Vector3 &v) const { - return elements[0][1] * v[0] + elements[1][1] * v[1] + elements[2][1] * v[2]; -} -real_t Basis::tdotz(const Vector3 &v) const { - return elements[0][2] * v[0] + elements[1][2] * v[1] + elements[2][2] * v[2]; -} - -bool Basis::operator==(const Basis &p_matrix) const { - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - if (elements[i][j] != p_matrix.elements[i][j]) - return false; - } - } - - return true; -} - -bool Basis::operator!=(const Basis &p_matrix) const { - return (!(*this == p_matrix)); -} - -Vector3 Basis::xform(const Vector3 &p_vector) const { - return Vector3( - elements[0].dot(p_vector), - elements[1].dot(p_vector), - elements[2].dot(p_vector)); -} - -Vector3 Basis::xform_inv(const Vector3 &p_vector) const { - return Vector3( - (elements[0][0] * p_vector.x) + (elements[1][0] * p_vector.y) + (elements[2][0] * p_vector.z), - (elements[0][1] * p_vector.x) + (elements[1][1] * p_vector.y) + (elements[2][1] * p_vector.z), - (elements[0][2] * p_vector.x) + (elements[1][2] * p_vector.y) + (elements[2][2] * p_vector.z)); -} -void Basis::operator*=(const Basis &p_matrix) { - set( - p_matrix.tdotx(elements[0]), p_matrix.tdoty(elements[0]), p_matrix.tdotz(elements[0]), - p_matrix.tdotx(elements[1]), p_matrix.tdoty(elements[1]), p_matrix.tdotz(elements[1]), - p_matrix.tdotx(elements[2]), p_matrix.tdoty(elements[2]), p_matrix.tdotz(elements[2])); -} - -Basis Basis::operator*(const Basis &p_matrix) const { - return Basis( - p_matrix.tdotx(elements[0]), p_matrix.tdoty(elements[0]), p_matrix.tdotz(elements[0]), - p_matrix.tdotx(elements[1]), p_matrix.tdoty(elements[1]), p_matrix.tdotz(elements[1]), - p_matrix.tdotx(elements[2]), p_matrix.tdoty(elements[2]), p_matrix.tdotz(elements[2])); -} - -void Basis::operator+=(const Basis &p_matrix) { - elements[0] += p_matrix.elements[0]; - elements[1] += p_matrix.elements[1]; - elements[2] += p_matrix.elements[2]; -} - -Basis Basis::operator+(const Basis &p_matrix) const { - Basis ret(*this); - ret += p_matrix; - return ret; -} - -void Basis::operator-=(const Basis &p_matrix) { - elements[0] -= p_matrix.elements[0]; - elements[1] -= p_matrix.elements[1]; - elements[2] -= p_matrix.elements[2]; -} - -Basis Basis::operator-(const Basis &p_matrix) const { - Basis ret(*this); - ret -= p_matrix; - return ret; -} - -void Basis::operator*=(real_t p_val) { - elements[0] *= p_val; - elements[1] *= p_val; - elements[2] *= p_val; -} - -Basis Basis::operator*(real_t p_val) const { - Basis ret(*this); - ret *= p_val; - return ret; -} - -Basis::operator String() const { - String s; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - if (i != 0 || j != 0) - s += ", "; - - s += String::num(elements[i][j]); - } - } - return s; -} - -/* create / set */ - -void Basis::set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) { - elements[0][0] = xx; - elements[0][1] = xy; - elements[0][2] = xz; - elements[1][0] = yx; - elements[1][1] = yy; - elements[1][2] = yz; - elements[2][0] = zx; - elements[2][1] = zy; - elements[2][2] = zz; -} -Vector3 Basis::get_column(int i) const { - return Vector3(elements[0][i], elements[1][i], elements[2][i]); -} - -Vector3 Basis::get_row(int i) const { - return Vector3(elements[i][0], elements[i][1], elements[i][2]); -} -Vector3 Basis::get_main_diagonal() const { - return Vector3(elements[0][0], elements[1][1], elements[2][2]); -} - -void Basis::set_row(int i, const Vector3 &p_row) { - elements[i][0] = p_row.x; - elements[i][1] = p_row.y; - elements[i][2] = p_row.z; -} - -Basis Basis::transpose_xform(const Basis &m) const { - return Basis( - elements[0].x * m[0].x + elements[1].x * m[1].x + elements[2].x * m[2].x, - elements[0].x * m[0].y + elements[1].x * m[1].y + elements[2].x * m[2].y, - elements[0].x * m[0].z + elements[1].x * m[1].z + elements[2].x * m[2].z, - elements[0].y * m[0].x + elements[1].y * m[1].x + elements[2].y * m[2].x, - elements[0].y * m[0].y + elements[1].y * m[1].y + elements[2].y * m[2].y, - elements[0].y * m[0].z + elements[1].y * m[1].z + elements[2].y * m[2].z, - elements[0].z * m[0].x + elements[1].z * m[1].x + elements[2].z * m[2].x, - elements[0].z * m[0].y + elements[1].z * m[1].y + elements[2].z * m[2].y, - elements[0].z * m[0].z + elements[1].z * m[1].z + elements[2].z * m[2].z); -} - -void Basis::orthonormalize() { - ERR_FAIL_COND(determinant() == 0); - - // Gram-Schmidt Process - - Vector3 x = get_axis(0); - Vector3 y = get_axis(1); - Vector3 z = get_axis(2); - - x.normalize(); - y = (y - x * (x.dot(y))); - y.normalize(); - z = (z - x * (x.dot(z)) - y * (y.dot(z))); - z.normalize(); - - set_axis(0, x); - set_axis(1, y); - set_axis(2, z); -} - -Basis Basis::orthonormalized() const { - Basis b = *this; - b.orthonormalize(); - return b; -} - -bool Basis::is_symmetric() const { - if (::fabs(elements[0][1] - elements[1][0]) > CMP_EPSILON) - return false; - if (::fabs(elements[0][2] - elements[2][0]) > CMP_EPSILON) - return false; - if (::fabs(elements[1][2] - elements[2][1]) > CMP_EPSILON) - return false; - - return true; -} - -Basis Basis::diagonalize() { - // I love copy paste - - if (!is_symmetric()) - return Basis(); - - const int ite_max = 1024; - - real_t off_matrix_norm_2 = elements[0][1] * elements[0][1] + elements[0][2] * elements[0][2] + elements[1][2] * elements[1][2]; - - int ite = 0; - Basis acc_rot; - while (off_matrix_norm_2 > CMP_EPSILON2 && ite++ < ite_max) { - real_t el01_2 = elements[0][1] * elements[0][1]; - real_t el02_2 = elements[0][2] * elements[0][2]; - real_t el12_2 = elements[1][2] * elements[1][2]; - // Find the pivot element - int i, j; - if (el01_2 > el02_2) { - if (el12_2 > el01_2) { - i = 1; - j = 2; - } else { - i = 0; - j = 1; - } - } else { - if (el12_2 > el02_2) { - i = 1; - j = 2; - } else { - i = 0; - j = 2; - } - } - - // Compute the rotation angle - real_t angle; - if (::fabs(elements[j][j] - elements[i][i]) < CMP_EPSILON) { - angle = Math_PI / 4; - } else { - angle = 0.5 * ::atan(2 * elements[i][j] / (elements[j][j] - elements[i][i])); - } - - // Compute the rotation matrix - Basis rot; - rot.elements[i][i] = rot.elements[j][j] = ::cos(angle); - rot.elements[i][j] = -(rot.elements[j][i] = ::sin(angle)); - - // Update the off matrix norm - off_matrix_norm_2 -= elements[i][j] * elements[i][j]; - - // Apply the rotation - *this = rot * *this * rot.transposed(); - acc_rot = rot * acc_rot; - } - - return acc_rot; -} - -static const Basis _ortho_bases[24] = { - Basis(1, 0, 0, 0, 1, 0, 0, 0, 1), - Basis(0, -1, 0, 1, 0, 0, 0, 0, 1), - Basis(-1, 0, 0, 0, -1, 0, 0, 0, 1), - Basis(0, 1, 0, -1, 0, 0, 0, 0, 1), - Basis(1, 0, 0, 0, 0, -1, 0, 1, 0), - Basis(0, 0, 1, 1, 0, 0, 0, 1, 0), - Basis(-1, 0, 0, 0, 0, 1, 0, 1, 0), - Basis(0, 0, -1, -1, 0, 0, 0, 1, 0), - Basis(1, 0, 0, 0, -1, 0, 0, 0, -1), - Basis(0, 1, 0, 1, 0, 0, 0, 0, -1), - Basis(-1, 0, 0, 0, 1, 0, 0, 0, -1), - Basis(0, -1, 0, -1, 0, 0, 0, 0, -1), - Basis(1, 0, 0, 0, 0, 1, 0, -1, 0), - Basis(0, 0, -1, 1, 0, 0, 0, -1, 0), - Basis(-1, 0, 0, 0, 0, -1, 0, -1, 0), - Basis(0, 0, 1, -1, 0, 0, 0, -1, 0), - Basis(0, 0, 1, 0, 1, 0, -1, 0, 0), - Basis(0, -1, 0, 0, 0, 1, -1, 0, 0), - Basis(0, 0, -1, 0, -1, 0, -1, 0, 0), - Basis(0, 1, 0, 0, 0, -1, -1, 0, 0), - Basis(0, 0, 1, 0, -1, 0, 1, 0, 0), - Basis(0, 1, 0, 0, 0, 1, 1, 0, 0), - Basis(0, 0, -1, 0, 1, 0, 1, 0, 0), - Basis(0, -1, 0, 0, 0, -1, 1, 0, 0) -}; - -int Basis::get_orthogonal_index() const { - //could be sped up if i come up with a way - Basis orth = *this; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - real_t v = orth[i][j]; - if (v > 0.5) - v = 1.0; - else if (v < -0.5) - v = -1.0; - else - v = 0; - - orth[i][j] = v; - } - } - - for (int i = 0; i < 24; i++) { - if (_ortho_bases[i] == orth) - return i; - } - - return 0; -} - -void Basis::set_orthogonal_index(int p_index) { - //there only exist 24 orthogonal bases in r3 - ERR_FAIL_COND(p_index >= 24); - - *this = _ortho_bases[p_index]; -} - -Basis::Basis(const Vector3 &p_euler) { - set_euler(p_euler); -} - -} // namespace godot - -#include "Quat.hpp" - -namespace godot { - -Basis::Basis(const Quat &p_quat) { - real_t d = p_quat.length_squared(); - real_t s = 2.0 / d; - real_t xs = p_quat.x * s, ys = p_quat.y * s, zs = p_quat.z * s; - real_t wx = p_quat.w * xs, wy = p_quat.w * ys, wz = p_quat.w * zs; - real_t xx = p_quat.x * xs, xy = p_quat.x * ys, xz = p_quat.x * zs; - real_t yy = p_quat.y * ys, yz = p_quat.y * zs, zz = p_quat.z * zs; - set(1.0 - (yy + zz), xy - wz, xz + wy, - xy + wz, 1.0 - (xx + zz), yz - wx, - xz - wy, yz + wx, 1.0 - (xx + yy)); -} - -Basis::Basis(const Vector3 &p_axis, real_t p_phi) { - // Rotation matrix from axis and angle, see https://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle - - Vector3 axis_sq(p_axis.x * p_axis.x, p_axis.y * p_axis.y, p_axis.z * p_axis.z); - - real_t cosine = ::cos(p_phi); - real_t sine = ::sin(p_phi); - - elements[0][0] = axis_sq.x + cosine * (1.0 - axis_sq.x); - elements[0][1] = p_axis.x * p_axis.y * (1.0 - cosine) - p_axis.z * sine; - elements[0][2] = p_axis.z * p_axis.x * (1.0 - cosine) + p_axis.y * sine; - - elements[1][0] = p_axis.x * p_axis.y * (1.0 - cosine) + p_axis.z * sine; - elements[1][1] = axis_sq.y + cosine * (1.0 - axis_sq.y); - elements[1][2] = p_axis.y * p_axis.z * (1.0 - cosine) - p_axis.x * sine; - - elements[2][0] = p_axis.z * p_axis.x * (1.0 - cosine) - p_axis.y * sine; - elements[2][1] = p_axis.y * p_axis.z * (1.0 - cosine) + p_axis.x * sine; - elements[2][2] = axis_sq.z + cosine * (1.0 - axis_sq.z); -} - -Basis::operator Quat() const { - //commenting this check because precision issues cause it to fail when it shouldn't - //ERR_FAIL_COND_V(is_rotation() == false, Quat()); - - real_t trace = elements[0][0] + elements[1][1] + elements[2][2]; - real_t temp[4]; - - if (trace > 0.0) { - real_t s = ::sqrt(trace + 1.0); - temp[3] = (s * 0.5); - s = 0.5 / s; - - temp[0] = ((elements[2][1] - elements[1][2]) * s); - temp[1] = ((elements[0][2] - elements[2][0]) * s); - temp[2] = ((elements[1][0] - elements[0][1]) * s); - } else { - int i = elements[0][0] < elements[1][1] ? - (elements[1][1] < elements[2][2] ? 2 : 1) : - (elements[0][0] < elements[2][2] ? 2 : 0); - int j = (i + 1) % 3; - int k = (i + 2) % 3; - - real_t s = ::sqrt(elements[i][i] - elements[j][j] - elements[k][k] + 1.0); - temp[i] = s * 0.5; - s = 0.5 / s; - - temp[3] = (elements[k][j] - elements[j][k]) * s; - temp[j] = (elements[j][i] + elements[i][j]) * s; - temp[k] = (elements[k][i] + elements[i][k]) * s; - } - - return Quat(temp[0], temp[1], temp[2], temp[3]); -} - -} // namespace godot diff --git a/src/core/CameraMatrix.cpp b/src/core/CameraMatrix.cpp deleted file mode 100644 index de53263..0000000 --- a/src/core/CameraMatrix.cpp +++ /dev/null @@ -1,655 +0,0 @@ -/*************************************************************************/ -/* CameraMatrix.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "CameraMatrix.hpp" - -void CameraMatrix::set_identity() { - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - matrix[i][j] = (i == j) ? 1 : 0; - } - } -} - -void CameraMatrix::set_zero() { - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - matrix[i][j] = 0; - } - } -} - -Plane CameraMatrix::xform4(const Plane &p_vec4) const { - Plane ret; - - ret.normal.x = matrix[0][0] * p_vec4.normal.x + matrix[1][0] * p_vec4.normal.y + matrix[2][0] * p_vec4.normal.z + matrix[3][0] * p_vec4.d; - ret.normal.y = matrix[0][1] * p_vec4.normal.x + matrix[1][1] * p_vec4.normal.y + matrix[2][1] * p_vec4.normal.z + matrix[3][1] * p_vec4.d; - ret.normal.z = matrix[0][2] * p_vec4.normal.x + matrix[1][2] * p_vec4.normal.y + matrix[2][2] * p_vec4.normal.z + matrix[3][2] * p_vec4.d; - ret.d = matrix[0][3] * p_vec4.normal.x + matrix[1][3] * p_vec4.normal.y + matrix[2][3] * p_vec4.normal.z + matrix[3][3] * p_vec4.d; - return ret; -} - -void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov) { - if (p_flip_fov) { - p_fovy_degrees = get_fovy(p_fovy_degrees, 1.0 / p_aspect); - } - - real_t sine, cotangent, deltaZ; - real_t radians = p_fovy_degrees / 2.0 * Math_PI / 180.0; - - deltaZ = p_z_far - p_z_near; - sine = sin(radians); - - if ((deltaZ == 0) || (sine == 0) || (p_aspect == 0)) { - return; - } - cotangent = cos(radians) / sine; - - set_identity(); - - matrix[0][0] = cotangent / p_aspect; - matrix[1][1] = cotangent; - matrix[2][2] = -(p_z_far + p_z_near) / deltaZ; - matrix[2][3] = -1; - matrix[3][2] = -2 * p_z_near * p_z_far / deltaZ; - matrix[3][3] = 0; -} - -void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov, int p_eye, real_t p_intraocular_dist, real_t p_convergence_dist) { - if (p_flip_fov) { - p_fovy_degrees = get_fovy(p_fovy_degrees, 1.0 / p_aspect); - } - - real_t left, right, modeltranslation, ymax, xmax, frustumshift; - - ymax = p_z_near * tan(p_fovy_degrees * Math_PI / 360.0f); - xmax = ymax * p_aspect; - frustumshift = (p_intraocular_dist / 2.0) * p_z_near / p_convergence_dist; - - switch (p_eye) { - case 1: { // left eye - left = -xmax + frustumshift; - right = xmax + frustumshift; - modeltranslation = p_intraocular_dist / 2.0; - }; break; - case 2: { // right eye - left = -xmax - frustumshift; - right = xmax - frustumshift; - modeltranslation = -p_intraocular_dist / 2.0; - }; break; - default: { // mono, should give the same result as set_perspective(p_fovy_degrees,p_aspect,p_z_near,p_z_far,p_flip_fov) - left = -xmax; - right = xmax; - modeltranslation = 0.0; - }; break; - }; - - set_frustum(left, right, -ymax, ymax, p_z_near, p_z_far); - - // translate matrix by (modeltranslation, 0.0, 0.0) - CameraMatrix cm; - cm.set_identity(); - cm.matrix[3][0] = modeltranslation; - *this = *this * cm; -} - -void CameraMatrix::set_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_dist, real_t p_display_width, real_t p_display_to_lens, real_t p_oversample, real_t p_z_near, real_t p_z_far) { - // we first calculate our base frustum on our values without taking our lens magnification into account. - real_t f1 = (p_intraocular_dist * 0.5) / p_display_to_lens; - real_t f2 = ((p_display_width - p_intraocular_dist) * 0.5) / p_display_to_lens; - real_t f3 = (p_display_width / 4.0) / p_display_to_lens; - - // now we apply our oversample factor to increase our FOV. how much we oversample is always a balance we strike between performance and how much - // we're willing to sacrifice in FOV. - real_t add = ((f1 + f2) * (p_oversample - 1.0)) / 2.0; - f1 += add; - f2 += add; - f3 *= p_oversample; - - // always apply KEEP_WIDTH aspect ratio - f3 /= p_aspect; - - switch (p_eye) { - case 1: { // left eye - set_frustum(-f2 * p_z_near, f1 * p_z_near, -f3 * p_z_near, f3 * p_z_near, p_z_near, p_z_far); - }; break; - case 2: { // right eye - set_frustum(-f1 * p_z_near, f2 * p_z_near, -f3 * p_z_near, f3 * p_z_near, p_z_near, p_z_far); - }; break; - default: { // mono, does not apply here! - }; break; - }; -}; - -void CameraMatrix::set_orthogonal(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_znear, real_t p_zfar) { - set_identity(); - - matrix[0][0] = 2.0 / (p_right - p_left); - matrix[3][0] = -((p_right + p_left) / (p_right - p_left)); - matrix[1][1] = 2.0 / (p_top - p_bottom); - matrix[3][1] = -((p_top + p_bottom) / (p_top - p_bottom)); - matrix[2][2] = -2.0 / (p_zfar - p_znear); - matrix[3][2] = -((p_zfar + p_znear) / (p_zfar - p_znear)); - matrix[3][3] = 1.0; -} - -void CameraMatrix::set_orthogonal(real_t p_size, real_t p_aspect, real_t p_znear, real_t p_zfar, bool p_flip_fov) { - if (!p_flip_fov) { - p_size *= p_aspect; - } - - set_orthogonal(-p_size / 2, +p_size / 2, -p_size / p_aspect / 2, +p_size / p_aspect / 2, p_znear, p_zfar); -} - -void CameraMatrix::set_frustum(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_near, real_t p_far) { - ERR_FAIL_COND(p_right <= p_left); - ERR_FAIL_COND(p_top <= p_bottom); - ERR_FAIL_COND(p_far <= p_near); - - real_t *te = &matrix[0][0]; - real_t x = 2 * p_near / (p_right - p_left); - real_t y = 2 * p_near / (p_top - p_bottom); - - real_t a = (p_right + p_left) / (p_right - p_left); - real_t b = (p_top + p_bottom) / (p_top - p_bottom); - real_t c = -(p_far + p_near) / (p_far - p_near); - real_t d = -2 * p_far * p_near / (p_far - p_near); - - te[0] = x; - te[1] = 0; - te[2] = 0; - te[3] = 0; - te[4] = 0; - te[5] = y; - te[6] = 0; - te[7] = 0; - te[8] = a; - te[9] = b; - te[10] = c; - te[11] = -1; - te[12] = 0; - te[13] = 0; - te[14] = d; - te[15] = 0; -} - -void CameraMatrix::set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset, real_t p_near, real_t p_far, bool p_flip_fov) { - if (!p_flip_fov) { - p_size *= p_aspect; - } - - set_frustum(-p_size / 2 + p_offset.x, +p_size / 2 + p_offset.x, -p_size / p_aspect / 2 + p_offset.y, +p_size / p_aspect / 2 + p_offset.y, p_near, p_far); -} - -real_t CameraMatrix::get_z_far() const { - const real_t *matrix = (const real_t *)this->matrix; - Plane new_plane = Plane(matrix[3] - matrix[2], - matrix[7] - matrix[6], - matrix[11] - matrix[10], - matrix[15] - matrix[14]); - - new_plane.normal = -new_plane.normal; - new_plane.normalize(); - - return new_plane.d; -} -real_t CameraMatrix::get_z_near() const { - const real_t *matrix = (const real_t *)this->matrix; - Plane new_plane = Plane(matrix[3] + matrix[2], - matrix[7] + matrix[6], - matrix[11] + matrix[10], - -matrix[15] - matrix[14]); - - new_plane.normalize(); - return new_plane.d; -} - -Vector2 CameraMatrix::get_viewport_half_extents() const { - const real_t *matrix = (const real_t *)this->matrix; - ///////--- Near Plane ---/////// - Plane near_plane = Plane(matrix[3] + matrix[2], - matrix[7] + matrix[6], - matrix[11] + matrix[10], - -matrix[15] - matrix[14]); - near_plane.normalize(); - - ///////--- Right Plane ---/////// - Plane right_plane = Plane(matrix[3] - matrix[0], - matrix[7] - matrix[4], - matrix[11] - matrix[8], - -matrix[15] + matrix[12]); - right_plane.normalize(); - - Plane top_plane = Plane(matrix[3] - matrix[1], - matrix[7] - matrix[5], - matrix[11] - matrix[9], - -matrix[15] + matrix[13]); - top_plane.normalize(); - - Vector3 res; - near_plane.intersect_3(right_plane, top_plane, &res); - - return Vector2(res.x, res.y); -} - -bool CameraMatrix::get_endpoints(const Transform &p_transform, Vector3 *p_8points) const { - std::vector<Plane> planes = get_projection_planes(Transform()); - const Planes intersections[8][3] = { - { PLANE_FAR, PLANE_LEFT, PLANE_TOP }, - { PLANE_FAR, PLANE_LEFT, PLANE_BOTTOM }, - { PLANE_FAR, PLANE_RIGHT, PLANE_TOP }, - { PLANE_FAR, PLANE_RIGHT, PLANE_BOTTOM }, - { PLANE_NEAR, PLANE_LEFT, PLANE_TOP }, - { PLANE_NEAR, PLANE_LEFT, PLANE_BOTTOM }, - { PLANE_NEAR, PLANE_RIGHT, PLANE_TOP }, - { PLANE_NEAR, PLANE_RIGHT, PLANE_BOTTOM }, - }; - - for (int i = 0; i < 8; i++) { - Vector3 point; - bool res = planes[intersections[i][0]].intersect_3(planes[intersections[i][1]], planes[intersections[i][2]], &point); - ERR_FAIL_COND_V(!res, false); - p_8points[i] = p_transform.xform(point); - } - - return true; -} - -std::vector<Plane> CameraMatrix::get_projection_planes(const Transform &p_transform) const { - /** Fast Plane Extraction from combined modelview/projection matrices. - * References: - * https://web.archive.org/web/20011221205252/http://www.markmorley.com/opengl/frustumculling.html - * https://web.archive.org/web/20061020020112/http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf - */ - - std::vector<Plane> planes; - - const real_t *matrix = (const real_t *)this->matrix; - - Plane new_plane; - - ///////--- Near Plane ---/////// - new_plane = Plane(matrix[3] + matrix[2], - matrix[7] + matrix[6], - matrix[11] + matrix[10], - matrix[15] + matrix[14]); - - new_plane.normal = -new_plane.normal; - new_plane.normalize(); - - planes.push_back(p_transform.xform(new_plane)); - - ///////--- Far Plane ---/////// - new_plane = Plane(matrix[3] - matrix[2], - matrix[7] - matrix[6], - matrix[11] - matrix[10], - matrix[15] - matrix[14]); - - new_plane.normal = -new_plane.normal; - new_plane.normalize(); - - planes.push_back(p_transform.xform(new_plane)); - - ///////--- Left Plane ---/////// - new_plane = Plane(matrix[3] + matrix[0], - matrix[7] + matrix[4], - matrix[11] + matrix[8], - matrix[15] + matrix[12]); - - new_plane.normal = -new_plane.normal; - new_plane.normalize(); - - planes.push_back(p_transform.xform(new_plane)); - - ///////--- Top Plane ---/////// - new_plane = Plane(matrix[3] - matrix[1], - matrix[7] - matrix[5], - matrix[11] - matrix[9], - matrix[15] - matrix[13]); - - new_plane.normal = -new_plane.normal; - new_plane.normalize(); - - planes.push_back(p_transform.xform(new_plane)); - - ///////--- Right Plane ---/////// - new_plane = Plane(matrix[3] - matrix[0], - matrix[7] - matrix[4], - matrix[11] - matrix[8], - matrix[15] - matrix[12]); - - new_plane.normal = -new_plane.normal; - new_plane.normalize(); - - planes.push_back(p_transform.xform(new_plane)); - - ///////--- Bottom Plane ---/////// - new_plane = Plane(matrix[3] + matrix[1], - matrix[7] + matrix[5], - matrix[11] + matrix[9], - matrix[15] + matrix[13]); - - new_plane.normal = -new_plane.normal; - new_plane.normalize(); - - planes.push_back(p_transform.xform(new_plane)); - - return planes; -} - -CameraMatrix CameraMatrix::inverse() const { - CameraMatrix cm = *this; - cm.invert(); - return cm; -} - -void CameraMatrix::invert() { - int i, j, k; - int pvt_i[4], pvt_j[4]; /* Locations of pivot matrix */ - real_t pvt_val; /* Value of current pivot element */ - real_t hold; /* Temporary storage */ - real_t determinat; /* Determinant */ - - determinat = 1.0; - for (k = 0; k < 4; k++) { - /** Locate k'th pivot element **/ - pvt_val = matrix[k][k]; /** Initialize for search **/ - pvt_i[k] = k; - pvt_j[k] = k; - for (i = k; i < 4; i++) { - for (j = k; j < 4; j++) { - if (absd(matrix[i][j]) > absd(pvt_val)) { - pvt_i[k] = i; - pvt_j[k] = j; - pvt_val = matrix[i][j]; - } - } - } - - /** Product of pivots, gives determinant when finished **/ - determinat *= pvt_val; - if (absd(determinat) < 1e-7) { - return; //(false); /** Matrix is singular (zero determinant). **/ - } - - /** "Interchange" rows (with sign change stuff) **/ - i = pvt_i[k]; - if (i != k) { /** If rows are different **/ - for (j = 0; j < 4; j++) { - hold = -matrix[k][j]; - matrix[k][j] = matrix[i][j]; - matrix[i][j] = hold; - } - } - - /** "Interchange" columns **/ - j = pvt_j[k]; - if (j != k) { /** If columns are different **/ - for (i = 0; i < 4; i++) { - hold = -matrix[i][k]; - matrix[i][k] = matrix[i][j]; - matrix[i][j] = hold; - } - } - - /** Divide column by minus pivot value **/ - for (i = 0; i < 4; i++) { - if (i != k) - matrix[i][k] /= (-pvt_val); - } - - /** Reduce the matrix **/ - for (i = 0; i < 4; i++) { - hold = matrix[i][k]; - for (j = 0; j < 4; j++) { - if (i != k && j != k) - matrix[i][j] += hold * matrix[k][j]; - } - } - - /** Divide row by pivot **/ - for (j = 0; j < 4; j++) { - if (j != k) - matrix[k][j] /= pvt_val; - } - - /** Replace pivot by reciprocal (at last we can touch it). **/ - matrix[k][k] = 1.0 / pvt_val; - } - - /* That was most of the work, one final pass of row/column interchange */ - /* to finish */ - for (k = 4 - 2; k >= 0; k--) { /* Don't need to work with 1 by 1 corner*/ - i = pvt_j[k]; /* Rows to swap correspond to pivot COLUMN */ - if (i != k) { /* If rows are different */ - for (j = 0; j < 4; j++) { - hold = matrix[k][j]; - matrix[k][j] = -matrix[i][j]; - matrix[i][j] = hold; - } - } - - j = pvt_i[k]; /* Columns to swap correspond to pivot ROW */ - if (j != k) /* If columns are different */ - for (i = 0; i < 4; i++) { - hold = matrix[i][k]; - matrix[i][k] = -matrix[i][j]; - matrix[i][j] = hold; - } - } -} - -CameraMatrix::CameraMatrix() { - set_identity(); -} - -CameraMatrix CameraMatrix::operator*(const CameraMatrix &p_matrix) const { - CameraMatrix new_matrix; - - for (int j = 0; j < 4; j++) { - for (int i = 0; i < 4; i++) { - real_t ab = 0; - for (int k = 0; k < 4; k++) - ab += matrix[k][i] * p_matrix.matrix[j][k]; - new_matrix.matrix[j][i] = ab; - } - } - - return new_matrix; -} - -void CameraMatrix::set_light_bias() { - real_t *m = &matrix[0][0]; - - m[0] = 0.5; - m[1] = 0.0; - m[2] = 0.0; - m[3] = 0.0; - m[4] = 0.0; - m[5] = 0.5; - m[6] = 0.0; - m[7] = 0.0; - m[8] = 0.0; - m[9] = 0.0; - m[10] = 0.5; - m[11] = 0.0; - m[12] = 0.5; - m[13] = 0.5; - m[14] = 0.5; - m[15] = 1.0; -} - -void CameraMatrix::set_light_atlas_rect(const Rect2 &p_rect) { - real_t *m = &matrix[0][0]; - - m[0] = p_rect.size.width; - m[1] = 0.0; - m[2] = 0.0; - m[3] = 0.0; - m[4] = 0.0; - m[5] = p_rect.size.height; - m[6] = 0.0; - m[7] = 0.0; - m[8] = 0.0; - m[9] = 0.0; - m[10] = 1.0; - m[11] = 0.0; - m[12] = p_rect.position.x; - m[13] = p_rect.position.y; - m[14] = 0.0; - m[15] = 1.0; -} - -CameraMatrix::operator String() const { - String str; - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - str += String((j > 0) ? ", " : "\n") + String::num(matrix[i][j]); - - return str; -} - -real_t CameraMatrix::get_aspect() const { - Vector2 vp_he = get_viewport_half_extents(); - return vp_he.x / vp_he.y; -} - -int CameraMatrix::get_pixels_per_meter(int p_for_pixel_width) const { - Vector3 result = xform(Vector3(1, 0, -1)); - - return int((result.x * 0.5 + 0.5) * p_for_pixel_width); -} - -bool CameraMatrix::is_orthogonal() const { - return matrix[3][3] == 1.0; -} - -real_t CameraMatrix::get_fov() const { - const real_t *matrix = (const real_t *)this->matrix; - - Plane right_plane = Plane(matrix[3] - matrix[0], - matrix[7] - matrix[4], - matrix[11] - matrix[8], - -matrix[15] + matrix[12]); - right_plane.normalize(); - - if ((matrix[8] == 0) && (matrix[9] == 0)) { - return Math::rad2deg(acos(std::abs(right_plane.normal.x))) * 2.0; - } else { - // our frustum is asymmetrical need to calculate the left planes angle separately.. - Plane left_plane = Plane(matrix[3] + matrix[0], - matrix[7] + matrix[4], - matrix[11] + matrix[8], - matrix[15] + matrix[12]); - left_plane.normalize(); - - return Math::rad2deg(acos(std::abs(left_plane.normal.x))) + Math::rad2deg(acos(std::abs(right_plane.normal.x))); - } -} - -void CameraMatrix::make_scale(const Vector3 &p_scale) { - set_identity(); - matrix[0][0] = p_scale.x; - matrix[1][1] = p_scale.y; - matrix[2][2] = p_scale.z; -} - -void CameraMatrix::scale_translate_to_fit(const AABB &p_aabb) { - Vector3 min = p_aabb.position; - Vector3 max = p_aabb.position + p_aabb.size; - - matrix[0][0] = 2 / (max.x - min.x); - matrix[1][0] = 0; - matrix[2][0] = 0; - matrix[3][0] = -(max.x + min.x) / (max.x - min.x); - - matrix[0][1] = 0; - matrix[1][1] = 2 / (max.y - min.y); - matrix[2][1] = 0; - matrix[3][1] = -(max.y + min.y) / (max.y - min.y); - - matrix[0][2] = 0; - matrix[1][2] = 0; - matrix[2][2] = 2 / (max.z - min.z); - matrix[3][2] = -(max.z + min.z) / (max.z - min.z); - - matrix[0][3] = 0; - matrix[1][3] = 0; - matrix[2][3] = 0; - matrix[3][3] = 1; -} - -CameraMatrix::operator Transform() const { - Transform tr; - const real_t *m = &matrix[0][0]; - - tr.basis.elements[0][0] = m[0]; - tr.basis.elements[1][0] = m[1]; - tr.basis.elements[2][0] = m[2]; - - tr.basis.elements[0][1] = m[4]; - tr.basis.elements[1][1] = m[5]; - tr.basis.elements[2][1] = m[6]; - - tr.basis.elements[0][2] = m[8]; - tr.basis.elements[1][2] = m[9]; - tr.basis.elements[2][2] = m[10]; - - tr.origin.x = m[12]; - tr.origin.y = m[13]; - tr.origin.z = m[14]; - - return tr; -} - -CameraMatrix::CameraMatrix(const Transform &p_transform) { - const Transform &tr = p_transform; - real_t *m = &matrix[0][0]; - - m[0] = tr.basis.elements[0][0]; - m[1] = tr.basis.elements[1][0]; - m[2] = tr.basis.elements[2][0]; - m[3] = 0.0; - m[4] = tr.basis.elements[0][1]; - m[5] = tr.basis.elements[1][1]; - m[6] = tr.basis.elements[2][1]; - m[7] = 0.0; - m[8] = tr.basis.elements[0][2]; - m[9] = tr.basis.elements[1][2]; - m[10] = tr.basis.elements[2][2]; - m[11] = 0.0; - m[12] = tr.origin.x; - m[13] = tr.origin.y; - m[14] = tr.origin.z; - m[15] = 1.0; -} - -CameraMatrix::~CameraMatrix() { -} diff --git a/src/core/Color.cpp b/src/core/Color.cpp deleted file mode 100644 index 8efc5c3..0000000 --- a/src/core/Color.cpp +++ /dev/null @@ -1,655 +0,0 @@ -/*************************************************************************/ -/* Color.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "Color.hpp" -#include "Defs.hpp" -#include "String.hpp" - -#include <gdnative/color.h> -#include <cmath> - -namespace godot { - -#define MIN(a, b) (a < b ? a : b) -#define MAX(a, b) (a > b ? a : b) - -static String _to_hex(float p_val); - -static float _parse_col(const String &p_str, int p_ofs) { - int ig = 0; - - for (int i = 0; i < 2; i++) { - int c = (int)(wchar_t)p_str[i + p_ofs]; - int v = 0; - - if (c >= '0' && c <= '9') { - v = c - '0'; - } else if (c >= 'a' && c <= 'f') { - v = c - 'a'; - v += 10; - } else if (c >= 'A' && c <= 'F') { - v = c - 'A'; - v += 10; - } else { - return -1; - } - - if (i == 0) - ig += v * 16; - else - ig += v; - } - - return ig; -} - -uint32_t Color::to_32() const { - uint32_t c = (uint8_t)(a * 255); - c <<= 8; - c |= (uint8_t)(r * 255); - c <<= 8; - c |= (uint8_t)(g * 255); - c <<= 8; - c |= (uint8_t)(b * 255); - - return c; -} - -uint32_t Color::to_ARGB32() const { - uint32_t c = (uint8_t)(a * 255); - c <<= 8; - c |= (uint8_t)(r * 255); - c <<= 8; - c |= (uint8_t)(g * 255); - c <<= 8; - c |= (uint8_t)(b * 255); - - return c; -} - -uint32_t Color::to_ABGR32() const { - uint32_t c = (uint8_t)(a * 255); - c <<= 8; - c |= (uint8_t)(b * 255); - c <<= 8; - c |= (uint8_t)(g * 255); - c <<= 8; - c |= (uint8_t)(r * 255); - - return c; -} - -uint64_t Color::to_ABGR64() const { - uint64_t c = (uint16_t)(a * 65535); - c <<= 16; - c |= (uint16_t)(b * 65535); - c <<= 16; - c |= (uint16_t)(g * 65535); - c <<= 16; - c |= (uint16_t)(r * 65535); - - return c; -} - -uint64_t Color::to_ARGB64() const { - uint64_t c = (uint16_t)(a * 65535); - c <<= 16; - c |= (uint16_t)(r * 65535); - c <<= 16; - c |= (uint16_t)(g * 65535); - c <<= 16; - c |= (uint16_t)(b * 65535); - - return c; -} - -uint32_t Color::to_RGBA32() const { - uint32_t c = (uint8_t)(r * 255); - c <<= 8; - c |= (uint8_t)(g * 255); - c <<= 8; - c |= (uint8_t)(b * 255); - c <<= 8; - c |= (uint8_t)(a * 255); - - return c; -} - -uint64_t Color::to_RGBA64() const { - uint64_t c = (uint16_t)(r * 65535); - c <<= 16; - c |= (uint16_t)(g * 65535); - c <<= 16; - c |= (uint16_t)(b * 65535); - c <<= 16; - c |= (uint16_t)(a * 65535); - - return c; -} - -float Color::gray() const { - return (r + g + b) / 3.0; -} - -uint8_t Color::get_r8() const { - return (uint8_t)(r * 255.0); -} - -uint8_t Color::get_g8() const { - return (uint8_t)(g * 255.0); -} - -uint8_t Color::get_b8() const { - return (uint8_t)(b * 255.0); -} - -uint8_t Color::get_a8() const { - return (uint8_t)(a * 255.0); -} - -float Color::get_h() const { - float min = MIN(r, g); - min = MIN(min, b); - float max = MAX(r, g); - max = MAX(max, b); - - float delta = max - min; - - if (delta == 0) - return 0; - - float h; - if (r == max) - h = (g - b) / delta; // between yellow & magenta - else if (g == max) - h = 2 + (b - r) / delta; // between cyan & yellow - else - h = 4 + (r - g) / delta; // between magenta & cyan - - h /= 6.0; - if (h < 0) - h += 1.0; - - return h; -} - -float Color::get_s() const { - float min = MIN(r, g); - min = MIN(min, b); - float max = MAX(r, g); - max = MAX(max, b); - float delta = max - min; - return (max != 0) ? (delta / max) : 0; -} - -float Color::get_v() const { - float max = MAX(r, g); - max = MAX(max, b); - return max; -} - -void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) { - int i; - float f, p, q, t; - a = p_alpha; - - if (p_s == 0) { - // acp_hromatic (grey) - r = g = b = p_v; - return; - } - - p_h *= 6.0; - p_h = ::fmod(p_h, 6); - i = ::floor(p_h); - - f = p_h - i; - p = p_v * (1 - p_s); - q = p_v * (1 - p_s * f); - t = p_v * (1 - p_s * (1 - f)); - - switch (i) { - case 0: // Red is the dominant color - r = p_v; - g = t; - b = p; - break; - case 1: // Green is the dominant color - r = q; - g = p_v; - b = p; - break; - case 2: - r = p; - g = p_v; - b = t; - break; - case 3: // Blue is the dominant color - r = p; - g = q; - b = p_v; - break; - case 4: - r = t; - g = p; - b = p_v; - break; - default: // (5) Red is the dominant color - r = p_v; - g = p; - b = q; - break; - } -} - -Color Color::darkened(const float p_amount) const { - Color res = *this; - res.r = res.r * (1.0f - p_amount); - res.g = res.g * (1.0f - p_amount); - res.b = res.b * (1.0f - p_amount); - return res; -} - -Color Color::lightened(const float p_amount) const { - Color res = *this; - res.r = res.r + (1.0f - res.r) * p_amount; - res.g = res.g + (1.0f - res.g) * p_amount; - res.b = res.b + (1.0f - res.b) * p_amount; - return res; -} - -Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const { - p_h = ::fmod(p_h * 360.0f, 360.0f); - if (p_h < 0.0) - p_h += 360.0f; - - const float h_ = p_h / 60.0f; - const float c = p_v * p_s; - const float x = c * (1.0f - ::fabs(::fmod(h_, 2.0f) - 1.0f)); - float r, g, b; - - switch ((int)h_) { - case 0: { - r = c; - g = x; - b = 0; - } break; - case 1: { - r = x; - g = c; - b = 0; - } break; - case 2: { - r = 0; - g = c; - b = x; - } break; - case 3: { - r = 0; - g = x; - b = c; - } break; - case 4: { - r = x; - g = 0; - b = c; - } break; - case 5: { - r = c; - g = 0; - b = x; - } break; - default: { - r = 0; - g = 0; - b = 0; - } break; - } - - const float m = p_v - c; - return Color(m + r, m + g, m + b, p_a); -} - -void Color::invert() { - r = 1.0 - r; - g = 1.0 - g; - b = 1.0 - b; -} - -void Color::contrast() { - r = ::fmod(r + 0.5, 1.0); - g = ::fmod(g + 0.5, 1.0); - b = ::fmod(b + 0.5, 1.0); -} -Color Color::inverted() const { - Color c = *this; - c.invert(); - return c; -} -Color Color::contrasted() const { - Color c = *this; - c.contrast(); - return c; -} - -Color Color::linear_interpolate(const Color &p_b, float p_t) const { - Color res = *this; - - res.r += (p_t * (p_b.r - r)); - res.g += (p_t * (p_b.g - g)); - res.b += (p_t * (p_b.b - b)); - res.a += (p_t * (p_b.a - a)); - - return res; -} - -Color Color::blend(const Color &p_over) const { - Color res; - float sa = 1.0 - p_over.a; - res.a = a * sa + p_over.a; - if (res.a == 0) { - return Color(0, 0, 0, 0); - } else { - res.r = (r * a * sa + p_over.r * p_over.a) / res.a; - res.g = (g * a * sa + p_over.g * p_over.a) / res.a; - res.b = (b * a * sa + p_over.b * p_over.a) / res.a; - } - return res; -} - -Color Color::to_linear() const { - return Color( - r < 0.04045 ? r * (1.0 / 12.92) : ::pow((r + 0.055) * (1.0 / (1 + 0.055)), 2.4), - g < 0.04045 ? g * (1.0 / 12.92) : ::pow((g + 0.055) * (1.0 / (1 + 0.055)), 2.4), - b < 0.04045 ? b * (1.0 / 12.92) : ::pow((b + 0.055) * (1.0 / (1 + 0.055)), 2.4), - a); -} - -Color Color::hex(uint32_t p_hex) { - float a = (p_hex & 0xFF) / 255.0; - p_hex >>= 8; - float b = (p_hex & 0xFF) / 255.0; - p_hex >>= 8; - float g = (p_hex & 0xFF) / 255.0; - p_hex >>= 8; - float r = (p_hex & 0xFF) / 255.0; - - return Color(r, g, b, a); -} - -Color Color::html(const String &p_color) { - String color = p_color; - if (color.length() == 0) - return Color(); - if (color[0] == '#') - color = color.substr(1, color.length() - 1); - - bool alpha = false; - - if (color.length() == 8) { - alpha = true; - } else if (color.length() == 6) { - alpha = false; - } else { - ERR_PRINTS(String("Invalid Color Code: ") + p_color); - ERR_FAIL_V(Color()); - } - - int a = 255; - if (alpha) { - a = _parse_col(color, 0); - if (a < 0) { - ERR_PRINTS(String("Invalid Color Code: ") + p_color); - ERR_FAIL_V(Color()); - } - } - - int from = alpha ? 2 : 0; - - int r = _parse_col(color, from + 0); - if (r < 0) { - ERR_PRINTS(String("Invalid Color Code: ") + p_color); - ERR_FAIL_V(Color()); - } - int g = _parse_col(color, from + 2); - if (g < 0) { - ERR_PRINTS(String("Invalid Color Code: ") + p_color); - ERR_FAIL_V(Color()); - } - int b = _parse_col(color, from + 4); - if (b < 0) { - ERR_PRINTS(String("Invalid Color Code: ") + p_color); - ERR_FAIL_V(Color()); - } - - return Color(r / 255.0, g / 255.0, b / 255.0, a / 255.0); -} - -bool Color::html_is_valid(const String &p_color) { - String color = p_color; - - if (color.length() == 0) - return false; - if (color[0] == '#') - color = color.substr(1, color.length() - 1); - - bool alpha = false; - - if (color.length() == 8) { - alpha = true; - } else if (color.length() == 6) { - alpha = false; - } else { - return false; - } - - int a = 255; - if (alpha) { - a = _parse_col(color, 0); - if (a < 0) { - return false; - } - } - - int from = alpha ? 2 : 0; - - int r = _parse_col(color, from + 0); - if (r < 0) { - return false; - } - int g = _parse_col(color, from + 2); - if (g < 0) { - return false; - } - int b = _parse_col(color, from + 4); - if (b < 0) { - return false; - } - - return true; -} - -#ifndef CLAMP -#define CLAMP(m_a, m_min, m_max) (((m_a) < (m_min)) ? (m_min) : (((m_a) > (m_max)) ? m_max : m_a)) -#endif -static String _to_hex(float p_val) { - int v = p_val * 255; - v = CLAMP(v, 0, 255); - String ret; - - for (int i = 0; i < 2; i++) { - wchar_t c[2] = { 0, 0 }; - int lv = v & 0xF; - if (lv < 10) - c[0] = '0' + lv; - else - c[0] = 'a' + lv - 10; - - v >>= 4; - String cs = (const wchar_t *)c; - ret = cs + ret; - } - - return ret; -} - -String Color::to_html(bool p_alpha) const { - String txt; - txt += _to_hex(r); - txt += _to_hex(g); - txt += _to_hex(b); - if (p_alpha) - txt = _to_hex(a) + txt; - return txt; -} - -Color::operator String() const { - return String::num(r) + ", " + String::num(g) + ", " + String::num(b) + ", " + String::num(a); -} - -bool Color::operator<(const Color &p_color) const { - if (r == p_color.r) { - if (g == p_color.g) { - if (b == p_color.b) { - return (a < p_color.a); - } else - return (b < p_color.b); - } else - return g < p_color.g; - } else - return r < p_color.r; -} - -Color Color::operator+(const Color &p_color) const { - return Color( - r + p_color.r, - g + p_color.g, - b + p_color.b, - a + p_color.a); -} - -void Color::operator+=(const Color &p_color) { - r = r + p_color.r; - g = g + p_color.g; - b = b + p_color.b; - a = a + p_color.a; -} - -Color Color::operator-(const Color &p_color) const { - return Color( - r - p_color.r, - g - p_color.g, - b - p_color.b, - a - p_color.a); -} - -void Color::operator-=(const Color &p_color) { - r = r - p_color.r; - g = g - p_color.g; - b = b - p_color.b; - a = a - p_color.a; -} - -Color Color::operator*(const Color &p_color) const { - return Color( - r * p_color.r, - g * p_color.g, - b * p_color.b, - a * p_color.a); -} - -Color Color::operator*(const real_t &rvalue) const { - return Color( - r * rvalue, - g * rvalue, - b * rvalue, - a * rvalue); -} - -void Color::operator*=(const Color &p_color) { - r = r * p_color.r; - g = g * p_color.g; - b = b * p_color.b; - a = a * p_color.a; -} - -void Color::operator*=(const real_t &rvalue) { - r = r * rvalue; - g = g * rvalue; - b = b * rvalue; - a = a * rvalue; -} - -Color Color::operator/(const Color &p_color) const { - return Color( - r / p_color.r, - g / p_color.g, - b / p_color.b, - a / p_color.a); -} - -Color Color::operator/(const real_t &rvalue) const { - return Color( - r / rvalue, - g / rvalue, - b / rvalue, - a / rvalue); -} - -void Color::operator/=(const Color &p_color) { - r = r / p_color.r; - g = g / p_color.g; - b = b / p_color.b; - a = a / p_color.a; -} - -void Color::operator/=(const real_t &rvalue) { - if (rvalue == 0) { - r = 1.0; - g = 1.0; - b = 1.0; - a = 1.0; - } else { - r = r / rvalue; - g = g / rvalue; - b = b / rvalue; - a = a / rvalue; - } -} - -Color Color::operator-() const { - return Color( - 1.0 - r, - 1.0 - g, - 1.0 - b, - 1.0 - a); -} - -} // namespace godot diff --git a/src/core/Dictionary.cpp b/src/core/Dictionary.cpp deleted file mode 100644 index 6f846c3..0000000 --- a/src/core/Dictionary.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/*************************************************************************/ -/* Dictionary.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "Dictionary.hpp" -#include "Array.hpp" -#include "GodotGlobal.hpp" -#include "Variant.hpp" - -namespace godot { - -Dictionary::Dictionary() { - godot::api->godot_dictionary_new(&_godot_dictionary); -} - -Dictionary::Dictionary(const Dictionary &other) { - godot::api->godot_dictionary_new_copy(&_godot_dictionary, &other._godot_dictionary); -} - -Dictionary &Dictionary::operator=(const Dictionary &other) { - godot::api->godot_dictionary_destroy(&_godot_dictionary); - godot::api->godot_dictionary_new_copy(&_godot_dictionary, &other._godot_dictionary); - return *this; -} - -void Dictionary::clear() { - godot::api->godot_dictionary_clear(&_godot_dictionary); -} - -bool Dictionary::empty() const { - return godot::api->godot_dictionary_empty(&_godot_dictionary); -} - -void Dictionary::erase(const Variant &key) { - godot::api->godot_dictionary_erase(&_godot_dictionary, (godot_variant *)&key); -} - -bool Dictionary::has(const Variant &key) const { - return godot::api->godot_dictionary_has(&_godot_dictionary, (godot_variant *)&key); -} - -bool Dictionary::has_all(const Array &keys) const { - return godot::api->godot_dictionary_has_all(&_godot_dictionary, (godot_array *)&keys); -} - -uint32_t Dictionary::hash() const { - return godot::api->godot_dictionary_hash(&_godot_dictionary); -} - -Array Dictionary::keys() const { - godot_array a = godot::api->godot_dictionary_keys(&_godot_dictionary); - return Array(a); -} - -Variant &Dictionary::operator[](const Variant &key) { - godot_variant *v = godot::api->godot_dictionary_operator_index(&_godot_dictionary, (godot_variant *)&key); - return *reinterpret_cast<Variant *>(v); -} - -const Variant &Dictionary::operator[](const Variant &key) const { - // oops I did it again - godot_variant *v = godot::api->godot_dictionary_operator_index((godot_dictionary *)&_godot_dictionary, (godot_variant *)&key); - return *reinterpret_cast<Variant *>(v); -} - -int Dictionary::size() const { - return godot::api->godot_dictionary_size(&_godot_dictionary); -} - -String Dictionary::to_json() const { - godot_string s = godot::api->godot_dictionary_to_json(&_godot_dictionary); - return String(s); -} - -Array Dictionary::values() const { - godot_array a = godot::api->godot_dictionary_values(&_godot_dictionary); - return Array(a); -} - -Dictionary::~Dictionary() { - godot::api->godot_dictionary_destroy(&_godot_dictionary); -} - -} // namespace godot diff --git a/src/core/GodotGlobal.cpp b/src/core/GodotGlobal.cpp deleted file mode 100644 index b9cf88a..0000000 --- a/src/core/GodotGlobal.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/*************************************************************************/ -/* GodotGlobal.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "GodotGlobal.hpp" - -#include "String.hpp" - -#include "Wrapped.hpp" - -static GDCALLINGCONV void *wrapper_create(void *data, const void *type_tag, godot_object *instance) { - godot::_Wrapped *wrapper_memory = (godot::_Wrapped *)godot::api->godot_alloc(sizeof(godot::_Wrapped)); - - if (!wrapper_memory) - return NULL; - wrapper_memory->_owner = instance; - wrapper_memory->_type_tag = (size_t)type_tag; - - return (void *)wrapper_memory; -} - -static GDCALLINGCONV void wrapper_destroy(void *data, void *wrapper) { - if (wrapper) - godot::api->godot_free(wrapper); -} - -namespace godot { - -void *_RegisterState::nativescript_handle; -int _RegisterState::language_index; - -const godot_gdnative_core_api_struct *api = nullptr; -const godot_gdnative_core_1_1_api_struct *core_1_1_api = nullptr; -const godot_gdnative_core_1_2_api_struct *core_1_2_api = nullptr; - -const godot_gdnative_ext_nativescript_api_struct *nativescript_api = nullptr; -const godot_gdnative_ext_nativescript_1_1_api_struct *nativescript_1_1_api = nullptr; -const godot_gdnative_ext_pluginscript_api_struct *pluginscript_api = nullptr; -const godot_gdnative_ext_android_api_struct *android_api = nullptr; -const godot_gdnative_ext_arvr_api_struct *arvr_api = nullptr; -const godot_gdnative_ext_videodecoder_api_struct *videodecoder_api = nullptr; -const godot_gdnative_ext_net_api_struct *net_api = nullptr; -const godot_gdnative_ext_net_3_2_api_struct *net_3_2_api = nullptr; - -const void *gdnlib = NULL; - -void Godot::print(const String &message) { - godot::api->godot_print((godot_string *)&message); -} - -void Godot::print_warning(const String &description, const String &function, const String &file, int line) { - int len; - - char *c_desc = description.alloc_c_string(); - char *c_func = function.alloc_c_string(); - char *c_file = file.alloc_c_string(); - - if (c_desc != nullptr && c_func != nullptr && c_file != nullptr) { - godot::api->godot_print_warning(c_desc, c_func, c_file, line); - }; - - if (c_desc != nullptr) - godot::api->godot_free(c_desc); - if (c_func != nullptr) - godot::api->godot_free(c_func); - if (c_file != nullptr) - godot::api->godot_free(c_file); -} - -void Godot::print_error(const String &description, const String &function, const String &file, int line) { - int len; - - char *c_desc = description.alloc_c_string(); - char *c_func = function.alloc_c_string(); - char *c_file = file.alloc_c_string(); - - if (c_desc != nullptr && c_func != nullptr && c_file != nullptr) { - godot::api->godot_print_error(c_desc, c_func, c_file, line); - }; - - if (c_desc != nullptr) - godot::api->godot_free(c_desc); - if (c_func != nullptr) - godot::api->godot_free(c_func); - if (c_file != nullptr) - godot::api->godot_free(c_file); -} - -void ___register_types(); -void ___init_method_bindings(); - -void Godot::gdnative_init(godot_gdnative_init_options *options) { - godot::api = options->api_struct; - godot::gdnlib = options->gd_native_library; - - const godot_gdnative_api_struct *core_extension = godot::api->next; - - while (core_extension) { - if (core_extension->version.major == 1 && core_extension->version.minor == 1) { - godot::core_1_1_api = (const godot_gdnative_core_1_1_api_struct *)core_extension; - } else if (core_extension->version.major == 1 && core_extension->version.minor == 2) { - godot::core_1_2_api = (const godot_gdnative_core_1_2_api_struct *)core_extension; - } - core_extension = core_extension->next; - } - - // now find our extensions - for (int i = 0; i < godot::api->num_extensions; i++) { - switch (godot::api->extensions[i]->type) { - case GDNATIVE_EXT_NATIVESCRIPT: { - godot::nativescript_api = (const godot_gdnative_ext_nativescript_api_struct *)godot::api->extensions[i]; - - const godot_gdnative_api_struct *extension = godot::nativescript_api->next; - - while (extension) { - if (extension->version.major == 1 && extension->version.minor == 1) { - godot::nativescript_1_1_api = (const godot_gdnative_ext_nativescript_1_1_api_struct *)extension; - } - - extension = extension->next; - } - } break; - case GDNATIVE_EXT_PLUGINSCRIPT: { - godot::pluginscript_api = (const godot_gdnative_ext_pluginscript_api_struct *)godot::api->extensions[i]; - } break; - case GDNATIVE_EXT_ANDROID: { - godot::android_api = (const godot_gdnative_ext_android_api_struct *)godot::api->extensions[i]; - } break; - case GDNATIVE_EXT_ARVR: { - godot::arvr_api = (const godot_gdnative_ext_arvr_api_struct *)godot::api->extensions[i]; - } break; - case GDNATIVE_EXT_VIDEODECODER: { - godot::videodecoder_api = (const godot_gdnative_ext_videodecoder_api_struct *)godot::api->extensions[i]; - } break; - case GDNATIVE_EXT_NET: { - godot::net_api = (const godot_gdnative_ext_net_api_struct *)godot::api->extensions[i]; - - const godot_gdnative_api_struct *extension = godot::net_api->next; - - while (extension) { - if (extension->version.major == 3 && extension->version.minor == 2) { - godot::net_3_2_api = (const godot_gdnative_ext_net_3_2_api_struct *)extension; - } - - extension = extension->next; - } - } break; - - default: - break; - } - } - - // Initialize the `language_index` here since `__register_types()` makes use of it. - godot_instance_binding_functions binding_funcs = {}; - binding_funcs.alloc_instance_binding_data = wrapper_create; - binding_funcs.free_instance_binding_data = wrapper_destroy; - - godot::_RegisterState::language_index = godot::nativescript_1_1_api->godot_nativescript_register_instance_binding_data_functions(binding_funcs); - - // register these now - ___register_types(); - ___init_method_bindings(); -} - -void Godot::gdnative_terminate(godot_gdnative_terminate_options *options) { - // reserved for future use. -} - -void Godot::gdnative_profiling_add_data(const char *p_signature, uint64_t p_time) { - godot::nativescript_1_1_api->godot_nativescript_profiling_add_data(p_signature, p_time); -} - -void Godot::nativescript_init(void *handle) { - godot::_RegisterState::nativescript_handle = handle; -} - -void Godot::nativescript_terminate(void *handle) { - godot::nativescript_1_1_api->godot_nativescript_unregister_instance_binding_data_functions(godot::_RegisterState::language_index); -} - -} // namespace godot diff --git a/src/core/NodePath.cpp b/src/core/NodePath.cpp deleted file mode 100644 index ff65773..0000000 --- a/src/core/NodePath.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/*************************************************************************/ -/* NodePath.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "NodePath.hpp" -#include "GodotGlobal.hpp" -#include "String.hpp" - -#include <gdnative/node_path.h> - -namespace godot { - -NodePath::NodePath() { - String from = ""; - godot::api->godot_node_path_new(&_node_path, (godot_string *)&from); -} - -NodePath::NodePath(const NodePath &other) { - String from = other; - godot::api->godot_node_path_new(&_node_path, (godot_string *)&from); -} - -NodePath::NodePath(const String &from) { - godot::api->godot_node_path_new(&_node_path, (godot_string *)&from); -} - -NodePath::NodePath(const char *contents) { - String from = contents; - godot::api->godot_node_path_new(&_node_path, (godot_string *)&from); -} - -String NodePath::get_name(const int idx) const { - godot_string str = godot::api->godot_node_path_get_name(&_node_path, idx); - return String(str); -} - -int NodePath::get_name_count() const { - return godot::api->godot_node_path_get_name_count(&_node_path); -} - -String NodePath::get_subname(const int idx) const { - godot_string str = godot::api->godot_node_path_get_subname(&_node_path, idx); - return String(str); -} - -int NodePath::get_subname_count() const { - return godot::api->godot_node_path_get_subname_count(&_node_path); -} - -bool NodePath::is_absolute() const { - return godot::api->godot_node_path_is_absolute(&_node_path); -} - -bool NodePath::is_empty() const { - return godot::api->godot_node_path_is_empty(&_node_path); -} - -NodePath NodePath::get_as_property_path() const { - godot_node_path path = godot::core_1_1_api->godot_node_path_get_as_property_path(&_node_path); - return NodePath(path); -} -String NodePath::get_concatenated_subnames() const { - godot_string str = godot::api->godot_node_path_get_concatenated_subnames(&_node_path); - return String(str); -} - -NodePath::operator String() const { - godot_string str = godot::api->godot_node_path_as_string(&_node_path); - return String(str); -} - -bool NodePath::operator==(const NodePath &other) { - return godot::api->godot_node_path_operator_equal(&_node_path, &other._node_path); -} - -void NodePath::operator=(const NodePath &other) { - godot::api->godot_node_path_destroy(&_node_path); - - String other_string = (String)other; - - godot::api->godot_node_path_new(&_node_path, (godot_string *)&other_string); -} - -NodePath::~NodePath() { - godot::api->godot_node_path_destroy(&_node_path); -} - -} // namespace godot diff --git a/src/core/Plane.cpp b/src/core/Plane.cpp deleted file mode 100644 index fcf0012..0000000 --- a/src/core/Plane.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/*************************************************************************/ -/* Plane.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "Plane.hpp" -#include "Vector3.hpp" - -#include <cmath> - -namespace godot { - -void Plane::set_normal(const Vector3 &p_normal) { - this->normal = p_normal; -} - -Vector3 Plane::project(const Vector3 &p_point) const { - return p_point - normal * distance_to(p_point); -} - -void Plane::normalize() { - real_t l = normal.length(); - if (l == 0) { - *this = Plane(0, 0, 0, 0); - return; - } - normal /= l; - d /= l; -} - -Plane Plane::normalized() const { - Plane p = *this; - p.normalize(); - return p; -} - -Vector3 Plane::get_any_point() const { - return get_normal() * d; -} - -Vector3 Plane::get_any_perpendicular_normal() const { - static const Vector3 p1 = Vector3(1, 0, 0); - static const Vector3 p2 = Vector3(0, 1, 0); - Vector3 p; - - if (::fabs(normal.dot(p1)) > 0.99) // if too similar to p1 - p = p2; // use p2 - else - p = p1; // use p1 - - p -= normal * normal.dot(p); - p.normalize(); - - return p; -} - -/* intersections */ - -bool Plane::intersect_3(const Plane &p_plane1, const Plane &p_plane2, Vector3 *r_result) const { - const Plane &p_plane0 = *this; - Vector3 normal0 = p_plane0.normal; - Vector3 normal1 = p_plane1.normal; - Vector3 normal2 = p_plane2.normal; - - real_t denom = vec3_cross(normal0, normal1).dot(normal2); - - if (::fabs(denom) <= CMP_EPSILON) - return false; - - if (r_result) { - *r_result = ((vec3_cross(normal1, normal2) * p_plane0.d) + - (vec3_cross(normal2, normal0) * p_plane1.d) + - (vec3_cross(normal0, normal1) * p_plane2.d)) / - denom; - } - - return true; -} - -bool Plane::intersects_ray(Vector3 p_from, Vector3 p_dir, Vector3 *p_intersection) const { - Vector3 segment = p_dir; - real_t den = normal.dot(segment); - - //printf("den is %i\n",den); - if (::fabs(den) <= CMP_EPSILON) { - return false; - } - - real_t dist = (normal.dot(p_from) - d) / den; - //printf("dist is %i\n",dist); - - if (dist > CMP_EPSILON) { //this is a ray, before the emiting pos (p_from) doesnt exist - - return false; - } - - dist = -dist; - *p_intersection = p_from + segment * dist; - - return true; -} - -bool Plane::intersects_segment(Vector3 p_begin, Vector3 p_end, Vector3 *p_intersection) const { - Vector3 segment = p_begin - p_end; - real_t den = normal.dot(segment); - - //printf("den is %i\n",den); - if (::fabs(den) <= CMP_EPSILON) { - return false; - } - - real_t dist = (normal.dot(p_begin) - d) / den; - //printf("dist is %i\n",dist); - - if (dist < -CMP_EPSILON || dist > (1.0 + CMP_EPSILON)) { - return false; - } - - dist = -dist; - *p_intersection = p_begin + segment * dist; - - return true; -} - -/* misc */ - -bool Plane::is_almost_like(const Plane &p_plane) const { - return (normal.dot(p_plane.normal) > _PLANE_EQ_DOT_EPSILON && ::fabs(d - p_plane.d) < _PLANE_EQ_D_EPSILON); -} - -Plane::operator String() const { - // return normal.operator String() + ", " + rtos(d); - return String(); // @Todo -} - -bool Plane::is_point_over(const Vector3 &p_point) const { - return (normal.dot(p_point) > d); -} - -real_t Plane::distance_to(const Vector3 &p_point) const { - return (normal.dot(p_point) - d); -} - -bool Plane::has_point(const Vector3 &p_point, real_t _epsilon) const { - real_t dist = normal.dot(p_point) - d; - dist = ::fabs(dist); - return (dist <= _epsilon); -} - -Plane::Plane(const Vector3 &p_normal, real_t p_d) { - normal = p_normal; - d = p_d; -} - -Plane::Plane(const Vector3 &p_point, const Vector3 &p_normal) { - normal = p_normal; - d = p_normal.dot(p_point); -} - -Plane::Plane(const Vector3 &p_point1, const Vector3 &p_point2, const Vector3 &p_point3, ClockDirection p_dir) { - if (p_dir == CLOCKWISE) - normal = (p_point1 - p_point3).cross(p_point1 - p_point2); - else - normal = (p_point1 - p_point2).cross(p_point1 - p_point3); - - normal.normalize(); - d = normal.dot(p_point1); -} - -bool Plane::operator==(const Plane &p_plane) const { - return normal == p_plane.normal && d == p_plane.d; -} - -bool Plane::operator!=(const Plane &p_plane) const { - return normal != p_plane.normal || d != p_plane.d; -} - -} // namespace godot diff --git a/src/core/PoolArrays.cpp b/src/core/PoolArrays.cpp deleted file mode 100644 index 576a0b7..0000000 --- a/src/core/PoolArrays.cpp +++ /dev/null @@ -1,571 +0,0 @@ -/*************************************************************************/ -/* PoolArrays.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "PoolArrays.hpp" -#include "Color.hpp" -#include "Defs.hpp" -#include "GodotGlobal.hpp" -#include "String.hpp" -#include "Vector2.hpp" -#include "Vector3.hpp" - -#include <gdnative/pool_arrays.h> - -namespace godot { - -PoolByteArray::PoolByteArray() { - godot::api->godot_pool_byte_array_new(&_godot_array); -} - -PoolByteArray::PoolByteArray(const PoolByteArray &p_other) { - godot::api->godot_pool_byte_array_new_copy(&_godot_array, &p_other._godot_array); -} - -PoolByteArray &PoolByteArray::operator=(const PoolByteArray &p_other) { - godot::api->godot_pool_byte_array_destroy(&_godot_array); - godot::api->godot_pool_byte_array_new_copy(&_godot_array, &p_other._godot_array); - return *this; -} - -PoolByteArray::PoolByteArray(const Array &array) { - godot::api->godot_pool_byte_array_new_with_array(&_godot_array, (godot_array *)&array); -} - -PoolByteArray::Read PoolByteArray::read() const { - Read read; - read._read_access = godot::api->godot_pool_byte_array_read(&_godot_array); - return read; -} - -PoolByteArray::Write PoolByteArray::write() { - Write write; - write._write_access = godot::api->godot_pool_byte_array_write(&_godot_array); - return write; -} - -void PoolByteArray::append(const uint8_t data) { - godot::api->godot_pool_byte_array_append(&_godot_array, data); -} - -void PoolByteArray::append_array(const PoolByteArray &array) { - godot::api->godot_pool_byte_array_append_array(&_godot_array, &array._godot_array); -} - -int PoolByteArray::insert(const int idx, const uint8_t data) { - return godot::api->godot_pool_byte_array_insert(&_godot_array, idx, data); -} - -void PoolByteArray::invert() { - godot::api->godot_pool_byte_array_invert(&_godot_array); -} - -void PoolByteArray::push_back(const uint8_t data) { - godot::api->godot_pool_byte_array_push_back(&_godot_array, data); -} - -void PoolByteArray::remove(const int idx) { - godot::api->godot_pool_byte_array_remove(&_godot_array, idx); -} - -void PoolByteArray::resize(const int size) { - godot::api->godot_pool_byte_array_resize(&_godot_array, size); -} - -void PoolByteArray::set(const int idx, const uint8_t data) { - godot::api->godot_pool_byte_array_set(&_godot_array, idx, data); -} - -uint8_t PoolByteArray::operator[](const int idx) { - return godot::api->godot_pool_byte_array_get(&_godot_array, idx); -} - -int PoolByteArray::size() const { - return godot::api->godot_pool_byte_array_size(&_godot_array); -} - -PoolByteArray::~PoolByteArray() { - godot::api->godot_pool_byte_array_destroy(&_godot_array); -} - -PoolIntArray::PoolIntArray() { - godot::api->godot_pool_int_array_new(&_godot_array); -} - -PoolIntArray::PoolIntArray(const PoolIntArray &p_other) { - godot::api->godot_pool_int_array_new_copy(&_godot_array, &p_other._godot_array); -} - -PoolIntArray &PoolIntArray::operator=(const PoolIntArray &p_other) { - godot::api->godot_pool_int_array_destroy(&_godot_array); - godot::api->godot_pool_int_array_new_copy(&_godot_array, &p_other._godot_array); - return *this; -} - -PoolIntArray::PoolIntArray(const Array &array) { - godot::api->godot_pool_int_array_new_with_array(&_godot_array, (godot_array *)&array); -} - -PoolIntArray::Read PoolIntArray::read() const { - Read read; - read._read_access = godot::api->godot_pool_int_array_read(&_godot_array); - return read; -} - -PoolIntArray::Write PoolIntArray::write() { - Write write; - write._write_access = godot::api->godot_pool_int_array_write(&_godot_array); - return write; -} - -void PoolIntArray::append(const int data) { - godot::api->godot_pool_int_array_append(&_godot_array, data); -} - -void PoolIntArray::append_array(const PoolIntArray &array) { - godot::api->godot_pool_int_array_append_array(&_godot_array, &array._godot_array); -} - -int PoolIntArray::insert(const int idx, const int data) { - return godot::api->godot_pool_int_array_insert(&_godot_array, idx, data); -} - -void PoolIntArray::invert() { - godot::api->godot_pool_int_array_invert(&_godot_array); -} - -void PoolIntArray::push_back(const int data) { - godot::api->godot_pool_int_array_push_back(&_godot_array, data); -} - -void PoolIntArray::remove(const int idx) { - godot::api->godot_pool_int_array_remove(&_godot_array, idx); -} - -void PoolIntArray::resize(const int size) { - godot::api->godot_pool_int_array_resize(&_godot_array, size); -} - -void PoolIntArray::set(const int idx, const int data) { - godot::api->godot_pool_int_array_set(&_godot_array, idx, data); -} - -int PoolIntArray::operator[](const int idx) { - return godot::api->godot_pool_int_array_get(&_godot_array, idx); -} - -int PoolIntArray::size() const { - return godot::api->godot_pool_int_array_size(&_godot_array); -} - -PoolIntArray::~PoolIntArray() { - godot::api->godot_pool_int_array_destroy(&_godot_array); -} - -PoolRealArray::PoolRealArray() { - godot::api->godot_pool_real_array_new(&_godot_array); -} - -PoolRealArray::PoolRealArray(const PoolRealArray &p_other) { - godot::api->godot_pool_real_array_new_copy(&_godot_array, &p_other._godot_array); -} - -PoolRealArray &PoolRealArray::operator=(const PoolRealArray &p_other) { - godot::api->godot_pool_real_array_destroy(&_godot_array); - godot::api->godot_pool_real_array_new_copy(&_godot_array, &p_other._godot_array); - return *this; -} - -PoolRealArray::Read PoolRealArray::read() const { - Read read; - read._read_access = godot::api->godot_pool_real_array_read(&_godot_array); - return read; -} - -PoolRealArray::Write PoolRealArray::write() { - Write write; - write._write_access = godot::api->godot_pool_real_array_write(&_godot_array); - return write; -} - -PoolRealArray::PoolRealArray(const Array &array) { - godot::api->godot_pool_real_array_new_with_array(&_godot_array, (godot_array *)&array); -} - -void PoolRealArray::append(const real_t data) { - godot::api->godot_pool_real_array_append(&_godot_array, data); -} - -void PoolRealArray::append_array(const PoolRealArray &array) { - godot::api->godot_pool_real_array_append_array(&_godot_array, &array._godot_array); -} - -int PoolRealArray::insert(const int idx, const real_t data) { - return godot::api->godot_pool_real_array_insert(&_godot_array, idx, data); -} - -void PoolRealArray::invert() { - godot::api->godot_pool_real_array_invert(&_godot_array); -} - -void PoolRealArray::push_back(const real_t data) { - godot::api->godot_pool_real_array_push_back(&_godot_array, data); -} - -void PoolRealArray::remove(const int idx) { - godot::api->godot_pool_real_array_remove(&_godot_array, idx); -} - -void PoolRealArray::resize(const int size) { - godot::api->godot_pool_real_array_resize(&_godot_array, size); -} - -void PoolRealArray::set(const int idx, const real_t data) { - godot::api->godot_pool_real_array_set(&_godot_array, idx, data); -} - -real_t PoolRealArray::operator[](const int idx) { - return godot::api->godot_pool_real_array_get(&_godot_array, idx); -} - -int PoolRealArray::size() const { - return godot::api->godot_pool_real_array_size(&_godot_array); -} - -PoolRealArray::~PoolRealArray() { - godot::api->godot_pool_real_array_destroy(&_godot_array); -} - -PoolStringArray::PoolStringArray() { - godot::api->godot_pool_string_array_new(&_godot_array); -} - -PoolStringArray::PoolStringArray(const PoolStringArray &p_other) { - godot::api->godot_pool_string_array_new_copy(&_godot_array, &p_other._godot_array); -} - -PoolStringArray &PoolStringArray::operator=(const PoolStringArray &p_other) { - godot::api->godot_pool_string_array_destroy(&_godot_array); - godot::api->godot_pool_string_array_new_copy(&_godot_array, &p_other._godot_array); - return *this; -} - -PoolStringArray::PoolStringArray(const Array &array) { - godot::api->godot_pool_string_array_new_with_array(&_godot_array, (godot_array *)&array); -} - -PoolStringArray::Read PoolStringArray::read() const { - Read read; - read._read_access = godot::api->godot_pool_string_array_read(&_godot_array); - return read; -} - -PoolStringArray::Write PoolStringArray::write() { - Write write; - write._write_access = godot::api->godot_pool_string_array_write(&_godot_array); - return write; -} - -void PoolStringArray::append(const String &data) { - godot::api->godot_pool_string_array_append(&_godot_array, (godot_string *)&data); -} - -void PoolStringArray::append_array(const PoolStringArray &array) { - godot::api->godot_pool_string_array_append_array(&_godot_array, &array._godot_array); -} - -int PoolStringArray::insert(const int idx, const String &data) { - return godot::api->godot_pool_string_array_insert(&_godot_array, idx, (godot_string *)&data); -} - -void PoolStringArray::invert() { - godot::api->godot_pool_string_array_invert(&_godot_array); -} - -void PoolStringArray::push_back(const String &data) { - godot::api->godot_pool_string_array_push_back(&_godot_array, (godot_string *)&data); -} - -void PoolStringArray::remove(const int idx) { - godot::api->godot_pool_string_array_remove(&_godot_array, idx); -} - -void PoolStringArray::resize(const int size) { - godot::api->godot_pool_string_array_resize(&_godot_array, size); -} - -void PoolStringArray::set(const int idx, const String &data) { - godot::api->godot_pool_string_array_set(&_godot_array, idx, (godot_string *)&data); -} - -const String PoolStringArray::operator[](const int idx) { - String s; - godot_string str = godot::api->godot_pool_string_array_get(&_godot_array, idx); - godot::api->godot_string_new_copy((godot_string *)&s, &str); - godot::api->godot_string_destroy(&str); - return s; -} - -int PoolStringArray::size() const { - return godot::api->godot_pool_string_array_size(&_godot_array); -} - -PoolStringArray::~PoolStringArray() { - godot::api->godot_pool_string_array_destroy(&_godot_array); -} - -PoolVector2Array::PoolVector2Array() { - godot::api->godot_pool_vector2_array_new(&_godot_array); -} - -PoolVector2Array::PoolVector2Array(const PoolVector2Array &p_other) { - godot::api->godot_pool_vector2_array_new_copy(&_godot_array, &p_other._godot_array); -} - -PoolVector2Array &PoolVector2Array::operator=(const PoolVector2Array &p_other) { - godot::api->godot_pool_vector2_array_destroy(&_godot_array); - godot::api->godot_pool_vector2_array_new_copy(&_godot_array, &p_other._godot_array); - return *this; -} - -PoolVector2Array::PoolVector2Array(const Array &array) { - godot::api->godot_pool_vector2_array_new_with_array(&_godot_array, (godot_array *)&array); -} - -PoolVector2Array::Read PoolVector2Array::read() const { - Read read; - read._read_access = godot::api->godot_pool_vector2_array_read(&_godot_array); - return read; -} - -PoolVector2Array::Write PoolVector2Array::write() { - Write write; - write._write_access = godot::api->godot_pool_vector2_array_write(&_godot_array); - return write; -} - -void PoolVector2Array::append(const Vector2 &data) { - godot::api->godot_pool_vector2_array_append(&_godot_array, (godot_vector2 *)&data); -} - -void PoolVector2Array::append_array(const PoolVector2Array &array) { - godot::api->godot_pool_vector2_array_append_array(&_godot_array, &array._godot_array); -} - -int PoolVector2Array::insert(const int idx, const Vector2 &data) { - return godot::api->godot_pool_vector2_array_insert(&_godot_array, idx, (godot_vector2 *)&data); -} - -void PoolVector2Array::invert() { - godot::api->godot_pool_vector2_array_invert(&_godot_array); -} - -void PoolVector2Array::push_back(const Vector2 &data) { - godot::api->godot_pool_vector2_array_push_back(&_godot_array, (godot_vector2 *)&data); -} - -void PoolVector2Array::remove(const int idx) { - godot::api->godot_pool_vector2_array_remove(&_godot_array, idx); -} - -void PoolVector2Array::resize(const int size) { - godot::api->godot_pool_vector2_array_resize(&_godot_array, size); -} - -void PoolVector2Array::set(const int idx, const Vector2 &data) { - godot::api->godot_pool_vector2_array_set(&_godot_array, idx, (godot_vector2 *)&data); -} - -const Vector2 PoolVector2Array::operator[](const int idx) { - Vector2 v; - *(godot_vector2 *)&v = godot::api->godot_pool_vector2_array_get(&_godot_array, idx); - return v; -} - -int PoolVector2Array::size() const { - return godot::api->godot_pool_vector2_array_size(&_godot_array); -} - -PoolVector2Array::~PoolVector2Array() { - godot::api->godot_pool_vector2_array_destroy(&_godot_array); -} - -PoolVector3Array::PoolVector3Array() { - godot::api->godot_pool_vector3_array_new(&_godot_array); -} - -PoolVector3Array::PoolVector3Array(const PoolVector3Array &p_other) { - godot::api->godot_pool_vector3_array_new_copy(&_godot_array, &p_other._godot_array); -} - -PoolVector3Array &PoolVector3Array::operator=(const PoolVector3Array &p_other) { - godot::api->godot_pool_vector3_array_destroy(&_godot_array); - godot::api->godot_pool_vector3_array_new_copy(&_godot_array, &p_other._godot_array); - return *this; -} - -PoolVector3Array::PoolVector3Array(const Array &array) { - godot::api->godot_pool_vector3_array_new_with_array(&_godot_array, (godot_array *)&array); -} - -PoolVector3Array::Read PoolVector3Array::read() const { - Read read; - read._read_access = godot::api->godot_pool_vector3_array_read(&_godot_array); - return read; -} - -PoolVector3Array::Write PoolVector3Array::write() { - Write write; - write._write_access = godot::api->godot_pool_vector3_array_write(&_godot_array); - return write; -} - -void PoolVector3Array::append(const Vector3 &data) { - godot::api->godot_pool_vector3_array_append(&_godot_array, (godot_vector3 *)&data); -} - -void PoolVector3Array::append_array(const PoolVector3Array &array) { - godot::api->godot_pool_vector3_array_append_array(&_godot_array, &array._godot_array); -} - -int PoolVector3Array::insert(const int idx, const Vector3 &data) { - return godot::api->godot_pool_vector3_array_insert(&_godot_array, idx, (godot_vector3 *)&data); -} - -void PoolVector3Array::invert() { - godot::api->godot_pool_vector3_array_invert(&_godot_array); -} - -void PoolVector3Array::push_back(const Vector3 &data) { - godot::api->godot_pool_vector3_array_push_back(&_godot_array, (godot_vector3 *)&data); -} - -void PoolVector3Array::remove(const int idx) { - godot::api->godot_pool_vector3_array_remove(&_godot_array, idx); -} - -void PoolVector3Array::resize(const int size) { - godot::api->godot_pool_vector3_array_resize(&_godot_array, size); -} - -void PoolVector3Array::set(const int idx, const Vector3 &data) { - godot::api->godot_pool_vector3_array_set(&_godot_array, idx, (godot_vector3 *)&data); -} - -const Vector3 PoolVector3Array::operator[](const int idx) { - Vector3 v; - *(godot_vector3 *)&v = godot::api->godot_pool_vector3_array_get(&_godot_array, idx); - return v; -} - -int PoolVector3Array::size() const { - return godot::api->godot_pool_vector3_array_size(&_godot_array); -} - -PoolVector3Array::~PoolVector3Array() { - godot::api->godot_pool_vector3_array_destroy(&_godot_array); -} - -PoolColorArray::PoolColorArray() { - godot::api->godot_pool_color_array_new(&_godot_array); -} - -PoolColorArray::PoolColorArray(const PoolColorArray &p_other) { - godot::api->godot_pool_color_array_new_copy(&_godot_array, &p_other._godot_array); -} - -PoolColorArray &PoolColorArray::operator=(const PoolColorArray &p_other) { - godot::api->godot_pool_color_array_destroy(&_godot_array); - godot::api->godot_pool_color_array_new_copy(&_godot_array, &p_other._godot_array); - return *this; -} - -PoolColorArray::PoolColorArray(const Array &array) { - godot::api->godot_pool_color_array_new_with_array(&_godot_array, (godot_array *)&array); -} - -PoolColorArray::Read PoolColorArray::read() const { - Read read; - read._read_access = godot::api->godot_pool_color_array_read(&_godot_array); - return read; -} - -PoolColorArray::Write PoolColorArray::write() { - Write write; - write._write_access = godot::api->godot_pool_color_array_write(&_godot_array); - return write; -} - -void PoolColorArray::append(const Color &data) { - godot::api->godot_pool_color_array_append(&_godot_array, (godot_color *)&data); -} - -void PoolColorArray::append_array(const PoolColorArray &array) { - godot::api->godot_pool_color_array_append_array(&_godot_array, &array._godot_array); -} - -int PoolColorArray::insert(const int idx, const Color &data) { - return godot::api->godot_pool_color_array_insert(&_godot_array, idx, (godot_color *)&data); -} - -void PoolColorArray::invert() { - godot::api->godot_pool_color_array_invert(&_godot_array); -} - -void PoolColorArray::push_back(const Color &data) { - godot::api->godot_pool_color_array_push_back(&_godot_array, (godot_color *)&data); -} - -void PoolColorArray::remove(const int idx) { - godot::api->godot_pool_color_array_remove(&_godot_array, idx); -} - -void PoolColorArray::resize(const int size) { - godot::api->godot_pool_color_array_resize(&_godot_array, size); -} - -void PoolColorArray::set(const int idx, const Color &data) { - godot::api->godot_pool_color_array_set(&_godot_array, idx, (godot_color *)&data); -} - -const Color PoolColorArray::operator[](const int idx) { - Color v; - *(godot_color *)&v = godot::api->godot_pool_color_array_get(&_godot_array, idx); - return v; -} - -int PoolColorArray::size() const { - return godot::api->godot_pool_color_array_size(&_godot_array); -} - -PoolColorArray::~PoolColorArray() { - godot::api->godot_pool_color_array_destroy(&_godot_array); -} - -} // namespace godot diff --git a/src/core/Quat.cpp b/src/core/Quat.cpp deleted file mode 100644 index 40d23e9..0000000 --- a/src/core/Quat.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/*************************************************************************/ -/* Quat.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "Quat.hpp" -#include "Basis.hpp" -#include "Defs.hpp" -#include "Vector3.hpp" - -#include <cmath> - -namespace godot { - -const Quat Quat::IDENTITY = Quat(); - -// set_euler_xyz expects a vector containing the Euler angles in the format -// (ax,ay,az), where ax is the angle of rotation around x axis, -// and similar for other axes. -// This implementation uses XYZ convention (Z is the first rotation). -void Quat::set_euler_xyz(const Vector3 &p_euler) { - real_t half_a1 = p_euler.x * 0.5; - real_t half_a2 = p_euler.y * 0.5; - real_t half_a3 = p_euler.z * 0.5; - - // R = X(a1).Y(a2).Z(a3) convention for Euler angles. - // Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-2) - // a3 is the angle of the first rotation, following the notation in this reference. - - real_t cos_a1 = ::cos(half_a1); - real_t sin_a1 = ::sin(half_a1); - real_t cos_a2 = ::cos(half_a2); - real_t sin_a2 = ::sin(half_a2); - real_t cos_a3 = ::cos(half_a3); - real_t sin_a3 = ::sin(half_a3); - - set(sin_a1 * cos_a2 * cos_a3 + sin_a2 * sin_a3 * cos_a1, - -sin_a1 * sin_a3 * cos_a2 + sin_a2 * cos_a1 * cos_a3, - sin_a1 * sin_a2 * cos_a3 + sin_a3 * cos_a1 * cos_a2, - -sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3); -} - -// get_euler_xyz returns a vector containing the Euler angles in the format -// (ax,ay,az), where ax is the angle of rotation around x axis, -// and similar for other axes. -// This implementation uses XYZ convention (Z is the first rotation). -Vector3 Quat::get_euler_xyz() const { - Basis m(*this); - return m.get_euler_xyz(); -} - -// set_euler_yxz expects a vector containing the Euler angles in the format -// (ax,ay,az), where ax is the angle of rotation around x axis, -// and similar for other axes. -// This implementation uses YXZ convention (Z is the first rotation). -void Quat::set_euler_yxz(const Vector3 &p_euler) { - real_t half_a1 = p_euler.y * 0.5; - real_t half_a2 = p_euler.x * 0.5; - real_t half_a3 = p_euler.z * 0.5; - - // R = Y(a1).X(a2).Z(a3) convention for Euler angles. - // Conversion to quaternion as listed in https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19770024290.pdf (page A-6) - // a3 is the angle of the first rotation, following the notation in this reference. - - real_t cos_a1 = ::cos(half_a1); - real_t sin_a1 = ::sin(half_a1); - real_t cos_a2 = ::cos(half_a2); - real_t sin_a2 = ::sin(half_a2); - real_t cos_a3 = ::cos(half_a3); - real_t sin_a3 = ::sin(half_a3); - - set(sin_a1 * cos_a2 * sin_a3 + cos_a1 * sin_a2 * cos_a3, - sin_a1 * cos_a2 * cos_a3 - cos_a1 * sin_a2 * sin_a3, - -sin_a1 * sin_a2 * cos_a3 + cos_a1 * sin_a2 * sin_a3, - sin_a1 * sin_a2 * sin_a3 + cos_a1 * cos_a2 * cos_a3); -} - -// get_euler_yxz returns a vector containing the Euler angles in the format -// (ax,ay,az), where ax is the angle of rotation around x axis, -// and similar for other axes. -// This implementation uses YXZ convention (Z is the first rotation). -Vector3 Quat::get_euler_yxz() const { - Basis m(*this); - return m.get_euler_yxz(); -} - -real_t Quat::length() const { - return ::sqrt(length_squared()); -} - -void Quat::normalize() { - *this /= length(); -} - -Quat Quat::normalized() const { - return *this / length(); -} - -bool Quat::is_normalized() const { - return std::abs(length_squared() - 1.0) < 0.00001; -} - -Quat Quat::inverse() const { - return Quat(-x, -y, -z, w); -} - -Quat Quat::slerp(const Quat &q, const real_t &t) const { - Quat to1; - real_t omega, cosom, sinom, scale0, scale1; - - // calc cosine - cosom = dot(q); - - // adjust signs (if necessary) - if (cosom < 0.0) { - cosom = -cosom; - to1.x = -q.x; - to1.y = -q.y; - to1.z = -q.z; - to1.w = -q.w; - } else { - to1.x = q.x; - to1.y = q.y; - to1.z = q.z; - to1.w = q.w; - } - - // calculate coefficients - - if ((1.0 - cosom) > CMP_EPSILON) { - // standard case (slerp) - omega = ::acos(cosom); - sinom = ::sin(omega); - scale0 = ::sin((1.0 - t) * omega) / sinom; - scale1 = ::sin(t * omega) / sinom; - } else { - // "from" and "to" quaternions are very close - // ... so we can do a linear interpolation - scale0 = 1.0 - t; - scale1 = t; - } - // calculate final values - return Quat( - scale0 * x + scale1 * to1.x, - scale0 * y + scale1 * to1.y, - scale0 * z + scale1 * to1.z, - scale0 * w + scale1 * to1.w); -} - -Quat Quat::slerpni(const Quat &q, const real_t &t) const { - const Quat &from = *this; - - real_t dot = from.dot(q); - - if (::fabs(dot) > 0.9999) - return from; - - real_t theta = ::acos(dot), - sinT = 1.0 / ::sin(theta), - newFactor = ::sin(t * theta) * sinT, - invFactor = ::sin((1.0 - t) * theta) * sinT; - - return Quat(invFactor * from.x + newFactor * q.x, - invFactor * from.y + newFactor * q.y, - invFactor * from.z + newFactor * q.z, - invFactor * from.w + newFactor * q.w); -} - -Quat Quat::cubic_slerp(const Quat &q, const Quat &prep, const Quat &postq, const real_t &t) const { - //the only way to do slerp :| - real_t t2 = (1.0 - t) * t * 2; - Quat sp = this->slerp(q, t); - Quat sq = prep.slerpni(postq, t); - return sp.slerpni(sq, t2); -} - -void Quat::get_axis_and_angle(Vector3 &r_axis, real_t &r_angle) const { - r_angle = 2 * ::acos(w); - r_axis.x = x / ::sqrt(1 - w * w); - r_axis.y = y / ::sqrt(1 - w * w); - r_axis.z = z / ::sqrt(1 - w * w); -} - -void Quat::set_axis_angle(const Vector3 &axis, const float angle) { - ERR_FAIL_COND(!axis.is_normalized()); - - real_t d = axis.length(); - if (d == 0) - set(0, 0, 0, 0); - else { - real_t sin_angle = ::sin(angle * 0.5); - real_t cos_angle = ::cos(angle * 0.5); - real_t s = sin_angle / d; - set(axis.x * s, axis.y * s, axis.z * s, - cos_angle); - } -} - -Quat Quat::operator*(const Vector3 &v) const { - return Quat(w * v.x + y * v.z - z * v.y, - w * v.y + z * v.x - x * v.z, - w * v.z + x * v.y - y * v.x, - -x * v.x - y * v.y - z * v.z); -} - -Vector3 Quat::xform(const Vector3 &v) const { - Quat q = *this * v; - q *= this->inverse(); - return Vector3(q.x, q.y, q.z); -} - -Quat::operator String() const { - return String(); // @Todo -} - -Quat::Quat(const Vector3 &axis, const real_t &angle) { - real_t d = axis.length(); - if (d == 0) - set(0, 0, 0, 0); - else { - real_t sin_angle = ::sin(angle * 0.5); - real_t cos_angle = ::cos(angle * 0.5); - real_t s = sin_angle / d; - set(axis.x * s, axis.y * s, axis.z * s, - cos_angle); - } -} - -Quat::Quat(const Vector3 &v0, const Vector3 &v1) // shortest arc -{ - Vector3 c = v0.cross(v1); - real_t d = v0.dot(v1); - - if (d < -1.0 + CMP_EPSILON) { - x = 0; - y = 1; - z = 0; - w = 0; - } else { - real_t s = ::sqrt((1.0 + d) * 2.0); - real_t rs = 1.0 / s; - - x = c.x * rs; - y = c.y * rs; - z = c.z * rs; - w = s * 0.5; - } -} - -real_t Quat::dot(const Quat &q) const { - return x * q.x + y * q.y + z * q.z + w * q.w; -} - -real_t Quat::length_squared() const { - return dot(*this); -} - -void Quat::operator+=(const Quat &q) { - x += q.x; - y += q.y; - z += q.z; - w += q.w; -} - -void Quat::operator-=(const Quat &q) { - x -= q.x; - y -= q.y; - z -= q.z; - w -= q.w; -} - -void Quat::operator*=(const Quat &q) { - set(w * q.x + x * q.w + y * q.z - z * q.y, - w * q.y + y * q.w + z * q.x - x * q.z, - w * q.z + z * q.w + x * q.y - y * q.x, - w * q.w - x * q.x - y * q.y - z * q.z); -} - -void Quat::operator*=(const real_t &s) { - x *= s; - y *= s; - z *= s; - w *= s; -} - -void Quat::operator/=(const real_t &s) { - *this *= 1.0 / s; -} - -Quat Quat::operator+(const Quat &q2) const { - const Quat &q1 = *this; - return Quat(q1.x + q2.x, q1.y + q2.y, q1.z + q2.z, q1.w + q2.w); -} - -Quat Quat::operator-(const Quat &q2) const { - const Quat &q1 = *this; - return Quat(q1.x - q2.x, q1.y - q2.y, q1.z - q2.z, q1.w - q2.w); -} - -Quat Quat::operator*(const Quat &q2) const { - Quat q1 = *this; - q1 *= q2; - return q1; -} - -Quat Quat::operator-() const { - const Quat &q2 = *this; - return Quat(-q2.x, -q2.y, -q2.z, -q2.w); -} - -Quat Quat::operator*(const real_t &s) const { - return Quat(x * s, y * s, z * s, w * s); -} - -Quat Quat::operator/(const real_t &s) const { - return *this * (1.0 / s); -} - -bool Quat::operator==(const Quat &p_quat) const { - return x == p_quat.x && y == p_quat.y && z == p_quat.z && w == p_quat.w; -} - -bool Quat::operator!=(const Quat &p_quat) const { - return x != p_quat.x || y != p_quat.y || z != p_quat.z || w != p_quat.w; -} - -} // namespace godot diff --git a/src/core/Rect2.cpp b/src/core/Rect2.cpp deleted file mode 100644 index ab21e5c..0000000 --- a/src/core/Rect2.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/*************************************************************************/ -/* Rect2.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "Rect2.hpp" -#include "String.hpp" -#include "Transform2D.hpp" -#include "Vector2.hpp" - -#include <cmath> - -namespace godot { - -#ifndef MAX -#define MAX(a, b) (a > b ? a : b) -#endif - -#ifndef MIN -#define MIN(a, b) (a < b ? a : b) -#endif - -real_t Rect2::distance_to(const Vector2 &p_point) const { - real_t dist = 1e20; - - if (p_point.x < position.x) { - dist = MIN(dist, position.x - p_point.x); - } - if (p_point.y < position.y) { - dist = MIN(dist, position.y - p_point.y); - } - if (p_point.x >= (position.x + size.x)) { - dist = MIN(p_point.x - (position.x + size.x), dist); - } - if (p_point.y >= (position.y + size.y)) { - dist = MIN(p_point.y - (position.y + size.y), dist); - } - - if (dist == 1e20) - return 0; - else - return dist; -} - -Rect2 Rect2::clip(const Rect2 &p_rect) const { /// return a clipped rect - - Rect2 new_rect = p_rect; - - if (!intersects(new_rect)) - return Rect2(); - - new_rect.position.x = MAX(p_rect.position.x, position.x); - new_rect.position.y = MAX(p_rect.position.y, position.y); - - Point2 p_rect_end = p_rect.position + p_rect.size; - Point2 end = position + size; - - new_rect.size.x = MIN(p_rect_end.x, end.x) - new_rect.position.x; - new_rect.size.y = MIN(p_rect_end.y, end.y) - new_rect.position.y; - - return new_rect; -} - -Rect2 Rect2::merge(const Rect2 &p_rect) const { ///< return a merged rect - - Rect2 new_rect; - - new_rect.position.x = MIN(p_rect.position.x, position.x); - new_rect.position.y = MIN(p_rect.position.y, position.y); - - new_rect.size.x = MAX(p_rect.position.x + p_rect.size.x, position.x + size.x); - new_rect.size.y = MAX(p_rect.position.y + p_rect.size.y, position.y + size.y); - - new_rect.size = new_rect.size - new_rect.position; //make relative again - - return new_rect; -} - -Rect2::operator String() const { - return String(position) + ", " + String(size); -} - -bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_position, Point2 *r_normal) const { - real_t min = 0, max = 1; - int axis = 0; - real_t sign = 0; - - for (int i = 0; i < 2; i++) { - real_t seg_from = p_from[i]; - real_t seg_to = p_to[i]; - real_t box_begin = position[i]; - real_t box_end = box_begin + size[i]; - real_t cmin, cmax; - real_t csign; - - if (seg_from < seg_to) { - if (seg_from > box_end || seg_to < box_begin) - return false; - real_t length = seg_to - seg_from; - cmin = (seg_from < box_begin) ? ((box_begin - seg_from) / length) : 0; - cmax = (seg_to > box_end) ? ((box_end - seg_from) / length) : 1; - csign = -1.0; - - } else { - if (seg_to > box_end || seg_from < box_begin) - return false; - real_t length = seg_to - seg_from; - cmin = (seg_from > box_end) ? (box_end - seg_from) / length : 0; - cmax = (seg_to < box_begin) ? (box_begin - seg_from) / length : 1; - csign = 1.0; - } - - if (cmin > min) { - min = cmin; - axis = i; - sign = csign; - } - if (cmax < max) - max = cmax; - if (max < min) - return false; - } - - Vector2 rel = p_to - p_from; - - if (r_normal) { - Vector2 normal; - normal[axis] = sign; - *r_normal = normal; - } - - if (r_position) - *r_position = p_from + rel * min; - - return true; -} - -bool Rect2::intersects_transformed(const Transform2D &p_xform, const Rect2 &p_rect) const { - //SAT intersection between local and transformed rect2 - - Vector2 xf_points[4] = { - p_xform.xform(p_rect.position), - p_xform.xform(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y)), - p_xform.xform(Vector2(p_rect.position.x, p_rect.position.y + p_rect.size.y)), - p_xform.xform(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y + p_rect.size.y)), - }; - - real_t low_limit; - - //base rect2 first (faster) - - if (xf_points[0].y > position.y) - goto next1; - if (xf_points[1].y > position.y) - goto next1; - if (xf_points[2].y > position.y) - goto next1; - if (xf_points[3].y > position.y) - goto next1; - - return false; - -next1: - - low_limit = position.y + size.y; - - if (xf_points[0].y < low_limit) - goto next2; - if (xf_points[1].y < low_limit) - goto next2; - if (xf_points[2].y < low_limit) - goto next2; - if (xf_points[3].y < low_limit) - goto next2; - - return false; - -next2: - - if (xf_points[0].x > position.x) - goto next3; - if (xf_points[1].x > position.x) - goto next3; - if (xf_points[2].x > position.x) - goto next3; - if (xf_points[3].x > position.x) - goto next3; - - return false; - -next3: - - low_limit = position.x + size.x; - - if (xf_points[0].x < low_limit) - goto next4; - if (xf_points[1].x < low_limit) - goto next4; - if (xf_points[2].x < low_limit) - goto next4; - if (xf_points[3].x < low_limit) - goto next4; - - return false; - -next4: - - Vector2 xf_points2[4] = { - position, - Vector2(position.x + size.x, position.y), - Vector2(position.x, position.y + size.y), - Vector2(position.x + size.x, position.y + size.y), - }; - - real_t maxa = p_xform.elements[0].dot(xf_points2[0]); - real_t mina = maxa; - - real_t dp = p_xform.elements[0].dot(xf_points2[1]); - maxa = MAX(dp, maxa); - mina = MIN(dp, mina); - - dp = p_xform.elements[0].dot(xf_points2[2]); - maxa = MAX(dp, maxa); - mina = MIN(dp, mina); - - dp = p_xform.elements[0].dot(xf_points2[3]); - maxa = MAX(dp, maxa); - mina = MIN(dp, mina); - - real_t maxb = p_xform.elements[0].dot(xf_points[0]); - real_t minb = maxb; - - dp = p_xform.elements[0].dot(xf_points[1]); - maxb = MAX(dp, maxb); - minb = MIN(dp, minb); - - dp = p_xform.elements[0].dot(xf_points[2]); - maxb = MAX(dp, maxb); - minb = MIN(dp, minb); - - dp = p_xform.elements[0].dot(xf_points[3]); - maxb = MAX(dp, maxb); - minb = MIN(dp, minb); - - if (mina > maxb) - return false; - if (minb > maxa) - return false; - - maxa = p_xform.elements[1].dot(xf_points2[0]); - mina = maxa; - - dp = p_xform.elements[1].dot(xf_points2[1]); - maxa = MAX(dp, maxa); - mina = MIN(dp, mina); - - dp = p_xform.elements[1].dot(xf_points2[2]); - maxa = MAX(dp, maxa); - mina = MIN(dp, mina); - - dp = p_xform.elements[1].dot(xf_points2[3]); - maxa = MAX(dp, maxa); - mina = MIN(dp, mina); - - maxb = p_xform.elements[1].dot(xf_points[0]); - minb = maxb; - - dp = p_xform.elements[1].dot(xf_points[1]); - maxb = MAX(dp, maxb); - minb = MIN(dp, minb); - - dp = p_xform.elements[1].dot(xf_points[2]); - maxb = MAX(dp, maxb); - minb = MIN(dp, minb); - - dp = p_xform.elements[1].dot(xf_points[3]); - maxb = MAX(dp, maxb); - minb = MIN(dp, minb); - - if (mina > maxb) - return false; - if (minb > maxa) - return false; - - return true; -} - -} // namespace godot diff --git a/src/core/String.cpp b/src/core/String.cpp deleted file mode 100644 index ea3f7f1..0000000 --- a/src/core/String.cpp +++ /dev/null @@ -1,522 +0,0 @@ -/*************************************************************************/ -/* String.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "String.hpp" - -#include "Array.hpp" -#include "GodotGlobal.hpp" -#include "NodePath.hpp" -#include "PoolArrays.hpp" -#include "Variant.hpp" - -#include <gdnative/string.h> - -#include <string.h> - -namespace godot { - -godot::CharString::~CharString() { - godot::api->godot_char_string_destroy(&_char_string); -} - -int godot::CharString::length() const { - return godot::api->godot_char_string_length(&_char_string); -} - -const char *godot::CharString::get_data() const { - return godot::api->godot_char_string_get_data(&_char_string); -} - -String String::num(double p_num, int p_decimals) { - return String(godot::api->godot_string_num_with_decimals(p_num, p_decimals)); -} - -String String::num_scientific(double p_num) { - return String(godot::api->godot_string_num_scientific(p_num)); -} - -String String::num_real(double p_num) { - return String(godot::api->godot_string_num_real(p_num)); -} - -String String::num_int64(int64_t p_num, int base, bool capitalize_hex) { - return String(godot::api->godot_string_num_int64_capitalized(p_num, base, capitalize_hex)); -} - -String String::chr(godot_char_type p_char) { - return String(godot::api->godot_string_chr(p_char)); -} - -String String::md5(const uint8_t *p_md5) { - return String(godot::api->godot_string_md5(p_md5)); -} - -String String::hex_encode_buffer(const uint8_t *p_buffer, int p_len) { - return String(godot::api->godot_string_hex_encode_buffer(p_buffer, p_len)); -} - -godot::String::String() { - godot::api->godot_string_new(&_godot_string); -} - -String::String(const char *contents) { - godot::api->godot_string_new(&_godot_string); - godot::api->godot_string_parse_utf8(&_godot_string, contents); -} - -String::String(const wchar_t *contents) { - godot::api->godot_string_new_with_wide_string(&_godot_string, contents, wcslen(contents)); -} - -String::String(const wchar_t c) { - godot::api->godot_string_new_with_wide_string(&_godot_string, &c, 1); -} - -String::String(const String &other) { - godot::api->godot_string_new_copy(&_godot_string, &other._godot_string); -} - -String::String(String &&other) { - godot::api->godot_string_new_copy(&_godot_string, &other._godot_string); -} - -String::~String() { - godot::api->godot_string_destroy(&_godot_string); -} - -wchar_t &String::operator[](const int idx) { - return *const_cast<wchar_t *>(godot::api->godot_string_operator_index(&_godot_string, idx)); -} - -wchar_t String::operator[](const int idx) const { - return *godot::api->godot_string_operator_index((godot_string *)&_godot_string, idx); -} - -int String::length() const { - return godot::api->godot_string_length(&_godot_string); -} - -void String::operator=(const String &s) { - godot::api->godot_string_destroy(&_godot_string); - godot::api->godot_string_new_copy(&_godot_string, &s._godot_string); -} - -void String::operator=(String &&s) { - godot::api->godot_string_destroy(&_godot_string); - godot::api->godot_string_new_copy(&_godot_string, &s._godot_string); -} - -bool String::operator==(const String &s) const { - return godot::api->godot_string_operator_equal(&_godot_string, &s._godot_string); -} - -bool String::operator!=(const String &s) const { - return !(*this == s); -} - -String String::operator+(const String &s) const { - return String(godot::api->godot_string_operator_plus(&_godot_string, &s._godot_string)); -} - -void String::operator+=(const String &s) { - *this = String(godot::api->godot_string_operator_plus(&_godot_string, &s._godot_string)); -} - -void String::operator+=(const wchar_t c) { - String _to_be_added = String(c); - *this = String(godot::api->godot_string_operator_plus(&_godot_string, &_to_be_added._godot_string)); -} - -bool String::operator<(const String &s) const { - return godot::api->godot_string_operator_less(&_godot_string, &s._godot_string); -} - -bool String::operator<=(const String &s) const { - return godot::api->godot_string_operator_less(&_godot_string, &s._godot_string) || - (*this == s); -} - -bool String::operator>(const String &s) const { - return !(*this <= s); -} - -bool String::operator>=(const String &s) const { - return !(*this < s); -} - -String::operator NodePath() const { - return NodePath(*this); -} - -const wchar_t *String::unicode_str() const { - return godot::api->godot_string_wide_str(&_godot_string); -} - -char *String::alloc_c_string() const { - godot_char_string contents = godot::api->godot_string_utf8(&_godot_string); - - int length = godot::api->godot_char_string_length(&contents); - - char *result = (char *)godot::api->godot_alloc(length + 1); - - if (result) { - memcpy(result, godot::api->godot_char_string_get_data(&contents), length + 1); - } - - godot::api->godot_char_string_destroy(&contents); - - return result; -} - -CharString String::utf8() const { - CharString ret; - - ret._char_string = godot::api->godot_string_utf8(&_godot_string); - - return ret; -} - -CharString String::ascii(bool p_extended) const { - CharString ret; - - if (p_extended) - ret._char_string = godot::api->godot_string_ascii_extended(&_godot_string); - else - ret._char_string = godot::api->godot_string_ascii(&_godot_string); - - return ret; -} - -String operator+(const char *a, const String &b) { - return String(a) + b; -} - -String operator+(const wchar_t *a, const String &b) { - return String(a) + b; -} - -bool String::begins_with(const String &p_string) const { - return godot::api->godot_string_begins_with(&_godot_string, &p_string._godot_string); -} - -bool String::begins_with_char_array(const char *p_char_array) const { - return godot::api->godot_string_begins_with_char_array(&_godot_string, p_char_array); -} - -PoolStringArray String::bigrams() const { - godot_array arr = godot::api->godot_string_bigrams(&_godot_string); - return Array(arr); -} - -String String::c_escape() const { - return String(godot::api->godot_string_c_escape(&_godot_string)); -} - -String String::c_unescape() const { - return String(godot::api->godot_string_c_unescape(&_godot_string)); -} - -String String::capitalize() const { - return String(godot::api->godot_string_capitalize(&_godot_string)); -} - -bool String::empty() const { - return godot::api->godot_string_empty(&_godot_string); -} - -bool String::ends_with(const String &p_string) const { - return godot::api->godot_string_ends_with(&_godot_string, &p_string._godot_string); -} - -void String::erase(int position, int chars) { - godot::api->godot_string_erase(&_godot_string, position, chars); -} - -int String::find(String p_what, int p_from) const { - return godot::api->godot_string_find_from(&_godot_string, p_what._godot_string, p_from); -} - -int String::find_last(String p_what) const { - return godot::api->godot_string_find_last(&_godot_string, p_what._godot_string); -} - -int String::findn(String p_what, int p_from) const { - return godot::api->godot_string_findn_from(&_godot_string, p_what._godot_string, p_from); -} - -String String::format(Variant values) const { - return String(godot::api->godot_string_format(&_godot_string, (godot_variant *)&values)); -} - -String String::format(Variant values, String placeholder) const { - godot_char_string contents = godot::api->godot_string_utf8(&placeholder._godot_string); - String new_string(godot::api->godot_string_format_with_custom_placeholder(&_godot_string, (godot_variant *)&values, godot::api->godot_char_string_get_data(&contents))); - godot::api->godot_char_string_destroy(&contents); - - return new_string; -} - -String String::get_base_dir() const { - return String(godot::api->godot_string_get_base_dir(&_godot_string)); -} - -String String::get_basename() const { - return String(godot::api->godot_string_get_basename(&_godot_string)); -} - -String String::get_extension() const { - return String(godot::api->godot_string_get_extension(&_godot_string)); -} - -String String::get_file() const { - return String(godot::api->godot_string_get_file(&_godot_string)); -} - -int String::hash() const { - return godot::api->godot_string_hash(&_godot_string); -} - -int String::hex_to_int() const { - return godot::api->godot_string_hex_to_int(&_godot_string); -} - -String String::insert(int position, String what) const { - return String(godot::api->godot_string_insert(&_godot_string, position, what._godot_string)); -} - -bool String::is_abs_path() const { - return godot::api->godot_string_is_abs_path(&_godot_string); -} - -bool String::is_rel_path() const { - return godot::api->godot_string_is_rel_path(&_godot_string); -} - -bool String::is_subsequence_of(String text) const { - return godot::api->godot_string_is_subsequence_of(&_godot_string, &text._godot_string); -} - -bool String::is_subsequence_ofi(String text) const { - return godot::api->godot_string_is_subsequence_ofi(&_godot_string, &text._godot_string); -} - -bool String::is_valid_float() const { - return godot::api->godot_string_is_valid_float(&_godot_string); -} - -bool String::is_valid_html_color() const { - return godot::api->godot_string_is_valid_html_color(&_godot_string); -} - -bool String::is_valid_identifier() const { - return godot::api->godot_string_is_valid_identifier(&_godot_string); -} - -bool String::is_valid_integer() const { - return godot::api->godot_string_is_numeric(&_godot_string); -} - -bool String::is_valid_ip_address() const { - return godot::api->godot_string_is_valid_ip_address(&_godot_string); -} - -String String::json_escape() const { - return String(godot::api->godot_string_json_escape(&_godot_string)); -} - -String String::left(int position) const { - return String(godot::api->godot_string_left(&_godot_string, position)); -} - -bool String::match(String expr) const { - return godot::api->godot_string_match(&_godot_string, &expr._godot_string); -} - -bool String::matchn(String expr) const { - return godot::api->godot_string_match(&_godot_string, &expr._godot_string); -} - -PoolByteArray String::md5_buffer() const { - godot_pool_byte_array arr = godot::api->godot_string_md5_buffer(&_godot_string); - return PoolByteArray(arr); -} - -String String::md5_text() const { - return String(godot::api->godot_string_md5_text(&_godot_string)); -} - -int String::ord_at(int at) const { - return godot::api->godot_string_ord_at(&_godot_string, at); -} - -String String::pad_decimals(int digits) const { - return String(godot::api->godot_string_pad_decimals(&_godot_string, digits)); -} - -String String::pad_zeros(int digits) const { - return String(godot::api->godot_string_pad_zeros(&_godot_string, digits)); -} - -String String::percent_decode() const { - return String(godot::api->godot_string_percent_decode(&_godot_string)); -} - -String String::percent_encode() const { - return String(godot::api->godot_string_percent_encode(&_godot_string)); -} - -String String::plus_file(String file) const { - return String(godot::api->godot_string_plus_file(&_godot_string, &file._godot_string)); -} - -String String::replace(String p_key, String p_with) const { - return String(godot::api->godot_string_replace(&_godot_string, p_key._godot_string, p_with._godot_string)); -} - -String String::replacen(String what, String forwhat) const { - return String(godot::api->godot_string_replacen(&_godot_string, what._godot_string, forwhat._godot_string)); -} - -int String::rfind(String p_what, int p_from) const { - return godot::api->godot_string_rfind_from(&_godot_string, p_what._godot_string, p_from); -} - -int String::rfindn(String p_what, int p_from) const { - return godot::api->godot_string_rfindn_from(&_godot_string, p_what._godot_string, p_from); -} - -String String::right(int position) const { - return String(godot::api->godot_string_right(&_godot_string, position)); -} - -PoolByteArray String::sha256_buffer() const { - godot_pool_byte_array arr = godot::api->godot_string_sha256_buffer(&_godot_string); - return PoolByteArray(arr); -} - -String String::sha256_text() const { - return String(godot::api->godot_string_sha256_text(&_godot_string)); -} - -float String::similarity(String text) const { - return godot::api->godot_string_similarity(&_godot_string, &text._godot_string); -} - -// TODO Suport allow_empty -PoolStringArray String::split(String divisor, bool /*allow_empty*/) const { - godot_array arr = godot::api->godot_string_split(&_godot_string, &divisor._godot_string); - return Array(arr); -} - -// TODO Suport allow_empty -PoolIntArray String::split_ints(String divisor, bool /*allow_empty*/) const { - godot_array arr = godot::api->godot_string_split_floats(&_godot_string, &divisor._godot_string); - return Array(arr); -} - -// TODO Suport allow_empty -PoolRealArray String::split_floats(String divisor, bool /*allow_empty*/) const { - // TODO The GDNative API returns godot_array, when according to the doc, it should have been godot_pool_real_array - godot_array arr = godot::api->godot_string_split_floats(&_godot_string, &divisor._godot_string); - Array wrapped_array(arr); - return PoolRealArray(wrapped_array); -} - -String String::strip_edges(bool left, bool right) const { - return String(godot::api->godot_string_strip_edges(&_godot_string, left, right)); -} - -String String::substr(int from, int len) const { - return String(godot::api->godot_string_substr(&_godot_string, from, len)); -} - -float String::to_float() const { - return godot::api->godot_string_to_float(&_godot_string); -} - -int64_t String::to_int() const { - return godot::api->godot_string_to_int(&_godot_string); -} - -String String::to_lower() const { - return String(godot::api->godot_string_to_lower(&_godot_string)); -} - -String String::to_upper() const { - return String(godot::api->godot_string_to_upper(&_godot_string)); -} - -String String::xml_escape() const { - return String(godot::api->godot_string_xml_escape(&_godot_string)); -} - -String String::xml_unescape() const { - return String(godot::api->godot_string_xml_unescape(&_godot_string)); -} - -signed char String::casecmp_to(String p_str) const { - return godot::api->godot_string_casecmp_to(&_godot_string, &p_str._godot_string); -} - -signed char String::nocasecmp_to(String p_str) const { - return godot::api->godot_string_nocasecmp_to(&_godot_string, &p_str._godot_string); -} - -signed char String::naturalnocasecmp_to(String p_str) const { - return godot::api->godot_string_naturalnocasecmp_to(&_godot_string, &p_str._godot_string); -} - -String String::dedent() const { - godot_string s = godot::core_1_1_api->godot_string_dedent(&_godot_string); - return String(s); -} - -PoolStringArray String::rsplit(const String &divisor, const bool allow_empty, const int maxsplit) const { - godot_pool_string_array arr = - godot::core_1_1_api->godot_string_rsplit(&_godot_string, &divisor._godot_string, allow_empty, maxsplit); - return PoolStringArray(arr); -} - -String String::rstrip(const String &chars) const { - godot_string s = godot::core_1_1_api->godot_string_rstrip(&_godot_string, &chars._godot_string); - return String(s); -} - -String String::trim_prefix(const String &prefix) const { - godot_string s = godot::core_1_1_api->godot_string_trim_prefix(&_godot_string, &prefix._godot_string); - return String(s); -} - -String String::trim_suffix(const String &suffix) const { - godot_string s = godot::core_1_1_api->godot_string_trim_suffix(&_godot_string, &suffix._godot_string); - return String(s); -} - -} // namespace godot diff --git a/src/core/Transform.cpp b/src/core/Transform.cpp deleted file mode 100644 index 37dbb72..0000000 --- a/src/core/Transform.cpp +++ /dev/null @@ -1,305 +0,0 @@ -/*************************************************************************/ -/* Transform.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "Transform.hpp" - -#include "Basis.hpp" - -#include "AABB.hpp" -#include "Plane.hpp" - -#include "Quat.hpp" - -namespace godot { - -const Transform Transform::IDENTITY = Transform(); -const Transform Transform::FLIP_X = Transform(-1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0); -const Transform Transform::FLIP_Y = Transform(1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0); -const Transform Transform::FLIP_Z = Transform(1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0); - -Transform Transform::inverse_xform(const Transform &t) const { - Vector3 v = t.origin - origin; - return Transform(basis.transpose_xform(t.basis), - basis.xform(v)); -} - -void Transform::set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t tx, real_t ty, real_t tz) { - basis.elements[0][0] = xx; - basis.elements[0][1] = xy; - basis.elements[0][2] = xz; - basis.elements[1][0] = yx; - basis.elements[1][1] = yy; - basis.elements[1][2] = yz; - basis.elements[2][0] = zx; - basis.elements[2][1] = zy; - basis.elements[2][2] = zz; - origin.x = tx; - origin.y = ty; - origin.z = tz; -} - -Vector3 Transform::xform(const Vector3 &p_vector) const { - return Vector3( - basis.elements[0].dot(p_vector) + origin.x, - basis.elements[1].dot(p_vector) + origin.y, - basis.elements[2].dot(p_vector) + origin.z); -} -Vector3 Transform::xform_inv(const Vector3 &p_vector) const { - Vector3 v = p_vector - origin; - - return Vector3( - (basis.elements[0][0] * v.x) + (basis.elements[1][0] * v.y) + (basis.elements[2][0] * v.z), - (basis.elements[0][1] * v.x) + (basis.elements[1][1] * v.y) + (basis.elements[2][1] * v.z), - (basis.elements[0][2] * v.x) + (basis.elements[1][2] * v.y) + (basis.elements[2][2] * v.z)); -} - -Plane Transform::xform(const Plane &p_plane) const { - Vector3 point = p_plane.normal * p_plane.d; - Vector3 point_dir = point + p_plane.normal; - point = xform(point); - point_dir = xform(point_dir); - - Vector3 normal = point_dir - point; - normal.normalize(); - real_t d = normal.dot(point); - - return Plane(normal, d); -} -Plane Transform::xform_inv(const Plane &p_plane) const { - Vector3 point = p_plane.normal * p_plane.d; - Vector3 point_dir = point + p_plane.normal; - point = xform_inv(point); - point_dir = xform_inv(point_dir); - - Vector3 normal = point_dir - point; - normal.normalize(); - real_t d = normal.dot(point); - - return Plane(normal, d); -} - -AABB Transform::xform(const AABB &p_aabb) const { - /* define vertices */ - Vector3 x = basis.get_axis(0) * p_aabb.size.x; - Vector3 y = basis.get_axis(1) * p_aabb.size.y; - Vector3 z = basis.get_axis(2) * p_aabb.size.z; - Vector3 pos = xform(p_aabb.position); - //could be even further optimized - AABB new_aabb; - new_aabb.position = pos; - new_aabb.expand_to(pos + x); - new_aabb.expand_to(pos + y); - new_aabb.expand_to(pos + z); - new_aabb.expand_to(pos + x + y); - new_aabb.expand_to(pos + x + z); - new_aabb.expand_to(pos + y + z); - new_aabb.expand_to(pos + x + y + z); - return new_aabb; -} -AABB Transform::xform_inv(const AABB &p_aabb) const { - /* define vertices */ - Vector3 vertices[8] = { - Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z), - Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z), - Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z), - Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z), - Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z), - Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z), - Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z), - Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z) - }; - - AABB ret; - - ret.position = xform_inv(vertices[0]); - - for (int i = 1; i < 8; i++) { - ret.expand_to(xform_inv(vertices[i])); - } - - return ret; -} - -void Transform::affine_invert() { - basis.invert(); - origin = basis.xform(-origin); -} - -Transform Transform::affine_inverse() const { - Transform ret = *this; - ret.affine_invert(); - return ret; -} - -void Transform::invert() { - basis.transpose(); - origin = basis.xform(-origin); -} - -Transform Transform::inverse() const { - // FIXME: this function assumes the basis is a rotation matrix, with no scaling. - // Transform::affine_inverse can handle matrices with scaling, so GDScript should eventually use that. - Transform ret = *this; - ret.invert(); - return ret; -} - -void Transform::rotate(const Vector3 &p_axis, real_t p_phi) { - *this = rotated(p_axis, p_phi); -} - -Transform Transform::rotated(const Vector3 &p_axis, real_t p_phi) const { - return Transform(Basis(p_axis, p_phi), Vector3()) * (*this); -} - -void Transform::rotate_basis(const Vector3 &p_axis, real_t p_phi) { - basis.rotate(p_axis, p_phi); -} - -Transform Transform::looking_at(const Vector3 &p_target, const Vector3 &p_up) const { - Transform t = *this; - t.set_look_at(origin, p_target, p_up); - return t; -} - -void Transform::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up) { - // Reference: MESA source code - Vector3 v_x, v_y, v_z; - - /* Make rotation matrix */ - - /* Z vector */ - v_z = p_eye - p_target; - - v_z.normalize(); - - v_y = p_up; - - v_x = v_y.cross(v_z); - - /* Recompute Y = Z cross X */ - v_y = v_z.cross(v_x); - - v_x.normalize(); - v_y.normalize(); - - basis.set_axis(0, v_x); - basis.set_axis(1, v_y); - basis.set_axis(2, v_z); - origin = p_eye; -} - -Transform Transform::interpolate_with(const Transform &p_transform, real_t p_c) const { - /* not sure if very "efficient" but good enough? */ - - Vector3 src_scale = basis.get_scale(); - Quat src_rot = basis; - Vector3 src_loc = origin; - - Vector3 dst_scale = p_transform.basis.get_scale(); - Quat dst_rot = p_transform.basis; - Vector3 dst_loc = p_transform.origin; - - Transform dst; - dst.basis = src_rot.slerp(dst_rot, p_c); - dst.basis.scale(src_scale.linear_interpolate(dst_scale, p_c)); - dst.origin = src_loc.linear_interpolate(dst_loc, p_c); - - return dst; -} - -void Transform::scale(const Vector3 &p_scale) { - basis.scale(p_scale); - origin *= p_scale; -} - -Transform Transform::scaled(const Vector3 &p_scale) const { - Transform t = *this; - t.scale(p_scale); - return t; -} - -void Transform::scale_basis(const Vector3 &p_scale) { - basis.scale(p_scale); -} - -void Transform::translate(real_t p_tx, real_t p_ty, real_t p_tz) { - translate(Vector3(p_tx, p_ty, p_tz)); -} -void Transform::translate(const Vector3 &p_translation) { - for (int i = 0; i < 3; i++) { - origin[i] += basis.elements[i].dot(p_translation); - } -} - -Transform Transform::translated(const Vector3 &p_translation) const { - Transform t = *this; - t.translate(p_translation); - return t; -} - -void Transform::orthonormalize() { - basis.orthonormalize(); -} - -Transform Transform::orthonormalized() const { - Transform _copy = *this; - _copy.orthonormalize(); - return _copy; -} - -bool Transform::operator==(const Transform &p_transform) const { - return (basis == p_transform.basis && origin == p_transform.origin); -} -bool Transform::operator!=(const Transform &p_transform) const { - return (basis != p_transform.basis || origin != p_transform.origin); -} - -void Transform::operator*=(const Transform &p_transform) { - origin = xform(p_transform.origin); - basis *= p_transform.basis; -} - -Transform Transform::operator*(const Transform &p_transform) const { - Transform t = *this; - t *= p_transform; - return t; -} - -Transform::operator String() const { - return basis.operator String() + " - " + origin.operator String(); -} - -Transform::Transform(const Basis &p_basis, const Vector3 &p_origin) { - basis = p_basis; - origin = p_origin; -} - -} // namespace godot diff --git a/src/core/Transform2D.cpp b/src/core/Transform2D.cpp deleted file mode 100644 index 01565e1..0000000 --- a/src/core/Transform2D.cpp +++ /dev/null @@ -1,332 +0,0 @@ -/*************************************************************************/ -/* Transform2D.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "Transform2D.hpp" -#include "Rect2.hpp" -#include "String.hpp" -#include "Vector2.hpp" - -#include <algorithm> - -namespace godot { - -const Transform2D Transform2D::IDENTITY; -const Transform2D Transform2D::FLIP_X = Transform2D(-1, 0, 0, 1, 0, 0); -const Transform2D Transform2D::FLIP_Y = Transform2D(1, 0, 0, -1, 0, 0); - -Transform2D::Transform2D(real_t xx, real_t xy, real_t yx, real_t yy, real_t ox, real_t oy) { - elements[0][0] = xx; - elements[0][1] = xy; - elements[1][0] = yx; - elements[1][1] = yy; - elements[2][0] = ox; - elements[2][1] = oy; -} - -Vector2 Transform2D::basis_xform(const Vector2 &v) const { - return Vector2( - tdotx(v), - tdoty(v)); -} - -Vector2 Transform2D::basis_xform_inv(const Vector2 &v) const { - return Vector2( - elements[0].dot(v), - elements[1].dot(v)); -} - -Vector2 Transform2D::xform(const Vector2 &v) const { - return Vector2( - tdotx(v), - tdoty(v)) + - elements[2]; -} -Vector2 Transform2D::xform_inv(const Vector2 &p_vec) const { - Vector2 v = p_vec - elements[2]; - - return Vector2( - elements[0].dot(v), - elements[1].dot(v)); -} -Rect2 Transform2D::xform(const Rect2 &p_rect) const { - Vector2 x = elements[0] * p_rect.size.x; - Vector2 y = elements[1] * p_rect.size.y; - Vector2 position = xform(p_rect.position); - - Rect2 new_rect; - new_rect.position = position; - new_rect.expand_to(position + x); - new_rect.expand_to(position + y); - new_rect.expand_to(position + x + y); - return new_rect; -} - -void Transform2D::set_rotation_and_scale(real_t p_rot, const Size2 &p_scale) { - elements[0][0] = ::cos(p_rot) * p_scale.x; - elements[1][1] = ::cos(p_rot) * p_scale.y; - elements[1][0] = -::sin(p_rot) * p_scale.y; - elements[0][1] = ::sin(p_rot) * p_scale.x; -} - -Rect2 Transform2D::xform_inv(const Rect2 &p_rect) const { - Vector2 ends[4] = { - xform_inv(p_rect.position), - xform_inv(Vector2(p_rect.position.x, p_rect.position.y + p_rect.size.y)), - xform_inv(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y + p_rect.size.y)), - xform_inv(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y)) - }; - - Rect2 new_rect; - new_rect.position = ends[0]; - new_rect.expand_to(ends[1]); - new_rect.expand_to(ends[2]); - new_rect.expand_to(ends[3]); - - return new_rect; -} - -void Transform2D::invert() { - // FIXME: this function assumes the basis is a rotation matrix, with no scaling. - // Transform2D::affine_inverse can handle matrices with scaling, so GDScript should eventually use that. - std::swap(elements[0][1], elements[1][0]); - elements[2] = basis_xform(-elements[2]); -} - -Transform2D Transform2D::inverse() const { - Transform2D inv = *this; - inv.invert(); - return inv; -} - -void Transform2D::affine_invert() { - real_t det = basis_determinant(); - ERR_FAIL_COND(det == 0); - real_t idet = 1.0 / det; - - std::swap(elements[0][0], elements[1][1]); - elements[0] *= Vector2(idet, -idet); - elements[1] *= Vector2(-idet, idet); - - elements[2] = basis_xform(-elements[2]); -} - -Transform2D Transform2D::affine_inverse() const { - Transform2D inv = *this; - inv.affine_invert(); - return inv; -} - -void Transform2D::rotate(real_t p_phi) { - *this = Transform2D(p_phi, Vector2()) * (*this); -} - -real_t Transform2D::get_rotation() const { - real_t det = basis_determinant(); - Transform2D m = orthonormalized(); - if (det < 0) { - m.scale_basis(Size2(-1, -1)); - } - return ::atan2(m[0].y, m[0].x); -} - -void Transform2D::set_rotation(real_t p_rot) { - real_t cr = ::cos(p_rot); - real_t sr = ::sin(p_rot); - elements[0][0] = cr; - elements[0][1] = sr; - elements[1][0] = -sr; - elements[1][1] = cr; -} - -Transform2D::Transform2D(real_t p_rot, const Vector2 &p_position) { - real_t cr = ::cos(p_rot); - real_t sr = ::sin(p_rot); - elements[0][0] = cr; - elements[0][1] = sr; - elements[1][0] = -sr; - elements[1][1] = cr; - elements[2] = p_position; -} - -Size2 Transform2D::get_scale() const { - real_t det_sign = basis_determinant() > 0 ? 1 : -1; - return det_sign * Size2(elements[0].length(), elements[1].length()); -} - -void Transform2D::scale(const Size2 &p_scale) { - scale_basis(p_scale); - elements[2] *= p_scale; -} -void Transform2D::scale_basis(const Size2 &p_scale) { - elements[0][0] *= p_scale.x; - elements[0][1] *= p_scale.y; - elements[1][0] *= p_scale.x; - elements[1][1] *= p_scale.y; -} -void Transform2D::translate(real_t p_tx, real_t p_ty) { - translate(Vector2(p_tx, p_ty)); -} -void Transform2D::translate(const Vector2 &p_translation) { - elements[2] += basis_xform(p_translation); -} - -void Transform2D::orthonormalize() { - // Gram-Schmidt Process - - Vector2 x = elements[0]; - Vector2 y = elements[1]; - - x.normalize(); - y = (y - x * (x.dot(y))); - y.normalize(); - - elements[0] = x; - elements[1] = y; -} -Transform2D Transform2D::orthonormalized() const { - Transform2D on = *this; - on.orthonormalize(); - return on; -} - -bool Transform2D::operator==(const Transform2D &p_transform) const { - for (int i = 0; i < 3; i++) { - if (elements[i] != p_transform.elements[i]) - return false; - } - - return true; -} - -bool Transform2D::operator!=(const Transform2D &p_transform) const { - for (int i = 0; i < 3; i++) { - if (elements[i] != p_transform.elements[i]) - return true; - } - - return false; -} - -void Transform2D::operator*=(const Transform2D &p_transform) { - elements[2] = xform(p_transform.elements[2]); - - real_t x0, x1, y0, y1; - - x0 = tdotx(p_transform.elements[0]); - x1 = tdoty(p_transform.elements[0]); - y0 = tdotx(p_transform.elements[1]); - y1 = tdoty(p_transform.elements[1]); - - elements[0][0] = x0; - elements[0][1] = x1; - elements[1][0] = y0; - elements[1][1] = y1; -} - -Transform2D Transform2D::operator*(const Transform2D &p_transform) const { - Transform2D t = *this; - t *= p_transform; - return t; -} - -Transform2D Transform2D::scaled(const Size2 &p_scale) const { - Transform2D copy = *this; - copy.scale(p_scale); - return copy; -} - -Transform2D Transform2D::basis_scaled(const Size2 &p_scale) const { - Transform2D copy = *this; - copy.scale_basis(p_scale); - return copy; -} - -Transform2D Transform2D::untranslated() const { - Transform2D copy = *this; - copy.elements[2] = Vector2(); - return copy; -} - -Transform2D Transform2D::translated(const Vector2 &p_offset) const { - Transform2D copy = *this; - copy.translate(p_offset); - return copy; -} - -Transform2D Transform2D::rotated(real_t p_phi) const { - Transform2D copy = *this; - copy.rotate(p_phi); - return copy; -} - -real_t Transform2D::basis_determinant() const { - return elements[0].x * elements[1].y - elements[0].y * elements[1].x; -} - -Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, real_t p_c) const { - //extract parameters - Vector2 p1 = get_origin(); - Vector2 p2 = p_transform.get_origin(); - - real_t r1 = get_rotation(); - real_t r2 = p_transform.get_rotation(); - - Size2 s1 = get_scale(); - Size2 s2 = p_transform.get_scale(); - - //slerp rotation - Vector2 v1(::cos(r1), ::sin(r1)); - Vector2 v2(::cos(r2), ::sin(r2)); - - real_t dot = v1.dot(v2); - - dot = (dot < -1.0) ? -1.0 : ((dot > 1.0) ? 1.0 : dot); //clamp dot to [-1,1] - - Vector2 v; - - if (dot > 0.9995) { - v = Vector2::linear_interpolate(v1, v2, p_c).normalized(); //linearly interpolate to avoid numerical precision issues - } else { - real_t angle = p_c * ::acos(dot); - Vector2 v3 = (v2 - v1 * dot).normalized(); - v = v1 * ::cos(angle) + v3 * ::sin(angle); - } - - //construct matrix - Transform2D res(::atan2(v.y, v.x), Vector2::linear_interpolate(p1, p2, p_c)); - res.scale_basis(Vector2::linear_interpolate(s1, s2, p_c)); - return res; -} - -Transform2D::operator String() const { - return String(String() + elements[0] + ", " + elements[1] + ", " + elements[2]); -} - -} // namespace godot diff --git a/src/core/Variant.cpp b/src/core/Variant.cpp deleted file mode 100644 index a0b50df..0000000 --- a/src/core/Variant.cpp +++ /dev/null @@ -1,381 +0,0 @@ -/*************************************************************************/ -/* Variant.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "Variant.hpp" - -#include <gdnative/variant.h> - -#include "CoreTypes.hpp" -#include "Defs.hpp" -#include "GodotGlobal.hpp" -#include "Object.hpp" - -namespace godot { - -Variant::Variant() { - godot::api->godot_variant_new_nil(&_godot_variant); -} - -Variant::Variant(const Variant &v) { - godot::api->godot_variant_new_copy(&_godot_variant, &v._godot_variant); -} - -Variant::Variant(bool p_bool) { - godot::api->godot_variant_new_bool(&_godot_variant, p_bool); -} - -Variant::Variant(signed int p_int) // real one -{ - godot::api->godot_variant_new_int(&_godot_variant, p_int); -} - -Variant::Variant(unsigned int p_int) { - godot::api->godot_variant_new_uint(&_godot_variant, p_int); -} - -Variant::Variant(signed short p_short) // real one -{ - godot::api->godot_variant_new_int(&_godot_variant, (int)p_short); -} - -Variant::Variant(int64_t p_char) // real one -{ - godot::api->godot_variant_new_int(&_godot_variant, p_char); -} - -Variant::Variant(uint64_t p_char) { - godot::api->godot_variant_new_uint(&_godot_variant, p_char); -} - -Variant::Variant(float p_float) { - godot::api->godot_variant_new_real(&_godot_variant, p_float); -} - -Variant::Variant(double p_double) { - godot::api->godot_variant_new_real(&_godot_variant, p_double); -} - -Variant::Variant(const String &p_string) { - godot::api->godot_variant_new_string(&_godot_variant, (godot_string *)&p_string); -} - -Variant::Variant(const char *const p_cstring) { - String s = String(p_cstring); - godot::api->godot_variant_new_string(&_godot_variant, (godot_string *)&s); -} - -Variant::Variant(const wchar_t *p_wstring) { - String s = p_wstring; - godot::api->godot_variant_new_string(&_godot_variant, (godot_string *)&s); -} - -Variant::Variant(const Vector2 &p_vector2) { - godot::api->godot_variant_new_vector2(&_godot_variant, (godot_vector2 *)&p_vector2); -} - -Variant::Variant(const Rect2 &p_rect2) { - godot::api->godot_variant_new_rect2(&_godot_variant, (godot_rect2 *)&p_rect2); -} - -Variant::Variant(const Vector3 &p_vector3) { - godot::api->godot_variant_new_vector3(&_godot_variant, (godot_vector3 *)&p_vector3); -} - -Variant::Variant(const Plane &p_plane) { - godot::api->godot_variant_new_plane(&_godot_variant, (godot_plane *)&p_plane); -} - -Variant::Variant(const AABB &p_aabb) { - godot::api->godot_variant_new_aabb(&_godot_variant, (godot_aabb *)&p_aabb); -} - -Variant::Variant(const Quat &p_quat) { - godot::api->godot_variant_new_quat(&_godot_variant, (godot_quat *)&p_quat); -} - -Variant::Variant(const Basis &p_transform) { - godot::api->godot_variant_new_basis(&_godot_variant, (godot_basis *)&p_transform); -} - -Variant::Variant(const Transform2D &p_transform) { - godot::api->godot_variant_new_transform2d(&_godot_variant, (godot_transform2d *)&p_transform); -} - -Variant::Variant(const Transform &p_transform) { - godot::api->godot_variant_new_transform(&_godot_variant, (godot_transform *)&p_transform); -} - -Variant::Variant(const Color &p_color) { - godot::api->godot_variant_new_color(&_godot_variant, (godot_color *)&p_color); -} - -Variant::Variant(const NodePath &p_path) { - godot::api->godot_variant_new_node_path(&_godot_variant, (godot_node_path *)&p_path); -} - -Variant::Variant(const RID &p_rid) { - godot::api->godot_variant_new_rid(&_godot_variant, (godot_rid *)&p_rid); -} - -Variant::Variant(const Object *p_object) { - if (p_object) - godot::api->godot_variant_new_object(&_godot_variant, p_object->_owner); - else - godot::api->godot_variant_new_nil(&_godot_variant); -} - -Variant::Variant(const Dictionary &p_dictionary) { - godot::api->godot_variant_new_dictionary(&_godot_variant, (godot_dictionary *)&p_dictionary); -} - -Variant::Variant(const Array &p_array) { - godot::api->godot_variant_new_array(&_godot_variant, (godot_array *)&p_array); -} - -Variant::Variant(const PoolByteArray &p_raw_array) { - godot::api->godot_variant_new_pool_byte_array(&_godot_variant, (godot_pool_byte_array *)&p_raw_array); -} - -Variant::Variant(const PoolIntArray &p_int_array) { - godot::api->godot_variant_new_pool_int_array(&_godot_variant, (godot_pool_int_array *)&p_int_array); -} - -Variant::Variant(const PoolRealArray &p_real_array) { - godot::api->godot_variant_new_pool_real_array(&_godot_variant, (godot_pool_real_array *)&p_real_array); -} - -Variant::Variant(const PoolStringArray &p_string_array) { - godot::api->godot_variant_new_pool_string_array(&_godot_variant, (godot_pool_string_array *)&p_string_array); -} - -Variant::Variant(const PoolVector2Array &p_vector2_array) { - godot::api->godot_variant_new_pool_vector2_array(&_godot_variant, (godot_pool_vector2_array *)&p_vector2_array); -} - -Variant::Variant(const PoolVector3Array &p_vector3_array) { - godot::api->godot_variant_new_pool_vector3_array(&_godot_variant, (godot_pool_vector3_array *)&p_vector3_array); -} - -Variant::Variant(const PoolColorArray &p_color_array) { - godot::api->godot_variant_new_pool_color_array(&_godot_variant, (godot_pool_color_array *)&p_color_array); -} - -Variant &Variant::operator=(const Variant &v) { - godot::api->godot_variant_new_copy(&_godot_variant, &v._godot_variant); - return *this; -} - -Variant::operator bool() const { - return booleanize(); -} -Variant::operator signed int() const { - return godot::api->godot_variant_as_int(&_godot_variant); -} -Variant::operator unsigned int() const // this is the real one -{ - return godot::api->godot_variant_as_uint(&_godot_variant); -} -Variant::operator signed short() const { - return godot::api->godot_variant_as_int(&_godot_variant); -} -Variant::operator unsigned short() const { - return godot::api->godot_variant_as_uint(&_godot_variant); -} -Variant::operator signed char() const { - return godot::api->godot_variant_as_int(&_godot_variant); -} -Variant::operator unsigned char() const { - return godot::api->godot_variant_as_uint(&_godot_variant); -} -Variant::operator int64_t() const { - return godot::api->godot_variant_as_int(&_godot_variant); -} -Variant::operator uint64_t() const { - return godot::api->godot_variant_as_uint(&_godot_variant); -} - -Variant::operator wchar_t() const { - return godot::api->godot_variant_as_int(&_godot_variant); -} - -Variant::operator float() const { - return godot::api->godot_variant_as_real(&_godot_variant); -} - -Variant::operator double() const { - return godot::api->godot_variant_as_real(&_godot_variant); -} -Variant::operator String() const { - godot_string s = godot::api->godot_variant_as_string(&_godot_variant); - return String(s); -} -Variant::operator Vector2() const { - godot_vector2 s = godot::api->godot_variant_as_vector2(&_godot_variant); - return *(Vector2 *)&s; -} -Variant::operator Rect2() const { - godot_rect2 s = godot::api->godot_variant_as_rect2(&_godot_variant); - return *(Rect2 *)&s; -} -Variant::operator Vector3() const { - godot_vector3 s = godot::api->godot_variant_as_vector3(&_godot_variant); - return *(Vector3 *)&s; -} -Variant::operator Plane() const { - godot_plane s = godot::api->godot_variant_as_plane(&_godot_variant); - return *(Plane *)&s; -} -Variant::operator AABB() const { - godot_aabb s = godot::api->godot_variant_as_aabb(&_godot_variant); - return *(AABB *)&s; -} -Variant::operator Quat() const { - godot_quat s = godot::api->godot_variant_as_quat(&_godot_variant); - return *(Quat *)&s; -} -Variant::operator Basis() const { - godot_basis s = godot::api->godot_variant_as_basis(&_godot_variant); - return *(Basis *)&s; -} -Variant::operator Transform() const { - godot_transform s = godot::api->godot_variant_as_transform(&_godot_variant); - return *(Transform *)&s; -} -Variant::operator Transform2D() const { - godot_transform2d s = godot::api->godot_variant_as_transform2d(&_godot_variant); - return *(Transform2D *)&s; -} - -Variant::operator Color() const { - godot_color s = godot::api->godot_variant_as_color(&_godot_variant); - return *(Color *)&s; -} -Variant::operator NodePath() const { - godot_node_path ret = godot::api->godot_variant_as_node_path(&_godot_variant); - return NodePath(ret); -} -Variant::operator RID() const { - godot_rid s = godot::api->godot_variant_as_rid(&_godot_variant); - return *(RID *)&s; -} - -Variant::operator Dictionary() const { - Dictionary ret(godot::api->godot_variant_as_dictionary(&_godot_variant)); - return ret; -} - -Variant::operator Array() const { - Array ret(godot::api->godot_variant_as_array(&_godot_variant)); - return ret; -} - -Variant::operator PoolByteArray() const { - godot_pool_byte_array ret = godot::api->godot_variant_as_pool_byte_array(&_godot_variant); - return PoolByteArray(ret); -} -Variant::operator PoolIntArray() const { - godot_pool_int_array ret = godot::api->godot_variant_as_pool_int_array(&_godot_variant); - return PoolIntArray(ret); -} -Variant::operator PoolRealArray() const { - godot_pool_real_array ret = godot::api->godot_variant_as_pool_real_array(&_godot_variant); - return PoolRealArray(ret); -} -Variant::operator PoolStringArray() const { - godot_pool_string_array ret = godot::api->godot_variant_as_pool_string_array(&_godot_variant); - return PoolStringArray(ret); -} -Variant::operator PoolVector2Array() const { - godot_pool_vector2_array ret = godot::api->godot_variant_as_pool_vector2_array(&_godot_variant); - return PoolVector2Array(ret); -} -Variant::operator PoolVector3Array() const { - godot_pool_vector3_array ret = godot::api->godot_variant_as_pool_vector3_array(&_godot_variant); - return PoolVector3Array(ret); -} -Variant::operator PoolColorArray() const { - godot_pool_color_array ret = godot::api->godot_variant_as_pool_color_array(&_godot_variant); - return PoolColorArray(ret); -} -Variant::operator godot_object *() const { - return godot::api->godot_variant_as_object(&_godot_variant); -} - -Variant::Type Variant::get_type() const { - return static_cast<Type>(godot::api->godot_variant_get_type(&_godot_variant)); -} - -Variant Variant::call(const String &method, const Variant **args, const int arg_count) { - godot_variant v = godot::api->godot_variant_call( - &_godot_variant, (godot_string *)&method, (const godot_variant **)args, arg_count, nullptr); - return Variant(v); -} - -bool Variant::has_method(const String &method) { - return godot::api->godot_variant_has_method(&_godot_variant, (godot_string *)&method); -} - -bool Variant::operator==(const Variant &b) const { - return godot::api->godot_variant_operator_equal(&_godot_variant, &b._godot_variant); -} - -bool Variant::operator!=(const Variant &b) const { - return !(*this == b); -} - -bool Variant::operator<(const Variant &b) const { - return godot::api->godot_variant_operator_less(&_godot_variant, &b._godot_variant); -} - -bool Variant::operator<=(const Variant &b) const { - return (*this < b) || (*this == b); -} - -bool Variant::operator>(const Variant &b) const { - return !(*this <= b); -} - -bool Variant::operator>=(const Variant &b) const { - return !(*this < b); -} - -bool Variant::hash_compare(const Variant &b) const { - return godot::api->godot_variant_hash_compare(&_godot_variant, &b._godot_variant); -} - -bool Variant::booleanize() const { - return godot::api->godot_variant_booleanize(&_godot_variant); -} - -Variant::~Variant() { - godot::api->godot_variant_destroy(&_godot_variant); -} - -} // namespace godot diff --git a/src/core/class_db.cpp b/src/core/class_db.cpp new file mode 100644 index 0000000..57e77c3 --- /dev/null +++ b/src/core/class_db.cpp @@ -0,0 +1,312 @@ +/*************************************************************************/ +/* class_db.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include <godot_cpp/core/class_db.hpp> + +#include <godot_cpp/core/error_macros.hpp> +#include <godot_cpp/godot.hpp> + +#include <godot_cpp/core/memory.hpp> + +#include <algorithm> + +namespace godot { + +std::unordered_map<std::string, ClassDB::ClassInfo> ClassDB::classes; + +MethodDefinition D_METHOD(const char *p_name) { + return MethodDefinition(p_name); +} + +MethodDefinition D_METHOD(const char *p_name, const char *p_arg1) { + MethodDefinition method(p_name); + method.args.push_front(p_arg1); + return method; +} + +void ClassDB::add_property(const char *p_class, const PropertyInfo &p_pinfo, const char *p_setter, const char *p_getter, int p_index) { + ERR_FAIL_COND_MSG(classes.find(p_class) == classes.end(), "Trying to add property to non-existing class."); + + ClassInfo &info = classes[p_class]; + + ERR_FAIL_COND_MSG(info.property_setget.find(p_pinfo.name) != info.property_setget.end(), "Property already exists in class."); + + MethodBind *setter = nullptr; + if (p_setter) { + setter = get_method(p_class, p_setter); + + ERR_FAIL_COND_MSG(!setter, "Setter method not found for property."); + + size_t exp_args = 1 + (p_index >= 0 ? 1 : 0); + ERR_FAIL_COND_MSG(exp_args != setter->get_argument_count(), "Setter method must take a single argument."); + } + + ERR_FAIL_COND_MSG(!p_getter, "Getter method must be specified."); + + MethodBind *getter = get_method(p_class, p_getter); + ERR_FAIL_COND_MSG(!getter, "Getter method not found for property."); + { + size_t exp_args = 0 + (p_index >= 0 ? 1 : 0); + ERR_FAIL_COND_MSG(exp_args != getter->get_argument_count(), "Getter method must not take any argument."); + } + + info.property_list.push_back(p_pinfo); + + PropertySetGet setget; + setget.setter = p_setter; + setget.getter = p_getter; + setget._setptr = setter; + setget._getptr = getter; + setget.index = p_index; + setget.type = p_pinfo.type; + + info.property_setget[p_pinfo.name] = setget; +} + +MethodBind *ClassDB::get_method(const char *p_class, const char *p_method) { + ERR_FAIL_COND_V_MSG(classes.find(p_class) == classes.end(), nullptr, "Class not found."); + + ClassInfo *type = &classes[p_class]; + while (type) { + std::unordered_map<std::string, MethodBind *>::iterator method = type->method_map.find(p_method); + if (method != type->method_map.end()) { + return method->second; + } + type = type->parent_ptr; + continue; + } + + return nullptr; +} + +MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const void **p_defs, int p_defcount) { + const char *instance_type = p_bind->get_instance_class(); + + std::unordered_map<std::string, ClassInfo>::iterator type_it = classes.find(instance_type); + if (type_it == classes.end()) { + memdelete(p_bind); + ERR_FAIL_V_MSG(nullptr, "Class doesn't exist."); + } + + ClassInfo &type = type_it->second; + + if (type.method_map.find(method_name.name) != type.method_map.end()) { + memdelete(p_bind); + ERR_FAIL_V_MSG(nullptr, "Binding duplicate method."); + } + + if (type.virtual_methods.find(method_name.name) != type.virtual_methods.end()) { + memdelete(p_bind); + ERR_FAIL_V_MSG(nullptr, "Method already bound as virtual."); + } + + p_bind->set_name(method_name.name); + + if (method_name.args.size() > p_bind->get_argument_count()) { + memdelete(p_bind); + ERR_FAIL_V_MSG(nullptr, "Method definition has more arguments than the actual method."); + } + + p_bind->set_hint_flags(p_flags); + + std::vector<std::string> args; + args.resize(method_name.args.size()); + size_t arg_index = 0; + for (std::string arg : method_name.args) { + args[arg_index++] = arg; + } + + p_bind->set_argument_names(args); + + type.method_order.push_back(p_bind); + type.method_map[method_name.name] = p_bind; + + return p_bind; +} + +void ClassDB::add_signal(const char *p_class, const MethodInfo &p_signal) { + std::unordered_map<std::string, ClassInfo>::iterator type_it = classes.find(p_class); + + ERR_FAIL_COND_MSG(type_it == classes.end(), "Class doesn't exist."); + + ClassInfo &base = type_it->second; + ClassInfo *check = &base; + while (check) { + ERR_FAIL_COND_MSG(check->signal_map.find(p_signal.name) != check->signal_map.end(), String("Class '" + String(p_class) + "' already has signal '" + String(p_signal.name) + "'.").utf8().get_data()); + check = check->parent_ptr; + } + + base.signal_map[p_signal.name] = p_signal; +} + +void ClassDB::bind_integer_constant(const char *p_class, const char *p_enum, const char *p_name, GDNativeInt p_constant) { + std::unordered_map<std::string, ClassInfo>::iterator type_it = classes.find(p_class); + + ERR_FAIL_COND_MSG(type_it == classes.end(), "Class doesn't exist."); + + ClassInfo &type = type_it->second; + + ERR_FAIL_COND_MSG(type.constant_map.find(p_name) != type.constant_map.end(), "Constant already registered."); + + type.constant_map[p_name] = std::pair<std::string, GDNativeInt>{ p_enum, p_constant }; + type.constant_order.push_back(p_name); +} + +GDNativeExtensionClassCallVirtual ClassDB::get_virtual_func(void *p_userdata, const char *p_name) { + const char *class_name = (const char *)p_userdata; + + std::unordered_map<std::string, ClassInfo>::iterator type_it = classes.find(class_name); + ERR_FAIL_COND_V_MSG(type_it == classes.end(), nullptr, "Class doesn't exist."); + + ClassInfo &type = type_it->second; + + std::unordered_map<std::string, GDNativeExtensionClassCallVirtual>::iterator method_it = type.virtual_methods.find(p_name); + + if (method_it == type.virtual_methods.end()) { + return nullptr; + } + + return method_it->second; +} + +void ClassDB::bind_virtual_method(const char *p_class, const char *p_method, GDNativeExtensionClassCallVirtual p_call) { + std::unordered_map<std::string, ClassInfo>::iterator type_it = classes.find(p_class); + ERR_FAIL_COND_MSG(type_it == classes.end(), "Class doesn't exist."); + + ClassInfo &type = type_it->second; + + ERR_FAIL_COND_MSG(type.method_map.find(p_method) != type.method_map.end(), "Method already registered as non-virtual."); + ERR_FAIL_COND_MSG(type.virtual_methods.find(p_method) != type.virtual_methods.end(), "Virtual method already registered."); + + type.virtual_methods[p_method] = p_call; +} + +void ClassDB::initialize(GDNativeInitializationLevel p_level) { + for (const std::pair<std::string, ClassInfo> pair : classes) { + const ClassInfo &cl = pair.second; + if (cl.level != p_level) { + continue; + } + + GDNativeExtensionClassCreationInfo class_info = { + nullptr, // GDNativeExtensionClassSet set_func; + nullptr, // GDNativeExtensionClassGet get_func; + nullptr, // GDNativeExtensionClassGetPropertyList get_property_list_func; + nullptr, // GDNativeExtensionClassFreePropertyList free_property_list_func; + nullptr, // GDNativeExtensionClassNotification notification_func; + nullptr, // GDNativeExtensionClassToString to_string_func; + nullptr, // GDNativeExtensionClassReference reference_func; + nullptr, // GDNativeExtensionClassUnreference + cl.constructor, // GDNativeExtensionClassCreateInstance create_instance_func; /* this one is mandatory */ + cl.destructor, // GDNativeExtensionClassFreeInstance free_instance_func; /* this one is mandatory */ + cl.object_instance, // GDNativeExtensionClassObjectInstance object_instance_func; /* this one is mandatory */ + &ClassDB::get_virtual_func, // GDNativeExtensionClassGetVirtual get_virtual_func; + (void *)cl.name, //void *class_userdata; + }; + + internal::interface->classdb_register_extension_class(internal::library, cl.name, cl.parent_name, &class_info); + + for (MethodBind *method : cl.method_order) { + GDNativeExtensionClassMethodInfo method_info = { + method->get_name(), //const char *name; + method, //void *method_userdata; + MethodBind::bind_call, //GDNativeExtensionClassMethodCall call_func; + MethodBind::bind_ptrcall, //GDNativeExtensionClassMethodPtrCall ptrcall_func; + GDNATIVE_EXTENSION_METHOD_FLAGS_DEFAULT, //uint32_t method_flags; /* GDNativeExtensionClassMethodFlags */ + (uint32_t)method->get_argument_count(), //uint32_t argument_count; + (GDNativeBool)method->has_return(), //GDNativeBool has_return_value; + MethodBind::bind_get_argument_type, //(GDNativeExtensionClassMethodGetArgumentType) get_argument_type_func; + MethodBind::bind_get_argument_info, //GDNativeExtensionClassMethodGetArgumentInfo get_argument_info_func; /* name and hint information for the argument can be omitted in release builds. Class name should always be present if it applies. */ + MethodBind::bind_get_argument_metadata, //GDNativeExtensionClassMethodGetArgumentMetadata get_argument_metadata_func; + method->get_hint_flags(), //uint32_t default_argument_count; + nullptr, //GDNativeVariantPtr *default_arguments; + }; + internal::interface->classdb_register_extension_class_method(internal::library, cl.name, &method_info); + } + + for (const PropertyInfo &property : cl.property_list) { + GDNativePropertyInfo info = { + (uint32_t)property.type, //uint32_t type; + property.name, //const char *name; + property.class_name, //const char *class_name; + property.hint, // NONE //uint32_t hint; + property.hint_string, // const char *hint_string; + property.usage, // DEFAULT //uint32_t usage; + }; + + const PropertySetGet &setget = cl.property_setget.find(property.name)->second; + + internal::interface->classdb_register_extension_class_property(internal::library, cl.name, &info, setget.setter, setget.getter); + } + + for (const std::pair<std::string, MethodInfo> pair : cl.signal_map) { + const MethodInfo &signal = pair.second; + + std::vector<GDNativePropertyInfo> parameters; + parameters.reserve(signal.arguments.size()); + + for (const PropertyInfo &par : signal.arguments) { + parameters.push_back(GDNativePropertyInfo{ + static_cast<uint32_t>(par.type), // uint32_t type; + par.name, // const char *name; + par.class_name, // const char *class_name; + par.hint, // uint32_t hint; + par.hint_string, // const char *hint_string; + par.usage, // uint32_t usage; + }); + } + + internal::interface->classdb_register_extension_class_signal(internal::library, cl.name, pair.first.c_str(), parameters.data(), parameters.size()); + } + + for (std::string constant : cl.constant_order) { + const std::pair<std::string, GDNativeInt> &def = cl.constant_map.find(constant)->second; + + internal::interface->classdb_register_extension_class_integer_constant(internal::library, cl.name, def.first.c_str(), constant.c_str(), def.second); + } + } +} + +void ClassDB::deinitialize(GDNativeInitializationLevel p_level) { + for (const std::pair<std::string, ClassInfo> pair : classes) { + const ClassInfo &cl = pair.second; + if (cl.level != p_level) { + continue; + } + + internal::interface->classdb_unregister_extension_class(internal::library, cl.name); + + for (MethodBind *method : cl.method_order) { + memdelete(method); + } + } +} + +} // namespace godot diff --git a/src/core/Vector3.cpp b/src/core/error_macros.cpp index f0071a4..877f53c 100644 --- a/src/core/Vector3.cpp +++ b/src/core/error_macros.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* Vector3.cpp */ +/* error_macros.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,94 +28,30 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "Vector3.hpp" +#include <godot_cpp/core/error_macros.hpp> -#include "String.hpp" +#include <godot_cpp/godot.hpp> -#include <stdlib.h> - -#include "Basis.hpp" +#include <string> namespace godot { -const Vector3 Vector3::ZERO = Vector3(); -const Vector3 Vector3::ONE = Vector3(1, 1, 1); -const Vector3 Vector3::INF = Vector3(INFINITY, INFINITY, INFINITY); - -const Vector3 Vector3::LEFT = Vector3(-1, 0, 0); -const Vector3 Vector3::RIGHT = Vector3(1, 0, 0); -const Vector3 Vector3::UP = Vector3(0, 1, 0); -const Vector3 Vector3::DOWN = Vector3(0, -1, 0); -const Vector3 Vector3::FORWARD = Vector3(0, 0, -1); -const Vector3 Vector3::BACK = Vector3(0, 0, 1); - -bool Vector3::operator<(const Vector3 &p_v) const { - if (x == p_v.x) { - if (y == p_v.y) - return z < p_v.z; - else - return y < p_v.y; - } else { - return x < p_v.x; - } -} - -bool Vector3::operator<=(const Vector3 &p_v) const { - if (x == p_v.x) { - if (y == p_v.y) - return z <= p_v.z; - else - return y < p_v.y; +void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, bool p_is_warning) { + if (p_is_warning) { + internal::interface->print_warning(p_message, p_function, p_file, p_line); } else { - return x < p_v.x; + internal::interface->print_error(p_message, p_function, p_file, p_line); } } -Vector3 Vector3::cubic_interpolate(const Vector3 &b, const Vector3 &pre_a, const Vector3 &post_b, const real_t t) const { - Vector3 p0 = pre_a; - Vector3 p1 = *this; - Vector3 p2 = b; - Vector3 p3 = post_b; - - real_t t2 = t * t; - real_t t3 = t2 * t; - - Vector3 out; - out = ((p1 * 2.0) + - (-p0 + p2) * t + - (p0 * 2.0 - p1 * 5.0 + p2 * 4 - p3) * t2 + - (-p0 + p1 * 3.0 - p2 * 3.0 + p3) * t3) * - 0.5; - return out; -} - -Basis Vector3::outer(const Vector3 &b) const { - Vector3 row0(x * b.x, x * b.y, x * b.z); - Vector3 row1(y * b.x, y * b.y, y * b.z); - Vector3 row2(z * b.x, z * b.y, z * b.z); - return Basis(row0, row1, row2); -} - -int Vector3::max_axis() const { - return x < y ? (y < z ? 2 : 1) : (x < z ? 2 : 0); -} - -int Vector3::min_axis() const { - return x < y ? (x < z ? 0 : 2) : (y < z ? 1 : 2); -} - -void Vector3::rotate(const Vector3 &p_axis, real_t p_phi) { - *this = Basis(p_axis, p_phi).xform(*this); -} - -void Vector3::snap(real_t p_val) { - x = Math::stepify(x, p_val); - y = Math::stepify(y, p_val); - z = Math::stepify(z, p_val); +void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, bool p_is_warning) { + _err_print_error(p_function, p_file, p_line, p_error, "", p_is_warning); } -Vector3::operator String() const { - return String::num(x) + ", " + String::num(y) + ", " + String::num(z); +void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, const char *p_message, bool fatal) { + std::string fstr(fatal ? "FATAL: " : ""); + std::string err(fstr + "Index " + p_index_str + " = " + std::to_string(p_index) + " is out of bounds (" + p_size_str + " = " + std::to_string(p_size) + ")."); + _err_print_error(p_function, p_file, p_line, err.c_str(), p_message); } } // namespace godot diff --git a/src/core/TagDB.cpp b/src/core/memory.cpp index dced8d1..479c245 100644 --- a/src/core/TagDB.cpp +++ b/src/core/memory.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* TagDP.cpp */ +/* memory.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,51 +28,26 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "TagDB.hpp" +#include <godot_cpp/core/memory.hpp> -#include <unordered_map> - -#include <GodotGlobal.hpp> +#include <godot_cpp/godot.hpp> namespace godot { -namespace _TagDB { - -std::unordered_map<size_t, size_t> parent_to; - -void register_type(size_t type_tag, size_t base_type_tag) { - if (type_tag == base_type_tag) { - return; - } - parent_to[type_tag] = base_type_tag; +void *Memory::alloc_static(size_t p_bytes) { + return internal::interface->mem_alloc(p_bytes); } -bool is_type_known(size_t type_tag) { - return parent_to.find(type_tag) != parent_to.end(); +void *Memory::realloc_static(void *p_memory, size_t p_bytes) { + return internal::interface->mem_realloc(p_memory, p_bytes); } -void register_global_type(const char *name, size_t type_tag, size_t base_type_tag) { - godot::nativescript_1_1_api->godot_nativescript_set_global_type_tag(godot::_RegisterState::language_index, name, (const void *)type_tag); - - register_type(type_tag, base_type_tag); +void Memory::free_static(void *p_ptr) { + internal::interface->mem_free(p_ptr); } -bool is_type_compatible(size_t ask_tag, size_t have_tag) { - if (have_tag == 0) - return false; - - size_t tag = have_tag; - - while (tag != 0) { - if (tag == ask_tag) - return true; - - tag = parent_to[tag]; - } +} // namespace godot - return false; +void *operator new(size_t p_size, const char *p_description) { + return godot::Memory::alloc_static(p_size); } - -} // namespace _TagDB - -} // namespace godot diff --git a/src/core/method_bind.cpp b/src/core/method_bind.cpp new file mode 100644 index 0000000..cd956b6 --- /dev/null +++ b/src/core/method_bind.cpp @@ -0,0 +1,120 @@ +/*************************************************************************/ +/* method_bind.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include <godot_cpp/core/method_bind.hpp> + +namespace godot { + +const char *MethodBind::get_name() const { + return name; +} + +void MethodBind::set_name(const char *p_name) { + name = p_name; +} + +void MethodBind::set_argument_count(int p_count) { + argument_count = p_count; +} + +void MethodBind::set_const(bool p_const) { + _is_const = p_const; +} + +void MethodBind::set_return(bool p_return) { + _has_return = p_return; +} + +void MethodBind::set_argument_names(const std::vector<std::string> &p_names) { + argument_names = p_names; +} + +std::vector<std::string> MethodBind::get_argument_names() const { + return argument_names; +} + +void MethodBind::generate_argument_types(int p_count) { + set_argument_count(p_count); + + if (argument_types != nullptr) { + memdelete_arr(argument_types); + } + + argument_types = memnew_arr(GDNativeVariantType, p_count + 1); + + // -1 means return type. + for (int i = -1; i < p_count; i++) { + argument_types[i + 1] = gen_argument_type(i); + } +} + +GDNativePropertyInfo MethodBind::get_argument_info(int p_argument) const { + GDNativePropertyInfo info = gen_argument_type_info(p_argument); + if (p_argument >= 0) { + info.name = p_argument < (int)argument_names.size() ? argument_names[p_argument].c_str() : ""; + } + return info; +} + +GDNativeVariantType MethodBind::bind_get_argument_type(void *p_method_userdata, int32_t p_argument) { + const MethodBind *bind = reinterpret_cast<const MethodBind *>(p_method_userdata); + return bind->get_argument_type(p_argument); +} + +void MethodBind::bind_get_argument_info(void *p_method_userdata, int32_t p_argument, GDNativePropertyInfo *r_info) { + const MethodBind *bind = reinterpret_cast<const MethodBind *>(p_method_userdata); + *r_info = bind->get_argument_info(p_argument); +} + +GDNativeExtensionClassMethodArgumentMetadata MethodBind::bind_get_argument_metadata(void *p_method_userdata, int32_t p_argument) { + const MethodBind *bind = reinterpret_cast<const MethodBind *>(p_method_userdata); + return bind->get_argument_metadata(p_argument); +} + +void MethodBind::bind_call(void *p_method_userdata, GDExtensionClassInstancePtr p_instance, const GDNativeVariantPtr *p_args, const GDNativeInt p_argument_count, GDNativeVariantPtr r_return, GDNativeCallError *r_error) { + const MethodBind *bind = reinterpret_cast<const MethodBind *>(p_method_userdata); + Variant ret = bind->call(p_instance, p_args, p_argument_count, *r_error); + // This assumes the return value is an empty Variant, so it doesn't need to call the destructor first. + // Since only NativeExtensionMethodBind calls this from the Godot side, it should always be the case. + internal::interface->variant_new_copy(r_return, ret.ptr); +} + +void MethodBind::bind_ptrcall(void *p_method_userdata, GDExtensionClassInstancePtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr r_return) { + const MethodBind *bind = reinterpret_cast<const MethodBind *>(p_method_userdata); + bind->ptrcall(p_instance, p_args, r_return); +} + +MethodBind::~MethodBind() { + if (argument_types) { + memdelete_arr(argument_types); + } +} + +} // namespace godot diff --git a/src/core/RID.cpp b/src/core/object.cpp index fbd4e5c..e4b57fd 100644 --- a/src/core/RID.cpp +++ b/src/core/object.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* RID.cpp */ +/* object.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,52 +28,27 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "RID.hpp" - -#include <gdnative/rid.h> - -#include "GodotGlobal.hpp" +#include <godot_cpp/core/object.hpp> namespace godot { -RID::RID() { - godot::api->godot_rid_new(&_godot_rid); -} - -RID::RID(Object *p) { - godot::api->godot_rid_new_with_resource(&_godot_rid, (const godot_object *)p); -} - -godot_rid RID::_get_godot_rid() const { - return _godot_rid; -} +MethodInfo::MethodInfo() : + flags(METHOD_FLAG_NORMAL) {} -int32_t RID::get_id() const { - return godot::api->godot_rid_get_id(&_godot_rid); -} +MethodInfo::MethodInfo(const char *p_name) : + name(p_name), flags(METHOD_FLAG_NORMAL) {} -bool RID::operator==(const RID &p_other) const { - return godot::api->godot_rid_operator_equal(&_godot_rid, &p_other._godot_rid); +MethodInfo::MethodInfo(Variant::Type ret) : + flags(METHOD_FLAG_NORMAL) { + return_val.type = ret; } -bool RID::operator!=(const RID &p_other) const { - return !(*this == p_other); +MethodInfo::MethodInfo(Variant::Type ret, const char *p_name) : + name(p_name), flags(METHOD_FLAG_NORMAL) { + return_val.type = ret; } -bool RID::operator<(const RID &p_other) const { - return godot::api->godot_rid_operator_less(&_godot_rid, &p_other._godot_rid); -} - -bool RID::operator>(const RID &p_other) const { - return !(*this < p_other) && *this != p_other; -} - -bool RID::operator<=(const RID &p_other) const { - return (*this < p_other) || *this == p_other; -} - -bool RID::operator>=(const RID &p_other) const { - return !(*this < p_other); -} +MethodInfo::MethodInfo(const PropertyInfo &p_ret, const char *p_name) : + name(p_name), return_val(p_ret), flags(METHOD_FLAG_NORMAL) {} } // namespace godot diff --git a/src/gen/.gitignore b/src/gen/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/src/gen/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/src/core/Vector2.cpp b/src/godot.cpp index 006d2a0..3a1ee61 100644 --- a/src/core/Vector2.cpp +++ b/src/godot.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* Vector2.cpp */ +/* godot.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,73 +28,55 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "Vector2.hpp" +#include <godot_cpp/godot.hpp> -#include <gdnative/vector2.h> +#include <godot_cpp/classes/wrapped.hpp> +#include <godot_cpp/core/class_db.hpp> +#include <godot_cpp/core/memory.hpp> +#include <godot_cpp/variant/variant.hpp> -#include "String.hpp" +#include <godot_cpp/core/error_macros.hpp> namespace godot { -const Vector2 Vector2::ZERO = Vector2(); -const Vector2 Vector2::ONE = Vector2(1, 1); -const Vector2 Vector2::INF = Vector2(INFINITY, INFINITY); +namespace internal { -const Vector2 Vector2::LEFT = Vector2(-1, 0); -const Vector2 Vector2::RIGHT = Vector2(1, 0); -const Vector2 Vector2::UP = Vector2(0, -1); -const Vector2 Vector2::DOWN = Vector2(0, 1); +const GDNativeInterface *interface; +GDNativeExtensionClassLibraryPtr library; +void *token; -bool Vector2::operator==(const Vector2 &p_vec2) const { - return x == p_vec2.x && y == p_vec2.y; -} +} // namespace internal -bool Vector2::operator!=(const Vector2 &p_vec2) const { - return x != p_vec2.x || y != p_vec2.y; -} +GDNativeBool GDExtensionBinding::init(const GDNativeInterface *p_interface, const GDNativeExtensionClassLibraryPtr p_library, GDNativeInitialization *r_initialization) { + internal::interface = p_interface; + internal::library = p_library; + internal::token = p_library; -Vector2 Vector2::project(const Vector2 &p_vec) const { - Vector2 v1 = p_vec; - Vector2 v2 = *this; - return v2 * (v1.dot(v2) / v2.dot(v2)); -} + r_initialization->initialize = initialize_level; + r_initialization->deinitialize = deinitialize_level; -Vector2 Vector2::plane_project(real_t p_d, const Vector2 &p_vec) const { - return p_vec - *this * (dot(p_vec) - p_d); -} + Variant::init_bindings(); -Vector2 Vector2::clamped(real_t p_len) const { - real_t l = length(); - Vector2 v = *this; - if (l > 0 && p_len < l) { - v /= l; - v *= p_len; - } - return v; + return true; } -Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_t) const { - Vector2 p0 = p_pre_a; - Vector2 p1 = *this; - Vector2 p2 = p_b; - Vector2 p3 = p_post_b; - - real_t t = p_t; - real_t t2 = t * t; - real_t t3 = t2 * t; +void GDExtensionBinding::initialize_level(void *userdata, GDNativeInitializationLevel p_level) { + ClassDB::initialize(p_level); +} - Vector2 out; - out = ((p1 * 2.0) + - (-p0 + p2) * t + - (p0 * 2.0 - p1 * 5.0 + p2 * 4 - p3) * t2 + - (-p0 + p1 * 3.0 - p2 * 3.0 + p3) * t3) * - 0.5; +void GDExtensionBinding::deinitialize_level(void *userdata, GDNativeInitializationLevel p_level) { + ClassDB::deinitialize(p_level); +} - return out; +void *GDExtensionBinding::create_instance_callback(void *p_token, void *p_instance) { + ERR_FAIL_COND_V_MSG(p_token != internal::library, nullptr, "Asking for creating instance with invalid token."); + Wrapped *wrapped = memnew(Wrapped(p_instance)); + return wrapped; } -Vector2::operator String() const { - return String::num(x) + ", " + String::num(y); +void GDExtensionBinding::free_instance_callback(void *p_token, void *p_instance, void *p_binding) { + ERR_FAIL_COND_MSG(p_token != internal::library, "Asking for freeing instance with invalid token."); + memdelete((Wrapped *)p_binding); } } // namespace godot diff --git a/src/variant/char_string.cpp b/src/variant/char_string.cpp new file mode 100644 index 0000000..975b840 --- /dev/null +++ b/src/variant/char_string.cpp @@ -0,0 +1,267 @@ +/*************************************************************************/ +/* char_string.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include <godot_cpp/variant/char_string.hpp> + +#include <godot_cpp/core/memory.hpp> +#include <godot_cpp/variant/node_path.hpp> +#include <godot_cpp/variant/string.hpp> +#include <godot_cpp/variant/string_name.hpp> + +#include <godot_cpp/godot.hpp> + +namespace godot { + +const char *CharString::get_data() const { + return _data; +} + +CharString::CharString(const char *str, int length) : + _data(str), _length(length) {} + +CharString::~CharString() { + memdelete_arr(_data); +} + +Char16String::Char16String(const char16_t *str, int length) : + _data(str), _length(length) {} + +Char16String::~Char16String() { + memdelete_arr(_data); +} + +Char32String::Char32String(const char32_t *str, int length) : + _data(str), _length(length) {} + +Char32String::~Char32String() { + memdelete_arr(_data); +} + +CharWideString::CharWideString(const wchar_t *str, int length) : + _data(str), _length(length) {} + +CharWideString::~CharWideString() { + memdelete_arr(_data); +} + +// Custom String functions that are not part of bound API. +// It's easier to have them written in C++ directly than in a Python script that generates them. + +String::String(const char *from) { + internal::interface->string_new_with_utf8_chars(ptr, from); +} + +String::String(const wchar_t *from) { + internal::interface->string_new_with_wide_chars(ptr, from); +} + +String::String(const char16_t *from) { + internal::interface->string_new_with_utf16_chars(ptr, from); +} + +String::String(const char32_t *from) { + internal::interface->string_new_with_utf32_chars(ptr, from); +} + +CharString String::utf8() const { + int size = internal::interface->string_to_utf8_chars(ptr, nullptr, 0); + char *cstr = memnew_arr(char, size + 1); + internal::interface->string_to_utf8_chars(ptr, cstr, size + 1); + + cstr[size] = '\0'; + + return CharString(cstr, size + 1); +} + +CharString String::ascii() const { + int size = internal::interface->string_to_latin1_chars(ptr, nullptr, 0); + char *cstr = memnew_arr(char, size + 1); + internal::interface->string_to_latin1_chars(ptr, cstr, size + 1); + + cstr[size] = '\0'; + + return CharString(cstr, size + 1); +} + +Char16String String::utf16() const { + int size = internal::interface->string_to_utf16_chars(ptr, nullptr, 0); + char16_t *cstr = memnew_arr(char16_t, size + 1); + internal::interface->string_to_utf16_chars(ptr, cstr, size + 1); + + cstr[size] = '\0'; + + return Char16String(cstr, size + 1); +} + +Char32String String::utf32() const { + int size = internal::interface->string_to_utf32_chars(ptr, nullptr, 0); + char32_t *cstr = memnew_arr(char32_t, size + 1); + internal::interface->string_to_utf32_chars(ptr, cstr, size + 1); + + cstr[size] = '\0'; + + return Char32String(cstr, size + 1); +} + +CharWideString String::wide_string() const { + int size = internal::interface->string_to_wide_chars(ptr, nullptr, 0); + wchar_t *cstr = memnew_arr(wchar_t, size + 1); + internal::interface->string_to_wide_chars(ptr, cstr, size + 1); + + cstr[size] = '\0'; + + return CharWideString(cstr, size + 1); +} + +String &String::operator=(const char *p_str) { + *this = String(p_str); + return *this; +} + +String &String::operator=(const wchar_t *p_str) { + *this = String(p_str); + return *this; +} + +String &String::operator=(const char16_t *p_str) { + *this = String(p_str); + return *this; +} + +String &String::operator=(const char32_t *p_str) { + *this = String(p_str); + return *this; +} + +bool String::operator==(const char *p_str) const { + return *this == String(p_str); +} + +bool String::operator==(const wchar_t *p_str) const { + return *this == String(p_str); +} + +bool String::operator==(const char16_t *p_str) const { + return *this == String(p_str); +} + +bool String::operator==(const char32_t *p_str) const { + return *this == String(p_str); +} + +bool String::operator!=(const char *p_str) const { + return *this != String(p_str); +} + +bool String::operator!=(const wchar_t *p_str) const { + return *this != String(p_str); +} + +bool String::operator!=(const char16_t *p_str) const { + return *this != String(p_str); +} + +bool String::operator!=(const char32_t *p_str) const { + return *this != String(p_str); +} + +bool operator==(const char *p_chr, const String &p_str) { + return p_str == String(p_chr); +} + +bool operator==(const wchar_t *p_chr, const String &p_str) { + return p_str == String(p_chr); +} + +bool operator==(const char16_t *p_chr, const String &p_str) { + return p_str == String(p_chr); +} + +bool operator==(const char32_t *p_chr, const String &p_str) { + return p_str == String(p_chr); +} + +bool operator!=(const char *p_chr, const String &p_str) { + return !(p_str == p_chr); +} + +bool operator!=(const wchar_t *p_chr, const String &p_str) { + return !(p_str == p_chr); +} + +bool operator!=(const char16_t *p_chr, const String &p_str) { + return !(p_str == p_chr); +} + +bool operator!=(const char32_t *p_chr, const String &p_str) { + return !(p_str == p_chr); +} + +String operator+(const char *p_chr, const String &p_str) { + return String(p_chr) + p_str; +} + +String operator+(const wchar_t *p_chr, const String &p_str) { + return String(p_chr) + p_str; +} + +String operator+(const char16_t *p_chr, const String &p_str) { + return String(p_chr) + p_str; +} + +String operator+(const char32_t *p_chr, const String &p_str) { + return String(p_chr) + p_str; +} + +StringName::StringName(const char *from) : + StringName(String(from)) {} + +StringName::StringName(const wchar_t *from) : + StringName(String(from)) {} + +StringName::StringName(const char16_t *from) : + StringName(String(from)) {} + +StringName::StringName(const char32_t *from) : + StringName(String(from)) {} + +NodePath::NodePath(const char *from) : + NodePath(String(from)) {} + +NodePath::NodePath(const wchar_t *from) : + NodePath(String(from)) {} + +NodePath::NodePath(const char16_t *from) : + NodePath(String(from)) {} + +NodePath::NodePath(const char32_t *from) : + NodePath(String(from)) {} + +} // namespace godot diff --git a/src/variant/variant.cpp b/src/variant/variant.cpp new file mode 100644 index 0000000..a63e3f6 --- /dev/null +++ b/src/variant/variant.cpp @@ -0,0 +1,749 @@ +/*************************************************************************/ +/* variant.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include <godot_cpp/variant/variant.hpp> + +#include <godot_cpp/godot.hpp> + +#include <godot_cpp/core/binder_common.hpp> +#include <godot_cpp/core/defs.hpp> + +#include <utility> + +namespace godot { + +GDNativeVariantFromTypeConstructorFunc Variant::from_type_constructor[Variant::VARIANT_MAX]{}; +GDNativeTypeFromVariantConstructorFunc Variant::to_type_constructor[Variant::VARIANT_MAX]{}; + +void Variant::init_bindings() { + // Start from 1 to skip NIL. + for (int i = 1; i < VARIANT_MAX; i++) { + from_type_constructor[i] = internal::interface->get_variant_from_type_constructor((GDNativeVariantType)i); + to_type_constructor[i] = internal::interface->get_variant_to_type_constructor((GDNativeVariantType)i); + } + + String::init_bindings(); + Vector2::init_bindings(); + Vector2i::init_bindings(); + Rect2::init_bindings(); + Rect2i::init_bindings(); + Vector3::init_bindings(); + Vector3i::init_bindings(); + Transform2D::init_bindings(); + Plane::init_bindings(); + Quaternion::init_bindings(); + AABB::init_bindings(); + Basis::init_bindings(); + Transform3D::init_bindings(); + Color::init_bindings(); + StringName::init_bindings(); + NodePath::init_bindings(); + RID::init_bindings(); + Callable::init_bindings(); + Signal::init_bindings(); + Dictionary::init_bindings(); + Array::init_bindings(); + PackedByteArray::init_bindings(); + PackedInt32Array::init_bindings(); + PackedInt64Array::init_bindings(); + PackedFloat32Array::init_bindings(); + PackedFloat64Array::init_bindings(); + PackedStringArray::init_bindings(); + PackedVector2Array::init_bindings(); + PackedVector3Array::init_bindings(); + PackedColorArray::init_bindings(); +} + +Variant::Variant() { + internal::interface->variant_new_nil(ptr); +} + +Variant::Variant(const GDNativeVariantPtr native_ptr) { + internal::interface->variant_new_copy(ptr, native_ptr); +} + +Variant::Variant(const Variant &other) { + internal::interface->variant_new_copy(ptr, other.ptr); +} + +Variant::Variant(Variant &&other) { + std::swap(opaque, other.opaque); +} + +Variant::Variant(bool v) { + GDNativeBool encoded; + PtrToArg<bool>::encode(v, &encoded); + from_type_constructor[BOOL](ptr, &encoded); +} + +Variant::Variant(int64_t v) { + GDNativeInt encoded; + PtrToArg<int64_t>::encode(v, &encoded); + from_type_constructor[INT](ptr, &encoded); +} + +Variant::Variant(double v) { + double encoded; + PtrToArg<double>::encode(v, &encoded); + from_type_constructor[FLOAT](ptr, &encoded); +} + +Variant::Variant(const String &v) { + from_type_constructor[STRING](ptr, v.ptr); +} + +Variant::Variant(const Vector2 &v) { + from_type_constructor[VECTOR2](ptr, v.ptr); +} + +Variant::Variant(const Vector2i &v) { + from_type_constructor[VECTOR2I](ptr, v.ptr); +} + +Variant::Variant(const Rect2 &v) { + from_type_constructor[RECT2](ptr, v.ptr); +} + +Variant::Variant(const Rect2i &v) { + from_type_constructor[RECT2I](ptr, v.ptr); +} + +Variant::Variant(const Vector3 &v) { + from_type_constructor[VECTOR3](ptr, v.ptr); +} + +Variant::Variant(const Vector3i &v) { + from_type_constructor[VECTOR3I](ptr, v.ptr); +} + +Variant::Variant(const Transform2D &v) { + from_type_constructor[TRANSFORM2D](ptr, v.ptr); +} + +Variant::Variant(const Plane &v) { + from_type_constructor[PLANE](ptr, v.ptr); +} + +Variant::Variant(const Quaternion &v) { + from_type_constructor[QUATERNION](ptr, v.ptr); +} + +Variant::Variant(const godot::AABB &v) { + from_type_constructor[AABB](ptr, v.ptr); +} + +Variant::Variant(const Basis &v) { + from_type_constructor[BASIS](ptr, v.ptr); +} + +Variant::Variant(const Transform3D &v) { + from_type_constructor[TRANSFORM3D](ptr, v.ptr); +} + +Variant::Variant(const Color &v) { + from_type_constructor[COLOR](ptr, v.ptr); +} + +Variant::Variant(const StringName &v) { + from_type_constructor[STRING_NAME](ptr, v.ptr); +} + +Variant::Variant(const NodePath &v) { + from_type_constructor[NODE_PATH](ptr, v.ptr); +} + +Variant::Variant(const godot::RID &v) { + from_type_constructor[RID](ptr, v.ptr); +} + +Variant::Variant(const Object *v) { + from_type_constructor[OBJECT](ptr, v->_owner); +} + +Variant::Variant(const Callable &v) { + from_type_constructor[CALLABLE](ptr, v.ptr); +} + +Variant::Variant(const Signal &v) { + from_type_constructor[SIGNAL](ptr, v.ptr); +} + +Variant::Variant(const Dictionary &v) { + from_type_constructor[DICTIONARY](ptr, v.ptr); +} + +Variant::Variant(const Array &v) { + from_type_constructor[ARRAY](ptr, v.ptr); +} + +Variant::Variant(const PackedByteArray &v) { + from_type_constructor[PACKED_BYTE_ARRAY](ptr, v.ptr); +} + +Variant::Variant(const PackedInt32Array &v) { + from_type_constructor[PACKED_INT32_ARRAY](ptr, v.ptr); +} + +Variant::Variant(const PackedInt64Array &v) { + from_type_constructor[PACKED_INT64_ARRAY](ptr, v.ptr); +} + +Variant::Variant(const PackedFloat32Array &v) { + from_type_constructor[PACKED_FLOAT32_ARRAY](ptr, v.ptr); +} + +Variant::Variant(const PackedFloat64Array &v) { + from_type_constructor[PACKED_FLOAT64_ARRAY](ptr, v.ptr); +} + +Variant::Variant(const PackedStringArray &v) { + from_type_constructor[PACKED_STRING_ARRAY](ptr, v.ptr); +} + +Variant::Variant(const PackedVector2Array &v) { + from_type_constructor[PACKED_VECTOR2_ARRAY](ptr, v.ptr); +} + +Variant::Variant(const PackedVector3Array &v) { + from_type_constructor[PACKED_VECTOR3_ARRAY](ptr, v.ptr); +} + +Variant::Variant(const PackedColorArray &v) { + from_type_constructor[PACKED_COLOR_ARRAY](ptr, v.ptr); +} + +Variant::~Variant() { + internal::interface->variant_destroy(ptr); +} + +Variant::operator bool() const { + GDNativeBool result; + to_type_constructor[BOOL](&result, ptr); + return PtrToArg<bool>::convert(&result); +} + +Variant::operator int64_t() const { + GDNativeInt result; + to_type_constructor[INT](&result, ptr); + return PtrToArg<int64_t>::convert(&result); +} + +Variant::operator int32_t() const { + return static_cast<int32_t>(operator int64_t()); +} + +Variant::operator uint64_t() const { + return static_cast<uint64_t>(operator int64_t()); +} + +Variant::operator uint32_t() const { + return static_cast<uint32_t>(operator int64_t()); +} + +Variant::operator double() const { + double result; + to_type_constructor[FLOAT](&result, ptr); + return PtrToArg<double>::convert(&result); +} + +Variant::operator float() const { + return static_cast<float>(operator double()); +} + +Variant::operator String() const { + String result; + to_type_constructor[STRING](result.ptr, ptr); + return result; +} + +Variant::operator Vector2() const { + Vector2 result; + to_type_constructor[VECTOR2](result.ptr, ptr); + return result; +} + +Variant::operator Vector2i() const { + Vector2i result; + to_type_constructor[VECTOR2I](result.ptr, ptr); + return result; +} + +Variant::operator Rect2() const { + Rect2 result; + to_type_constructor[RECT2](result.ptr, ptr); + return result; +} + +Variant::operator Rect2i() const { + Rect2i result; + to_type_constructor[RECT2I](result.ptr, ptr); + return result; +} + +Variant::operator Vector3() const { + Vector3 result; + to_type_constructor[VECTOR3](result.ptr, ptr); + return result; +} + +Variant::operator Vector3i() const { + Vector3i result; + to_type_constructor[VECTOR3I](result.ptr, ptr); + return result; +} + +Variant::operator Transform2D() const { + Transform2D result; + to_type_constructor[TRANSFORM2D](result.ptr, ptr); + return result; +} + +Variant::operator Plane() const { + Plane result; + to_type_constructor[PLANE](result.ptr, ptr); + return result; +} + +Variant::operator Quaternion() const { + Quaternion result; + to_type_constructor[QUATERNION](result.ptr, ptr); + return result; +} + +Variant::operator godot::AABB() const { + godot::AABB result; + to_type_constructor[AABB](result.ptr, ptr); + return result; +} + +Variant::operator Basis() const { + Basis result; + to_type_constructor[BASIS](result.ptr, ptr); + return result; +} + +Variant::operator Transform3D() const { + Transform3D result; + to_type_constructor[TRANSFORM3D](result.ptr, ptr); + return result; +} + +Variant::operator Color() const { + Color result; + to_type_constructor[COLOR](result.ptr, ptr); + return result; +} + +Variant::operator StringName() const { + StringName result; + to_type_constructor[STRING_NAME](result.ptr, ptr); + return result; +} + +Variant::operator NodePath() const { + NodePath result; + to_type_constructor[NODE_PATH](result.ptr, ptr); + return result; +} + +Variant::operator godot::RID() const { + godot::RID result; + to_type_constructor[RID](result.ptr, ptr); + return result; +} + +Variant::operator Object *() const { + GodotObject *obj; + to_type_constructor[OBJECT](&obj, ptr); + return reinterpret_cast<Object *>(internal::interface->object_get_instance_binding(obj, internal::token, &Object::___binding_callbacks)); +} + +Variant::operator Callable() const { + Callable result; + to_type_constructor[CALLABLE](result.ptr, ptr); + return result; +} + +Variant::operator Signal() const { + Signal result; + to_type_constructor[SIGNAL](result.ptr, ptr); + return result; +} + +Variant::operator Dictionary() const { + Dictionary result; + to_type_constructor[DICTIONARY](result.ptr, ptr); + return result; +} + +Variant::operator Array() const { + Array result; + to_type_constructor[ARRAY](result.ptr, ptr); + return result; +} + +Variant::operator PackedByteArray() const { + PackedByteArray result; + to_type_constructor[PACKED_BYTE_ARRAY](result.ptr, ptr); + return result; +} + +Variant::operator PackedInt32Array() const { + PackedInt32Array result; + to_type_constructor[PACKED_INT32_ARRAY](result.ptr, ptr); + return result; +} + +Variant::operator PackedInt64Array() const { + PackedInt64Array result; + to_type_constructor[PACKED_INT64_ARRAY](result.ptr, ptr); + return result; +} + +Variant::operator PackedFloat32Array() const { + PackedFloat32Array result; + to_type_constructor[PACKED_FLOAT32_ARRAY](result.ptr, ptr); + return result; +} + +Variant::operator PackedFloat64Array() const { + PackedFloat64Array result; + to_type_constructor[PACKED_FLOAT64_ARRAY](result.ptr, ptr); + return result; +} + +Variant::operator PackedStringArray() const { + PackedStringArray result; + to_type_constructor[PACKED_STRING_ARRAY](result.ptr, ptr); + return result; +} + +Variant::operator PackedVector2Array() const { + PackedVector2Array result; + to_type_constructor[PACKED_VECTOR2_ARRAY](result.ptr, ptr); + return result; +} + +Variant::operator PackedVector3Array() const { + PackedVector3Array result; + to_type_constructor[PACKED_VECTOR3_ARRAY](result.ptr, ptr); + return result; +} + +Variant::operator PackedColorArray() const { + PackedColorArray result; + to_type_constructor[PACKED_COLOR_ARRAY](result.ptr, ptr); + return result; +} + +Variant::operator const GDNativeVariantPtr() const { + return reinterpret_cast<const GDNativeVariantPtr>(const_cast<uint8_t(*)[GODOT_CPP_VARIANT_SIZE]>(&opaque)); +} + +Variant::operator GDNativeVariantPtr() { + return reinterpret_cast<const GDNativeVariantPtr>(&opaque); +} + +Variant &Variant::operator=(const Variant &other) { + clear(); + internal::interface->variant_new_copy(ptr, other.ptr); + return *this; +} + +Variant &Variant::operator=(Variant &&other) { + std::swap(opaque, other.opaque); + return *this; +} + +bool Variant::operator==(const Variant &other) const { + if (get_type() != other.get_type()) { + return false; + } + bool valid = false; + Variant result; + evaluate(OP_EQUAL, *this, other, result, valid); + return result.operator bool(); +} + +bool Variant::operator!=(const Variant &other) const { + if (get_type() != other.get_type()) { + return true; + } + bool valid = false; + Variant result; + evaluate(OP_NOT_EQUAL, *this, other, result, valid); + return result.operator bool(); +} + +bool Variant::operator<(const Variant &other) const { + if (get_type() != other.get_type()) { + return get_type() < other.get_type(); + } + bool valid = false; + Variant result; + evaluate(OP_LESS, *this, other, result, valid); + return result.operator bool(); +} + +void Variant::operator=(const GDNativeVariantPtr other_ptr) { + internal::interface->variant_destroy(ptr); + internal::interface->variant_new_copy(ptr, other_ptr); +} + +void Variant::call(const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDNativeCallError &r_error) { + internal::interface->variant_call(ptr, method.ptr, reinterpret_cast<const GDNativeVariantPtr *>(const_cast<Variant **>(args)), argcount, r_ret.ptr, &r_error); +} + +void Variant::call_static(Variant::Type type, const StringName &method, const Variant **args, int argcount, Variant &r_ret, GDNativeCallError &r_error) { + internal::interface->variant_call_static(static_cast<GDNativeVariantType>(type), method.ptr, reinterpret_cast<const GDNativeVariantPtr *>(const_cast<Variant **>(args)), argcount, r_ret.ptr, &r_error); +} + +void Variant::evaluate(const Operator &op, const Variant &a, const Variant &b, Variant &r_ret, bool &r_valid) { + GDNativeBool valid; + internal::interface->variant_evaluate(static_cast<GDNativeVariantOperator>(op), a.ptr, b.ptr, r_ret.ptr, &valid); + r_valid = PtrToArg<bool>::convert(&valid); +} + +void Variant::set(const Variant &key, const Variant &value, bool *r_valid) { + GDNativeBool valid; + internal::interface->variant_set(ptr, key.ptr, value.ptr, &valid); + if (r_valid) { + *r_valid = PtrToArg<bool>::convert(&valid); + } +} + +void Variant::set_named(const StringName &name, const Variant &value, bool &r_valid) { + GDNativeBool valid; + internal::interface->variant_set_named(ptr, name.ptr, value.ptr, &valid); + r_valid = PtrToArg<bool>::convert(&valid); +} + +void Variant::set_indexed(int64_t index, const Variant &value, bool &r_valid, bool &r_oob) { + GDNativeBool valid, oob; + internal::interface->variant_set_indexed(ptr, index, value.ptr, &valid, &oob); + r_valid = PtrToArg<bool>::convert(&valid); + r_oob = PtrToArg<bool>::convert(&oob); +} + +void Variant::set_keyed(const Variant &key, const Variant &value, bool &r_valid) { + GDNativeBool valid; + internal::interface->variant_set_keyed(ptr, key.ptr, value.ptr, &valid); + r_valid = PtrToArg<bool>::convert(&valid); +} + +Variant Variant::get(const Variant &key, bool *r_valid) const { + Variant result; + GDNativeBool valid; + internal::interface->variant_get(ptr, key.ptr, result.ptr, &valid); + if (r_valid) { + *r_valid = PtrToArg<bool>::convert(&valid); + } + return result; +} + +Variant Variant::get_named(const StringName &name, bool &r_valid) const { + Variant result; + GDNativeBool valid; + internal::interface->variant_get_named(ptr, name.ptr, result.ptr, &valid); + r_valid = PtrToArg<bool>::convert(&valid); + return result; +} + +Variant Variant::get_indexed(int64_t index, bool &r_valid, bool &r_oob) const { + Variant result; + GDNativeBool valid; + GDNativeBool oob; + internal::interface->variant_get_indexed(ptr, index, result.ptr, &valid, &oob); + r_valid = PtrToArg<bool>::convert(&valid); + r_oob = PtrToArg<bool>::convert(&oob); + return result; +} + +Variant Variant::get_keyed(const Variant &key, bool &r_valid) const { + Variant result; + GDNativeBool valid; + internal::interface->variant_get_keyed(ptr, key.ptr, result.ptr, &valid); + r_valid = PtrToArg<bool>::convert(&valid); + return result; +} + +bool Variant::in(const Variant &index, bool *r_valid) const { + Variant result; + bool valid; + evaluate(OP_IN, *this, index, result, valid); + if (r_valid) { + *r_valid = valid; + } + return result.operator bool(); +} + +bool Variant::iter_init(Variant &r_iter, bool &r_valid) const { + GDNativeBool valid; + internal::interface->variant_iter_init(ptr, r_iter.ptr, &valid); + return PtrToArg<bool>::convert(&valid); +} + +bool Variant::iter_next(Variant &r_iter, bool &r_valid) const { + GDNativeBool valid; + internal::interface->variant_iter_next(ptr, r_iter.ptr, &valid); + return PtrToArg<bool>::convert(&valid); +} + +Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const { + Variant result; + GDNativeBool valid; + internal::interface->variant_iter_get(ptr, r_iter.ptr, result.ptr, &valid); + r_valid = PtrToArg<bool>::convert(&valid); + return result; +} + +Variant::Type Variant::get_type() const { + return static_cast<Variant::Type>(internal::interface->variant_get_type(ptr)); +} + +bool Variant::has_method(const StringName &method) const { + GDNativeBool has = internal::interface->variant_has_method(ptr, method.ptr); + return PtrToArg<bool>::convert(&has); +} + +bool Variant::has_key(const Variant &key, bool *r_valid) const { + GDNativeBool valid; + GDNativeBool has = internal::interface->variant_has_key(ptr, key.ptr, &valid); + if (r_valid) { + *r_valid = PtrToArg<bool>::convert(&valid); + } + return PtrToArg<bool>::convert(&has); +} + +bool Variant::has_member(Variant::Type type, const StringName &member) { + GDNativeBool has = internal::interface->variant_has_member(static_cast<GDNativeVariantType>(type), member.ptr); + return PtrToArg<bool>::convert(&has); +} + +bool Variant::hash_compare(const Variant &variant) const { + GDNativeBool compare = internal::interface->variant_hash_compare(ptr, variant.ptr); + return PtrToArg<bool>::convert(&compare); +} + +bool Variant::booleanize() const { + GDNativeBool booleanized = internal::interface->variant_booleanize(ptr); + return PtrToArg<bool>::convert(&booleanized); +} + +String Variant::stringify() const { + String result; + internal::interface->variant_stringify(ptr, result.ptr); + return result; +} + +Variant Variant::duplicate(bool deep) const { + Variant result; + GDNativeBool _deep; + PtrToArg<bool>::encode(deep, &_deep); + internal::interface->variant_duplicate(ptr, result.ptr, _deep); + return result; +} + +void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst) { + internal::interface->variant_blend(a.ptr, b.ptr, c, r_dst.ptr); +} + +void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &r_dst) { + internal::interface->variant_interpolate(a.ptr, b.ptr, c, r_dst.ptr); +} + +String Variant::get_type_name(Variant::Type type) { + String result; + internal::interface->variant_get_type_name(static_cast<GDNativeVariantType>(type), result.ptr); + return result; +} + +bool Variant::can_convert(Variant::Type from, Variant::Type to) { + GDNativeBool can; + internal::interface->variant_can_convert(static_cast<GDNativeVariantType>(from), static_cast<GDNativeVariantType>(to)); + return PtrToArg<bool>::convert(&can); +} + +bool Variant::can_convert_strict(Variant::Type from, Variant::Type to) { + GDNativeBool can; + internal::interface->variant_can_convert_strict(static_cast<GDNativeVariantType>(from), static_cast<GDNativeVariantType>(to)); + return PtrToArg<bool>::convert(&can); +} + +void Variant::clear() { + static const bool needs_deinit[Variant::VARIANT_MAX] = { + false, //NIL, + false, //BOOL, + false, //INT, + false, //FLOAT, + true, //STRING, + false, //VECTOR2, + false, //VECTOR2I, + false, //RECT2, + false, //RECT2I, + false, //VECTOR3, + false, //VECTOR3I, + true, //TRANSFORM2D, + false, //PLANE, + false, //QUATERNION, + true, //AABB, + true, //BASIS, + true, //TRANSFORM, + + // misc types + false, //COLOR, + true, //STRING_NAME, + true, //NODE_PATH, + false, //RID, + true, //OBJECT, + true, //CALLABLE, + true, //SIGNAL, + true, //DICTIONARY, + true, //ARRAY, + + // typed arrays + true, //PACKED_BYTE_ARRAY, + true, //PACKED_INT32_ARRAY, + true, //PACKED_INT64_ARRAY, + true, //PACKED_FLOAT32_ARRAY, + true, //PACKED_FLOAT64_ARRAY, + true, //PACKED_STRING_ARRAY, + true, //PACKED_VECTOR2_ARRAY, + true, //PACKED_VECTOR3_ARRAY, + true, //PACKED_COLOR_ARRAY, + }; + + if (unlikely(needs_deinit[get_type()])) { // Make it fast for types that don't need deinit. + internal::interface->variant_destroy(ptr); + } + internal::interface->variant_new_nil(ptr); +} + +} // namespace godot |