aboutsummaryrefslogtreecommitdiff
path: root/extension/src/openvic-extension/utility/Utilities.cpp
diff options
context:
space:
mode:
author hop311 <hop3114@gmail.com>2023-12-04 01:12:16 +0100
committer hop311 <hop3114@gmail.com>2023-12-04 01:18:15 +0100
commit6e350a3dc0b596b1f76fab3b943b67b7713ea4fa (patch)
treeb963c671239ecd693d4162afe4b1b9d3b064554e /extension/src/openvic-extension/utility/Utilities.cpp
parent9165f5980c5cfe75b3bad4303a5822340f6adcfc (diff)
Sim submodule update + extension compatibility
Diffstat (limited to 'extension/src/openvic-extension/utility/Utilities.cpp')
-rw-r--r--extension/src/openvic-extension/utility/Utilities.cpp114
1 files changed, 20 insertions, 94 deletions
diff --git a/extension/src/openvic-extension/utility/Utilities.cpp b/extension/src/openvic-extension/utility/Utilities.cpp
index 5940373..e3bcce6 100644
--- a/extension/src/openvic-extension/utility/Utilities.cpp
+++ b/extension/src/openvic-extension/utility/Utilities.cpp
@@ -4,6 +4,7 @@
#include <godot_cpp/classes/file_access.hpp>
#include <godot_cpp/classes/resource_loader.hpp>
+#include <godot_cpp/classes/translation_server.hpp>
#include <godot_cpp/variant/utility_functions.hpp>
#include <gli/convert.hpp>
@@ -12,6 +13,24 @@
using namespace godot;
using namespace OpenVic;
+/* Date formatted like this: "January 1, 1836" (with the month localised, if possible). */
+String Utilities::date_to_formatted_string(Date date) {
+ std::string const& month_name = date.get_month_name();
+ const String day_and_year = " " + String::num_int64(date.get_day()) + ", " + String::num_int64(date.get_year());
+ TranslationServer const* server = TranslationServer::get_singleton();
+ if (server != nullptr) {
+ return server->translate(std_to_godot_string_name(month_name)) + day_and_year;
+ } else {
+ return std_to_godot_string(month_name) + day_and_year;
+ }
+}
+
+Ref<Resource> Utilities::load_resource(String const& path, String const& type_hint) {
+ ResourceLoader* loader = ResourceLoader::get_singleton();
+ ERR_FAIL_NULL_V(loader, nullptr);
+ return loader->load(path, type_hint);
+}
+
static Ref<Image> load_dds_image(String const& path) {
gli::texture2d texture { gli::load_dds(Utilities::godot_to_std_string(path)) };
if (texture.empty()) {
@@ -42,7 +61,7 @@ static Ref<Image> load_dds_image(String const& path) {
PackedByteArray pixels;
pixels.resize(size);
- /* Index offset used to control whether we are reading */
+ /* Index offset used to control whether we are reading */
const size_t rb_idx = 2 * needs_bgr_to_rgb;
uint8_t const* ptr = static_cast<uint8_t const*>(texture.data());
for (size_t i = 0; i < size; i += 4) {
@@ -72,96 +91,3 @@ Ref<FontFile> Utilities::load_godot_font(String const& fnt_path, Ref<Image> cons
}
return font;
}
-
-// Get the polar coordinates of a pixel relative to the center
-static Vector2 getPolar(Vector2 UVin, Vector2 center) {
- Vector2 relcoord = (UVin - center);
- float dist = relcoord.length();
- float theta = std::numbers::pi / 2 + atan2(relcoord.y, relcoord.x);
- if (theta < 0.0f) {
- theta += std::numbers::pi * 2;
- }
- return { dist, theta };
-}
-
-// From thebookofshaders, returns a gradient falloff
-static inline float parabola(float base, float x, float k) {
- return powf(base * x * (1.0 - x), k);
-}
-
-static inline float parabola_shadow(float base, float x) {
- return base * x * x;
-}
-
-static Color pie_chart_fragment(
- Vector2 UV, float radius, Array const& stopAngles, Array const& colours, Vector2 shadow_displacement,
- float shadow_tightness, float shadow_radius, float shadow_thickness, Color trim_colour, float trim_size,
- float gradient_falloff, float gradient_base, bool donut, bool donut_inner_trim, float donut_inner_radius
-) {
-
- Vector2 coords = getPolar(UV, { 0.5, 0.5 });
- float dist = coords.x;
- float theta = coords.y;
-
- Vector2 shadow_polar = getPolar(UV, shadow_displacement);
- float shadow_peak = radius + (radius - donut_inner_radius) / 2.0;
- float shadow_gradient =
- shadow_thickness + parabola_shadow(shadow_tightness * -10.0, shadow_polar.x + shadow_peak - shadow_radius);
-
- // Inner hole of the donut => make it transparent
- if (donut && dist <= donut_inner_radius) {
- return { 0.1, 0.1, 0.1, shadow_gradient };
- }
- // Inner trim
- else if (donut && donut_inner_trim && dist <= donut_inner_radius + trim_size) {
- return { trim_colour, 1.0 };
- }
- // Interior
- else if (dist <= radius - trim_size) {
- Color col { 1.0f, 0.0f, 0.0f };
- for (int i = 0; i < stopAngles.size(); i++) {
- if (theta <= float(stopAngles[i])) {
- col = colours[i];
- break;
- }
- }
- float gradient = parabola(gradient_base, dist, gradient_falloff);
- return { col * (1.0 - gradient), 1.0 };
- }
- // Outer trim
- else if (dist <= radius) {
- return { trim_colour, 1.0 };
- }
- // Outside the circle
- else {
- return { 0.1, 0.1, 0.1, shadow_gradient };
- }
-}
-
-void Utilities::draw_pie_chart(
- Ref<Image> image, Array const& stopAngles, Array const& colours, float radius, Vector2 shadow_displacement,
- float shadow_tightness, float shadow_radius, float shadow_thickness, Color trim_colour, float trim_size,
- float gradient_falloff, float gradient_base, bool donut, bool donut_inner_trim, float donut_inner_radius
-) {
-
- ERR_FAIL_NULL_EDMSG(image, "Cannot draw pie chart to null image.");
- const int32_t width = image->get_width();
- const int32_t height = image->get_height();
- ERR_FAIL_COND_EDMSG(width <= 0 || height <= 0, "Cannot draw pie chart to empty image.");
- if (width != height) {
- UtilityFunctions::push_warning("Drawing pie chart to non-square image: ", width, "x", height);
- }
- const int32_t size = std::min(width, height);
- for (int32_t y = 0; y < size; ++y) {
- for (int32_t x = 0; x < size; ++x) {
- image->set_pixel(
- x, y,
- pie_chart_fragment(
- Vector2 { static_cast<float>(x), static_cast<float>(y) } / size, radius, stopAngles, colours,
- shadow_displacement, shadow_tightness, shadow_radius, shadow_thickness, trim_colour, trim_size,
- gradient_falloff, gradient_base, donut, donut_inner_trim, donut_inner_radius
- )
- );
- }
- }
-}