godot-cpp
godot-cpp copied to clipboard
class Gradient is missing a function 'get_color_at_offset'.
Function get_color_at_offset exists in gradient.h of engine but is missing in gradient.hpp of extension.
Also _update_sorting() is missing.
I see why its missing. Struct Point is unexposed. I had to recreate function like this:
class Gradient2 : public Gradient
{
GDCLASS(Gradient2 , Gradient)
public:
static void _bind_methods(){};
struct Point
{
Color color;
double offset;
};
_FORCE_INLINE_ Color get_color_at_offset(float p_offset) {
if (!get_point_count()) {
return Color(0, 0, 0, 1);
}
//_update_sorting();
// Binary search.
int low = 0;
int high = get_point_count() - 1;
int middle = 0;
#ifdef DEBUG_ENABLED
if (low > high) {
ERR_PRINT("low > high, this may be a bug");
}
#endif
while (low <= high) {
middle = (low + high) / 2;
const double &offset = get_offset(middle);
if (offset > p_offset) {
high = middle - 1; //search low end of array
} else if (offset < p_offset) {
low = middle + 1; //search high end of array
} else {
return get_color(middle);
}
}
// Return sampled value.
if (get_offset(middle) > p_offset) {
middle--;
}
int first = middle;
int second = middle + 1;
if (second >= get_point_count()) {
return get_color(get_point_count() - 1);
}
if (first < 0) {
return get_color(0);
}
const Point &pointFirst = GetPoint(first);
const Point &pointSecond = GetPoint(second);
switch (get_interpolation_mode()) {
case GRADIENT_INTERPOLATE_LINEAR: {
return pointFirst.color.lerp(pointSecond.color, (p_offset - pointFirst.offset) / (pointSecond.offset - pointFirst.offset));
} break;
case GRADIENT_INTERPOLATE_CONSTANT: {
return pointFirst.color;
} break;
case GRADIENT_INTERPOLATE_CUBIC: {
int p0 = first - 1;
int p3 = second + 1;
if (p3 >= get_point_count()) {
p3 = second;
}
if (p0 < 0) {
p0 = first;
}
const Point &pointP0 = GetPoint(p0);
const Point &pointP3 = GetPoint(p3);
float x = (p_offset - pointFirst.offset) / (pointSecond.offset - pointFirst.offset);
float r = Math::cubic_interpolate(pointFirst.color.r, pointSecond.color.r, pointP0.color.r, pointP3.color.r, x);
float g = Math::cubic_interpolate(pointFirst.color.g, pointSecond.color.g, pointP0.color.g, pointP3.color.g, x);
float b = Math::cubic_interpolate(pointFirst.color.b, pointSecond.color.b, pointP0.color.b, pointP3.color.b, x);
float a = Math::cubic_interpolate(pointFirst.color.a, pointSecond.color.a, pointP0.color.a, pointP3.color.a, x);
return Color(r, g, b, a);
} break;
default: {
// Fallback to linear interpolation.
return pointFirst.color.lerp(pointSecond.color, (p_offset - pointFirst.offset) / (pointSecond.offset - pointFirst.offset));
}
}
}
Point GetPoint(int32_t p)
{
return {get_color(p),get_offset(p)};
}
};
Maybe Struct Point could be moved to public field and then exposed?