Use LocalVector for Curve and Gradient

This commit is contained in:
Nazarii
2025-01-08 11:13:05 +02:00
parent 76c8e76560
commit 8bfb5d74b3
7 changed files with 141 additions and 149 deletions

View File

@@ -200,10 +200,11 @@ TEST_CASE("[NoiseTexture2D][SceneTree] Generating a basic noise texture with mip
noise_texture->set_noise(noise); noise_texture->set_noise(noise);
Ref<Gradient> gradient = memnew(Gradient); Ref<Gradient> gradient = memnew(Gradient);
Vector<Gradient::Point> points; Vector<float> offsets = { 0.0, 1.0 };
points.push_back({ 0.0, Color(1, 0, 0) }); Vector<Color> colors = { Color(1, 0, 0), Color(0, 0, 1) };
points.push_back({ 1.0, Color(0, 0, 1) }); gradient->set_offsets(offsets);
gradient->set_points(points); gradient->set_colors(colors);
noise_texture->set_color_ramp(gradient); noise_texture->set_color_ramp(gradient);
noise_texture->set_width(16); noise_texture->set_width(16);
noise_texture->set_height(16); noise_texture->set_height(16);
@@ -251,10 +252,12 @@ TEST_CASE("[NoiseTexture2D][SceneTree] Generating a seamless noise texture") {
SUBCASE("16x16 modulated with default (transparent)black and white gradient (RGBA8), with seamless blend skirt of 1.0") { SUBCASE("16x16 modulated with default (transparent)black and white gradient (RGBA8), with seamless blend skirt of 1.0") {
Ref<Gradient> gradient = memnew(Gradient); Ref<Gradient> gradient = memnew(Gradient);
Vector<Gradient::Point> points;
points.push_back({ 0.0, Color(0, 0, 0, 0) }); Vector<float> offsets = { 0.0, 1.0 };
points.push_back({ 1.0, Color(1, 1, 1, 1) }); Vector<Color> colors = { Color(0, 0, 0, 0), Color(1, 1, 1, 1) };
gradient->set_points(points); gradient->set_offsets(offsets);
gradient->set_colors(colors);
noise_texture->set_color_ramp(gradient); noise_texture->set_color_ramp(gradient);
noise_texture->set_seamless_blend_skirt(1.0); noise_texture->set_seamless_blend_skirt(1.0);
noise_texture->connect_changed(callable_mp(tester.ptr(), &NoiseTextureTester::check_seamless_texture_rgba)); noise_texture->connect_changed(callable_mp(tester.ptr(), &NoiseTextureTester::check_seamless_texture_rgba));

View File

@@ -184,10 +184,11 @@ TEST_CASE("[NoiseTexture3D][SceneTree] Generating a basic noise texture with mip
noise_texture->set_noise(noise); noise_texture->set_noise(noise);
Ref<Gradient> gradient = memnew(Gradient); Ref<Gradient> gradient = memnew(Gradient);
Vector<Gradient::Point> points; Vector<float> offsets = { 0.0, 1.0 };
points.push_back({ 0.0, Color(1, 0, 0) }); Vector<Color> colors = { Color(1, 0, 0), Color(0, 0, 1) };
points.push_back({ 1.0, Color(0, 0, 1) }); gradient->set_offsets(offsets);
gradient->set_points(points); gradient->set_colors(colors);
noise_texture->set_color_ramp(gradient); noise_texture->set_color_ramp(gradient);
noise_texture->set_width(16); noise_texture->set_width(16);
noise_texture->set_height(16); noise_texture->set_height(16);
@@ -219,10 +220,12 @@ TEST_CASE("[NoiseTexture3D][SceneTree] Generating a seamless noise texture") {
SUBCASE("16x16x16 modulated with default (transparent)black and white gradient (RGBA8), with seamless blend skirt of 1.0") { SUBCASE("16x16x16 modulated with default (transparent)black and white gradient (RGBA8), with seamless blend skirt of 1.0") {
Ref<Gradient> gradient = memnew(Gradient); Ref<Gradient> gradient = memnew(Gradient);
Vector<Gradient::Point> points;
points.push_back({ 0.0, Color(0, 0, 0, 0) }); Vector<float> offsets = { 0.0, 1.0 };
points.push_back({ 1.0, Color(1, 1, 1, 1) }); Vector<Color> colors = { Color(0, 0, 0, 0), Color(1, 1, 1, 1) };
gradient->set_points(points); gradient->set_offsets(offsets);
gradient->set_colors(colors);
noise_texture->set_color_ramp(gradient); noise_texture->set_color_ramp(gradient);
noise_texture->set_seamless_blend_skirt(1.0); noise_texture->set_seamless_blend_skirt(1.0);
noise_texture->connect_changed(callable_mp(tester.ptr(), &NoiseTexture3DTester::check_seamless_texture_rgba)); noise_texture->connect_changed(callable_mp(tester.ptr(), &NoiseTexture3DTester::check_seamless_texture_rgba));

View File

@@ -149,7 +149,7 @@ int Curve::get_index(real_t p_offset) const {
void Curve::clean_dupes() { void Curve::clean_dupes() {
bool dirty = false; bool dirty = false;
for (int i = 1; i < _points.size(); ++i) { for (uint32_t i = 1; i < _points.size(); ++i) {
real_t diff = _points[i - 1].position.x - _points[i].position.x; real_t diff = _points[i - 1].position.x - _points[i].position.x;
if (diff <= CMP_EPSILON) { if (diff <= CMP_EPSILON) {
_points.remove_at(i); _points.remove_at(i);
@@ -164,65 +164,65 @@ void Curve::clean_dupes() {
} }
void Curve::set_point_left_tangent(int p_index, real_t p_tangent) { void Curve::set_point_left_tangent(int p_index, real_t p_tangent) {
ERR_FAIL_INDEX(p_index, _points.size()); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_index, _points.size());
_points.write[p_index].left_tangent = p_tangent; _points[p_index].left_tangent = p_tangent;
_points.write[p_index].left_mode = TANGENT_FREE; _points[p_index].left_mode = TANGENT_FREE;
mark_dirty(); mark_dirty();
} }
void Curve::set_point_right_tangent(int p_index, real_t p_tangent) { void Curve::set_point_right_tangent(int p_index, real_t p_tangent) {
ERR_FAIL_INDEX(p_index, _points.size()); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_index, _points.size());
_points.write[p_index].right_tangent = p_tangent; _points[p_index].right_tangent = p_tangent;
_points.write[p_index].right_mode = TANGENT_FREE; _points[p_index].right_mode = TANGENT_FREE;
mark_dirty(); mark_dirty();
} }
void Curve::set_point_left_mode(int p_index, TangentMode p_mode) { void Curve::set_point_left_mode(int p_index, TangentMode p_mode) {
ERR_FAIL_INDEX(p_index, _points.size()); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_index, _points.size());
_points.write[p_index].left_mode = p_mode; _points[p_index].left_mode = p_mode;
if (p_index > 0) { if (p_index > 0) {
if (p_mode == TANGENT_LINEAR) { if (p_mode == TANGENT_LINEAR) {
Vector2 v = (_points[p_index - 1].position - _points[p_index].position).normalized(); Vector2 v = (_points[p_index - 1].position - _points[p_index].position).normalized();
_points.write[p_index].left_tangent = v.y / v.x; _points[p_index].left_tangent = v.y / v.x;
} }
} }
mark_dirty(); mark_dirty();
} }
void Curve::set_point_right_mode(int p_index, TangentMode p_mode) { void Curve::set_point_right_mode(int p_index, TangentMode p_mode) {
ERR_FAIL_INDEX(p_index, _points.size()); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_index, _points.size());
_points.write[p_index].right_mode = p_mode; _points[p_index].right_mode = p_mode;
if (p_index + 1 < _points.size()) { if ((uint32_t)p_index + 1 < _points.size()) {
if (p_mode == TANGENT_LINEAR) { if (p_mode == TANGENT_LINEAR) {
Vector2 v = (_points[p_index + 1].position - _points[p_index].position).normalized(); Vector2 v = (_points[p_index + 1].position - _points[p_index].position).normalized();
_points.write[p_index].right_tangent = v.y / v.x; _points[p_index].right_tangent = v.y / v.x;
} }
} }
mark_dirty(); mark_dirty();
} }
real_t Curve::get_point_left_tangent(int p_index) const { real_t Curve::get_point_left_tangent(int p_index) const {
ERR_FAIL_INDEX_V(p_index, _points.size(), 0); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_index, _points.size(), 0);
return _points[p_index].left_tangent; return _points[p_index].left_tangent;
} }
real_t Curve::get_point_right_tangent(int p_index) const { real_t Curve::get_point_right_tangent(int p_index) const {
ERR_FAIL_INDEX_V(p_index, _points.size(), 0); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_index, _points.size(), 0);
return _points[p_index].right_tangent; return _points[p_index].right_tangent;
} }
Curve::TangentMode Curve::get_point_left_mode(int p_index) const { Curve::TangentMode Curve::get_point_left_mode(int p_index) const {
ERR_FAIL_INDEX_V(p_index, _points.size(), TANGENT_FREE); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_index, _points.size(), TANGENT_FREE);
return _points[p_index].left_mode; return _points[p_index].left_mode;
} }
Curve::TangentMode Curve::get_point_right_mode(int p_index) const { Curve::TangentMode Curve::get_point_right_mode(int p_index) const {
ERR_FAIL_INDEX_V(p_index, _points.size(), TANGENT_FREE); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_index, _points.size(), TANGENT_FREE);
return _points[p_index].right_mode; return _points[p_index].right_mode;
} }
void Curve::_remove_point(int p_index) { void Curve::_remove_point(int p_index) {
ERR_FAIL_INDEX(p_index, _points.size()); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_index, _points.size());
_points.remove_at(p_index); _points.remove_at(p_index);
mark_dirty(); mark_dirty();
} }
@@ -243,21 +243,21 @@ void Curve::clear_points() {
} }
void Curve::set_point_value(int p_index, real_t p_position) { void Curve::set_point_value(int p_index, real_t p_position) {
ERR_FAIL_INDEX(p_index, _points.size()); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_index, _points.size());
_points.write[p_index].position.y = p_position; _points[p_index].position.y = p_position;
update_auto_tangents(p_index); update_auto_tangents(p_index);
mark_dirty(); mark_dirty();
} }
int Curve::set_point_offset(int p_index, real_t p_offset) { int Curve::set_point_offset(int p_index, real_t p_offset) {
ERR_FAIL_INDEX_V(p_index, _points.size(), -1); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_index, _points.size(), -1);
Point p = _points[p_index]; Point p = _points[p_index];
_remove_point(p_index); _remove_point(p_index);
int i = _add_point(Vector2(p_offset, p.position.y)); int i = _add_point(Vector2(p_offset, p.position.y));
_points.write[i].left_tangent = p.left_tangent; _points[i].left_tangent = p.left_tangent;
_points.write[i].right_tangent = p.right_tangent; _points[i].right_tangent = p.right_tangent;
_points.write[i].left_mode = p.left_mode; _points[i].left_mode = p.left_mode;
_points.write[i].right_mode = p.right_mode; _points[i].right_mode = p.right_mode;
if (p_index != i) { if (p_index != i) {
update_auto_tangents(p_index); update_auto_tangents(p_index);
} }
@@ -266,17 +266,17 @@ int Curve::set_point_offset(int p_index, real_t p_offset) {
} }
Vector2 Curve::get_point_position(int p_index) const { Vector2 Curve::get_point_position(int p_index) const {
ERR_FAIL_INDEX_V(p_index, _points.size(), Vector2(0, 0)); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_index, _points.size(), Vector2(0, 0));
return _points[p_index].position; return _points[p_index].position;
} }
Curve::Point Curve::get_point(int p_index) const { Curve::Point Curve::get_point(int p_index) const {
ERR_FAIL_INDEX_V(p_index, _points.size(), Point()); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_index, _points.size(), Point());
return _points[p_index]; return _points[p_index];
} }
void Curve::update_auto_tangents(int p_index) { void Curve::update_auto_tangents(int p_index) {
Point &p = _points.write[p_index]; Point &p = _points[p_index];
if (p_index > 0) { if (p_index > 0) {
if (p.left_mode == TANGENT_LINEAR) { if (p.left_mode == TANGENT_LINEAR) {
@@ -285,18 +285,18 @@ void Curve::update_auto_tangents(int p_index) {
} }
if (_points[p_index - 1].right_mode == TANGENT_LINEAR) { if (_points[p_index - 1].right_mode == TANGENT_LINEAR) {
Vector2 v = (_points[p_index - 1].position - p.position).normalized(); Vector2 v = (_points[p_index - 1].position - p.position).normalized();
_points.write[p_index - 1].right_tangent = v.y / v.x; _points[p_index - 1].right_tangent = v.y / v.x;
} }
} }
if (p_index + 1 < _points.size()) { if ((uint32_t)p_index + 1 < _points.size()) {
if (p.right_mode == TANGENT_LINEAR) { if (p.right_mode == TANGENT_LINEAR) {
Vector2 v = (_points[p_index + 1].position - p.position).normalized(); Vector2 v = (_points[p_index + 1].position - p.position).normalized();
p.right_tangent = v.y / v.x; p.right_tangent = v.y / v.x;
} }
if (_points[p_index + 1].left_mode == TANGENT_LINEAR) { if (_points[p_index + 1].left_mode == TANGENT_LINEAR) {
Vector2 v = (_points[p_index + 1].position - p.position).normalized(); Vector2 v = (_points[p_index + 1].position - p.position).normalized();
_points.write[p_index + 1].left_tangent = v.y / v.x; _points[p_index + 1].left_tangent = v.y / v.x;
} }
} }
} }
@@ -383,7 +383,7 @@ real_t Curve::sample(real_t p_offset) const {
return _points[0].position.y; return _points[0].position.y;
} }
int i = get_index(p_offset); uint32_t i = get_index(p_offset);
if (i == _points.size() - 1) { if (i == _points.size() - 1) {
return _points[i].position.y; return _points[i].position.y;
@@ -441,9 +441,9 @@ Array Curve::get_data() const {
const unsigned int ELEMS = 5; const unsigned int ELEMS = 5;
output.resize(_points.size() * ELEMS); output.resize(_points.size() * ELEMS);
for (int j = 0; j < _points.size(); ++j) { for (uint32_t j = 0; j < _points.size(); ++j) {
const Point p = _points[j]; const Point p = _points[j];
int i = j * ELEMS; uint32_t i = j * ELEMS;
output[i] = p.position; output[i] = p.position;
output[i + 1] = p.left_tangent; output[i + 1] = p.left_tangent;
@@ -479,8 +479,8 @@ void Curve::set_data(const Array p_input) {
_points.resize(new_size); _points.resize(new_size);
} }
for (int j = 0; j < _points.size(); ++j) { for (uint32_t j = 0; j < _points.size(); ++j) {
Point &p = _points.write[j]; Point &p = _points[j];
int i = j * ELEMS; int i = j * ELEMS;
p.position = p_input[i]; p.position = p_input[i];
@@ -631,7 +631,7 @@ bool Curve::_get(const StringName &p_name, Variant &r_ret) const {
} }
void Curve::_get_property_list(List<PropertyInfo> *p_list) const { void Curve::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < _points.size(); i++) { for (uint32_t i = 0; i < _points.size(); i++) {
PropertyInfo pi = PropertyInfo(Variant::VECTOR2, vformat("point_%d/position", i)); PropertyInfo pi = PropertyInfo(Variant::VECTOR2, vformat("point_%d/position", i));
pi.usage &= ~PROPERTY_USAGE_STORAGE; pi.usage &= ~PROPERTY_USAGE_STORAGE;
p_list->push_back(pi); p_list->push_back(pi);
@@ -740,7 +740,7 @@ void Curve2D::_add_point(const Vector2 &p_position, const Vector2 &p_in, const V
n.position = p_position; n.position = p_position;
n.in = p_in; n.in = p_in;
n.out = p_out; n.out = p_out;
if (p_atpos >= 0 && p_atpos < points.size()) { if ((uint32_t)p_atpos < points.size()) {
points.insert(p_atpos, n); points.insert(p_atpos, n);
} else { } else {
points.push_back(n); points.push_back(n);
@@ -755,43 +755,43 @@ void Curve2D::add_point(const Vector2 &p_position, const Vector2 &p_in, const Ve
} }
void Curve2D::set_point_position(int p_index, const Vector2 &p_position) { void Curve2D::set_point_position(int p_index, const Vector2 &p_position) {
ERR_FAIL_INDEX(p_index, points.size()); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_index, points.size());
points.write[p_index].position = p_position; points[p_index].position = p_position;
mark_dirty(); mark_dirty();
} }
Vector2 Curve2D::get_point_position(int p_index) const { Vector2 Curve2D::get_point_position(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), Vector2()); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_index, points.size(), Vector2());
return points[p_index].position; return points[p_index].position;
} }
void Curve2D::set_point_in(int p_index, const Vector2 &p_in) { void Curve2D::set_point_in(int p_index, const Vector2 &p_in) {
ERR_FAIL_INDEX(p_index, points.size()); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_index, points.size());
points.write[p_index].in = p_in; points[p_index].in = p_in;
mark_dirty(); mark_dirty();
} }
Vector2 Curve2D::get_point_in(int p_index) const { Vector2 Curve2D::get_point_in(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), Vector2()); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_index, points.size(), Vector2());
return points[p_index].in; return points[p_index].in;
} }
void Curve2D::set_point_out(int p_index, const Vector2 &p_out) { void Curve2D::set_point_out(int p_index, const Vector2 &p_out) {
ERR_FAIL_INDEX(p_index, points.size()); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_index, points.size());
points.write[p_index].out = p_out; points[p_index].out = p_out;
mark_dirty(); mark_dirty();
} }
Vector2 Curve2D::get_point_out(int p_index) const { Vector2 Curve2D::get_point_out(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), Vector2()); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_index, points.size(), Vector2());
return points[p_index].out; return points[p_index].out;
} }
void Curve2D::_remove_point(int p_index) { void Curve2D::_remove_point(int p_index) {
ERR_FAIL_INDEX(p_index, points.size()); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_index, points.size());
points.remove_at(p_index); points.remove_at(p_index);
mark_dirty(); mark_dirty();
} }
@@ -922,7 +922,7 @@ void Curve2D::_bake() const {
Vector<RBMap<real_t, Vector2>> midpoints = _tessellate_even_length(10, bake_interval); Vector<RBMap<real_t, Vector2>> midpoints = _tessellate_even_length(10, bake_interval);
int pc = 1; int pc = 1;
for (int i = 0; i < points.size() - 1; i++) { for (uint32_t i = 0; i < points.size() - 1; i++) {
pc++; pc++;
pc += midpoints[i].size(); pc += midpoints[i].size();
} }
@@ -939,7 +939,7 @@ void Curve2D::_bake() const {
bfw[0] = _calculate_tangent(points[0].position, points[0].position + points[0].out, points[1].position + points[1].in, points[1].position, 0.0); bfw[0] = _calculate_tangent(points[0].position, points[0].position + points[0].out, points[1].position + points[1].in, points[1].position, 0.0);
int pidx = 0; int pidx = 0;
for (int i = 0; i < points.size() - 1; i++) { for (uint32_t i = 0; i < points.size() - 1; i++) {
for (const KeyValue<real_t, Vector2> &E : midpoints[i]) { for (const KeyValue<real_t, Vector2> &E : midpoints[i]) {
pidx++; pidx++;
bpw[pidx] = E.value; bpw[pidx] = E.value;
@@ -1209,7 +1209,7 @@ Dictionary Curve2D::_get_data() const {
d.resize(points.size() * 3); d.resize(points.size() * 3);
Vector2 *w = d.ptrw(); Vector2 *w = d.ptrw();
for (int i = 0; i < points.size(); i++) { for (uint32_t i = 0; i < points.size(); i++) {
w[i * 3 + 0] = points[i].in; w[i * 3 + 0] = points[i].in;
w[i * 3 + 1] = points[i].out; w[i * 3 + 1] = points[i].out;
w[i * 3 + 2] = points[i].position; w[i * 3 + 2] = points[i].position;
@@ -1233,10 +1233,10 @@ void Curve2D::_set_data(const Dictionary &p_data) {
} }
const Vector2 *r = rp.ptr(); const Vector2 *r = rp.ptr();
for (int i = 0; i < points.size(); i++) { for (uint32_t i = 0; i < points.size(); i++) {
points.write[i].in = r[i * 3 + 0]; points[i].in = r[i * 3 + 0];
points.write[i].out = r[i * 3 + 1]; points[i].out = r[i * 3 + 1];
points.write[i].position = r[i * 3 + 2]; points[i].position = r[i * 3 + 2];
} }
mark_dirty(); mark_dirty();
@@ -1258,7 +1258,7 @@ PackedVector2Array Curve2D::tessellate(int p_max_stages, real_t p_tolerance) con
midpoints.resize(points.size() - 1); midpoints.resize(points.size() - 1);
int pc = 1; int pc = 1;
for (int i = 0; i < points.size() - 1; i++) { for (uint32_t i = 0; i < points.size() - 1; i++) {
_bake_segment2d(midpoints.write[i], 0, 1, points[i].position, points[i].out, points[i + 1].position, points[i + 1].in, 0, p_max_stages, p_tolerance); _bake_segment2d(midpoints.write[i], 0, 1, points[i].position, points[i].out, points[i + 1].position, points[i + 1].in, 0, p_max_stages, p_tolerance);
pc++; pc++;
pc += midpoints[i].size(); pc += midpoints[i].size();
@@ -1269,7 +1269,7 @@ PackedVector2Array Curve2D::tessellate(int p_max_stages, real_t p_tolerance) con
bpw[0] = points[0].position; bpw[0] = points[0].position;
int pidx = 0; int pidx = 0;
for (int i = 0; i < points.size() - 1; i++) { for (uint32_t i = 0; i < points.size() - 1; i++) {
for (const KeyValue<real_t, Vector2> &E : midpoints[i]) { for (const KeyValue<real_t, Vector2> &E : midpoints[i]) {
pidx++; pidx++;
bpw[pidx] = E.value; bpw[pidx] = E.value;
@@ -1288,7 +1288,7 @@ Vector<RBMap<real_t, Vector2>> Curve2D::_tessellate_even_length(int p_max_stages
midpoints.resize(points.size() - 1); midpoints.resize(points.size() - 1);
for (int i = 0; i < points.size() - 1; i++) { for (uint32_t i = 0; i < points.size() - 1; i++) {
_bake_segment2d_even_length(midpoints.write[i], 0, 1, points[i].position, points[i].out, points[i + 1].position, points[i + 1].in, 0, p_max_stages, p_length); _bake_segment2d_even_length(midpoints.write[i], 0, 1, points[i].position, points[i].out, points[i + 1].position, points[i + 1].in, 0, p_max_stages, p_length);
} }
return midpoints; return midpoints;
@@ -1303,7 +1303,7 @@ PackedVector2Array Curve2D::tessellate_even_length(int p_max_stages, real_t p_le
} }
int pc = 1; int pc = 1;
for (int i = 0; i < points.size() - 1; i++) { for (uint32_t i = 0; i < points.size() - 1; i++) {
pc++; pc++;
pc += midpoints[i].size(); pc += midpoints[i].size();
} }
@@ -1313,7 +1313,7 @@ PackedVector2Array Curve2D::tessellate_even_length(int p_max_stages, real_t p_le
bpw[0] = points[0].position; bpw[0] = points[0].position;
int pidx = 0; int pidx = 0;
for (int i = 0; i < points.size() - 1; i++) { for (uint32_t i = 0; i < points.size() - 1; i++) {
for (const KeyValue<real_t, Vector2> &E : midpoints[i]) { for (const KeyValue<real_t, Vector2> &E : midpoints[i]) {
pidx++; pidx++;
bpw[pidx] = E.value; bpw[pidx] = E.value;
@@ -1365,7 +1365,7 @@ bool Curve2D::_get(const StringName &p_name, Variant &r_ret) const {
} }
void Curve2D::_get_property_list(List<PropertyInfo> *p_list) const { void Curve2D::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < points.size(); i++) { for (uint32_t i = 0; i < points.size(); i++) {
PropertyInfo pi = PropertyInfo(Variant::VECTOR2, vformat("point_%d/position", i)); PropertyInfo pi = PropertyInfo(Variant::VECTOR2, vformat("point_%d/position", i));
pi.usage &= ~PROPERTY_USAGE_STORAGE; pi.usage &= ~PROPERTY_USAGE_STORAGE;
p_list->push_back(pi); p_list->push_back(pi);
@@ -1455,7 +1455,7 @@ void Curve3D::_add_point(const Vector3 &p_position, const Vector3 &p_in, const V
n.position = p_position; n.position = p_position;
n.in = p_in; n.in = p_in;
n.out = p_out; n.out = p_out;
if (p_atpos >= 0 && p_atpos < points.size()) { if ((uint32_t)p_atpos < points.size()) {
points.insert(p_atpos, n); points.insert(p_atpos, n);
} else { } else {
points.push_back(n); points.push_back(n);
@@ -1470,55 +1470,55 @@ void Curve3D::add_point(const Vector3 &p_position, const Vector3 &p_in, const Ve
} }
void Curve3D::set_point_position(int p_index, const Vector3 &p_position) { void Curve3D::set_point_position(int p_index, const Vector3 &p_position) {
ERR_FAIL_INDEX(p_index, points.size()); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_index, points.size());
points.write[p_index].position = p_position; points[p_index].position = p_position;
mark_dirty(); mark_dirty();
} }
Vector3 Curve3D::get_point_position(int p_index) const { Vector3 Curve3D::get_point_position(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), Vector3()); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_index, points.size(), Vector3());
return points[p_index].position; return points[p_index].position;
} }
void Curve3D::set_point_tilt(int p_index, real_t p_tilt) { void Curve3D::set_point_tilt(int p_index, real_t p_tilt) {
ERR_FAIL_INDEX(p_index, points.size()); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_index, points.size());
points.write[p_index].tilt = p_tilt; points[p_index].tilt = p_tilt;
mark_dirty(); mark_dirty();
} }
real_t Curve3D::get_point_tilt(int p_index) const { real_t Curve3D::get_point_tilt(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), 0); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_index, points.size(), 0);
return points[p_index].tilt; return points[p_index].tilt;
} }
void Curve3D::set_point_in(int p_index, const Vector3 &p_in) { void Curve3D::set_point_in(int p_index, const Vector3 &p_in) {
ERR_FAIL_INDEX(p_index, points.size()); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_index, points.size());
points.write[p_index].in = p_in; points[p_index].in = p_in;
mark_dirty(); mark_dirty();
} }
Vector3 Curve3D::get_point_in(int p_index) const { Vector3 Curve3D::get_point_in(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), Vector3()); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_index, points.size(), Vector3());
return points[p_index].in; return points[p_index].in;
} }
void Curve3D::set_point_out(int p_index, const Vector3 &p_out) { void Curve3D::set_point_out(int p_index, const Vector3 &p_out) {
ERR_FAIL_INDEX(p_index, points.size()); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_index, points.size());
points.write[p_index].out = p_out; points[p_index].out = p_out;
mark_dirty(); mark_dirty();
} }
Vector3 Curve3D::get_point_out(int p_index) const { Vector3 Curve3D::get_point_out(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), Vector3()); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_index, points.size(), Vector3());
return points[p_index].out; return points[p_index].out;
} }
void Curve3D::_remove_point(int p_index) { void Curve3D::_remove_point(int p_index) {
ERR_FAIL_INDEX(p_index, points.size()); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_index, points.size());
points.remove_at(p_index); points.remove_at(p_index);
mark_dirty(); mark_dirty();
} }
@@ -2227,7 +2227,7 @@ Dictionary Curve3D::_get_data() const {
t.resize(points.size()); t.resize(points.size());
real_t *wt = t.ptrw(); real_t *wt = t.ptrw();
for (int i = 0; i < points.size(); i++) { for (uint32_t i = 0; i < points.size(); i++) {
w[i * 3 + 0] = points[i].in; w[i * 3 + 0] = points[i].in;
w[i * 3 + 1] = points[i].out; w[i * 3 + 1] = points[i].out;
w[i * 3 + 2] = points[i].position; w[i * 3 + 2] = points[i].position;
@@ -2256,11 +2256,11 @@ void Curve3D::_set_data(const Dictionary &p_data) {
Vector<real_t> rtl = p_data["tilts"]; Vector<real_t> rtl = p_data["tilts"];
const real_t *rt = rtl.ptr(); const real_t *rt = rtl.ptr();
for (int i = 0; i < points.size(); i++) { for (uint32_t i = 0; i < points.size(); i++) {
points.write[i].in = r[i * 3 + 0]; points[i].in = r[i * 3 + 0];
points.write[i].out = r[i * 3 + 1]; points[i].out = r[i * 3 + 1];
points.write[i].position = r[i * 3 + 2]; points[i].position = r[i * 3 + 2];
points.write[i].tilt = rt[i]; points[i].tilt = rt[i];
} }
mark_dirty(); mark_dirty();
@@ -2414,7 +2414,7 @@ bool Curve3D::_get(const StringName &p_name, Variant &r_ret) const {
} }
void Curve3D::_get_property_list(List<PropertyInfo> *p_list) const { void Curve3D::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < points.size(); i++) { for (uint32_t i = 0; i < points.size(); i++) {
PropertyInfo pi = PropertyInfo(Variant::VECTOR3, vformat("point_%d/position", i)); PropertyInfo pi = PropertyInfo(Variant::VECTOR3, vformat("point_%d/position", i));
pi.usage &= ~PROPERTY_USAGE_STORAGE; pi.usage &= ~PROPERTY_USAGE_STORAGE;
p_list->push_back(pi); p_list->push_back(pi);

View File

@@ -156,7 +156,7 @@ private:
TangentMode right_mode = TANGENT_FREE); TangentMode right_mode = TANGENT_FREE);
void _remove_point(int p_index); void _remove_point(int p_index);
Vector<Point> _points; LocalVector<Point> _points;
mutable bool _baked_cache_dirty = false; mutable bool _baked_cache_dirty = false;
mutable Vector<real_t> _baked_cache; mutable Vector<real_t> _baked_cache;
int _bake_resolution = 100; int _bake_resolution = 100;
@@ -177,7 +177,7 @@ class Curve2D : public Resource {
Vector2 position; Vector2 position;
}; };
Vector<Point> points; LocalVector<Point> points;
struct BakedPoint { struct BakedPoint {
real_t ofs = 0.0; real_t ofs = 0.0;
@@ -265,7 +265,7 @@ class Curve3D : public Resource {
real_t tilt = 0.0; real_t tilt = 0.0;
}; };
Vector<Point> points; LocalVector<Point> points;
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
// For Path3DGizmo. // For Path3DGizmo.
mutable Vector<size_t> points_in_cache; mutable Vector<size_t> points_in_cache;

View File

@@ -33,10 +33,10 @@
Gradient::Gradient() { Gradient::Gradient() {
//Set initial gradient transition from black to white //Set initial gradient transition from black to white
points.resize(2); points.resize(2);
points.write[0].color = Color(0, 0, 0, 1); points[0].color = Color(0, 0, 0, 1);
points.write[0].offset = 0; points[0].offset = 0;
points.write[1].color = Color(1, 1, 1, 1); points[1].color = Color(1, 1, 1, 1);
points.write[1].offset = 1; points[1].offset = 1;
} }
Gradient::~Gradient() { Gradient::~Gradient() {
@@ -96,7 +96,7 @@ void Gradient::_validate_property(PropertyInfo &p_property) const {
Vector<float> Gradient::get_offsets() const { Vector<float> Gradient::get_offsets() const {
Vector<float> offsets; Vector<float> offsets;
offsets.resize(points.size()); offsets.resize(points.size());
for (int i = 0; i < points.size(); i++) { for (uint32_t i = 0; i < points.size(); i++) {
offsets.write[i] = points[i].offset; offsets.write[i] = points[i].offset;
} }
return offsets; return offsets;
@@ -105,7 +105,7 @@ Vector<float> Gradient::get_offsets() const {
Vector<Color> Gradient::get_colors() const { Vector<Color> Gradient::get_colors() const {
Vector<Color> colors; Vector<Color> colors;
colors.resize(points.size()); colors.resize(points.size());
for (int i = 0; i < points.size(); i++) { for (uint32_t i = 0; i < points.size(); i++) {
colors.write[i] = points[i].color; colors.write[i] = points[i].color;
} }
return colors; return colors;
@@ -140,8 +140,8 @@ Gradient::ColorSpace Gradient::get_interpolation_color_space() {
void Gradient::set_offsets(const Vector<float> &p_offsets) { void Gradient::set_offsets(const Vector<float> &p_offsets) {
points.resize(p_offsets.size()); points.resize(p_offsets.size());
for (int i = 0; i < points.size(); i++) { for (uint32_t i = 0; i < points.size(); i++) {
points.write[i].offset = p_offsets[i]; points[i].offset = p_offsets[i];
} }
is_sorted = false; is_sorted = false;
emit_changed(); emit_changed();
@@ -152,16 +152,12 @@ void Gradient::set_colors(const Vector<Color> &p_colors) {
is_sorted = false; is_sorted = false;
} }
points.resize(p_colors.size()); points.resize(p_colors.size());
for (int i = 0; i < points.size(); i++) { for (uint32_t i = 0; i < points.size(); i++) {
points.write[i].color = p_colors[i]; points[i].color = p_colors[i];
} }
emit_changed(); emit_changed();
} }
Vector<Gradient::Point> &Gradient::get_points() {
return points;
}
void Gradient::add_point(float p_offset, const Color &p_color) { void Gradient::add_point(float p_offset, const Color &p_color) {
Point p; Point p;
p.offset = p_offset; p.offset = p_offset;
@@ -173,15 +169,15 @@ void Gradient::add_point(float p_offset, const Color &p_color) {
} }
void Gradient::remove_point(int p_index) { void Gradient::remove_point(int p_index) {
ERR_FAIL_INDEX(p_index, points.size()); ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_index, points.size());
ERR_FAIL_COND(points.size() <= 1); ERR_FAIL_COND(points.size() <= 1);
points.remove_at(p_index); points.remove_at(p_index);
emit_changed(); emit_changed();
} }
void Gradient::reverse() { void Gradient::reverse() {
for (int i = 0; i < points.size(); i++) { for (uint32_t i = 0; i < points.size(); i++) {
points.write[i].offset = 1.0 - points[i].offset; points[i].offset = 1.0 - points[i].offset;
} }
is_sorted = false; is_sorted = false;
@@ -189,35 +185,29 @@ void Gradient::reverse() {
emit_changed(); emit_changed();
} }
void Gradient::set_points(const Vector<Gradient::Point> &p_points) {
points = p_points;
is_sorted = false;
emit_changed();
}
void Gradient::set_offset(int pos, const float offset) { void Gradient::set_offset(int pos, const float offset) {
ERR_FAIL_INDEX(pos, points.size()); ERR_FAIL_UNSIGNED_INDEX((uint32_t)pos, points.size());
_update_sorting(); _update_sorting();
points.write[pos].offset = offset; points[pos].offset = offset;
is_sorted = false; is_sorted = false;
emit_changed(); emit_changed();
} }
float Gradient::get_offset(int pos) { float Gradient::get_offset(int pos) {
ERR_FAIL_INDEX_V(pos, points.size(), 0.0); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)pos, points.size(), 0.0);
_update_sorting(); _update_sorting();
return points[pos].offset; return points[pos].offset;
} }
void Gradient::set_color(int pos, const Color &color) { void Gradient::set_color(int pos, const Color &color) {
ERR_FAIL_INDEX(pos, points.size()); ERR_FAIL_UNSIGNED_INDEX((uint32_t)pos, points.size());
_update_sorting(); _update_sorting();
points.write[pos].color = color; points[pos].color = color;
emit_changed(); emit_changed();
} }
Color Gradient::get_color(int pos) { Color Gradient::get_color(int pos) {
ERR_FAIL_INDEX_V(pos, points.size(), Color()); ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)pos, points.size(), Color());
_update_sorting(); _update_sorting();
return points[pos].color; return points[pos].color;
} }

View File

@@ -61,7 +61,7 @@ public:
}; };
private: private:
Vector<Point> points; LocalVector<Point> points;
bool is_sorted = true; bool is_sorted = true;
InterpolationMode interpolation_mode = GRADIENT_INTERPOLATE_LINEAR; InterpolationMode interpolation_mode = GRADIENT_INTERPOLATE_LINEAR;
ColorSpace interpolation_color_space = GRADIENT_COLOR_SPACE_SRGB; ColorSpace interpolation_color_space = GRADIENT_COLOR_SPACE_SRGB;
@@ -129,8 +129,6 @@ public:
void add_point(float p_offset, const Color &p_color); void add_point(float p_offset, const Color &p_color);
void remove_point(int p_index); void remove_point(int p_index);
void set_points(const Vector<Point> &p_points);
Vector<Point> &get_points();
void reverse(); void reverse();
void set_offset(int pos, const float offset); void set_offset(int pos, const float offset);
@@ -187,7 +185,7 @@ public:
} }
int first = middle; int first = middle;
int second = middle + 1; int second = middle + 1;
if (second >= points.size()) { if (second >= (int)points.size()) {
return points[points.size() - 1].color; return points[points.size() - 1].color;
} }
if (first < 0) { if (first < 0) {
@@ -212,7 +210,7 @@ public:
case GRADIENT_INTERPOLATE_CUBIC: { case GRADIENT_INTERPOLATE_CUBIC: {
int p0 = first - 1; int p0 = first - 1;
int p3 = second + 1; int p3 = second + 1;
if (p3 >= points.size()) { if (p3 >= (int)points.size()) {
p3 = second; p3 = second;
} }
if (p0 < 0) { if (p0 < 0) {

View File

@@ -70,11 +70,11 @@ TEST_CASE("[Gradient] Default gradient") {
TEST_CASE("[Gradient] Custom gradient (points specified in order)") { TEST_CASE("[Gradient] Custom gradient (points specified in order)") {
// Red-yellow-green gradient (with overbright green). // Red-yellow-green gradient (with overbright green).
Ref<Gradient> gradient = memnew(Gradient); Ref<Gradient> gradient = memnew(Gradient);
Vector<Gradient::Point> points; Vector<float> offsets = { 0.0, 0.5, 1.0 };
points.push_back({ 0.0, Color(1, 0, 0) }); Vector<Color> colors = { Color(1, 0, 0), Color(1, 1, 0), Color(0, 2, 0) };
points.push_back({ 0.5, Color(1, 1, 0) });
points.push_back({ 1.0, Color(0, 2, 0) }); gradient->set_offsets(offsets);
gradient->set_points(points); gradient->set_colors(colors);
CHECK_MESSAGE( CHECK_MESSAGE(
gradient->get_point_count() == 3, gradient->get_point_count() == 3,
@@ -109,14 +109,12 @@ TEST_CASE("[Gradient] Custom gradient (points specified out-of-order)") {
// HSL rainbow with points specified out of order. // HSL rainbow with points specified out of order.
// These should be sorted automatically when adding points. // These should be sorted automatically when adding points.
Ref<Gradient> gradient = memnew(Gradient); Ref<Gradient> gradient = memnew(Gradient);
Vector<Gradient::Point> points; LocalVector<Gradient::Point> points;
points.push_back({ 0.2, Color(1, 0, 0) }); Vector<float> offsets = { 0.2, 0.0, 0.8, 0.4, 1.0, 0.6 };
points.push_back({ 0.0, Color(1, 1, 0) }); Vector<Color> colors = { Color(1, 0, 0), Color(1, 1, 0), Color(0, 1, 0), Color(0, 1, 1), Color(0, 0, 1), Color(1, 0, 1) };
points.push_back({ 0.8, Color(0, 1, 0) });
points.push_back({ 0.4, Color(0, 1, 1) }); gradient->set_offsets(offsets);
points.push_back({ 1.0, Color(0, 0, 1) }); gradient->set_colors(colors);
points.push_back({ 0.6, Color(1, 0, 1) });
gradient->set_points(points);
CHECK_MESSAGE( CHECK_MESSAGE(
gradient->get_point_count() == 6, gradient->get_point_count() == 6,