mirror of
https://github.com/godotengine/godot.git
synced 2025-02-23 23:15:07 +08:00
Merge pull request #58023 from raulsntos/curve_points_in_inspector
Exposes the Curve, Curve2D and Curve3D points in the inspector
This commit is contained in:
commit
d4c4302e47
@ -38,12 +38,6 @@
|
||||
Removes all points from the curve.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_point_count" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the number of points describing the curve.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_point_left_mode" qualifiers="const">
|
||||
<return type="int" enum="Curve.TangentMode" />
|
||||
<argument index="0" name="index" type="int" />
|
||||
@ -159,6 +153,9 @@
|
||||
<member name="min_value" type="float" setter="set_min_value" getter="get_min_value" default="0.0">
|
||||
The minimum value the curve can reach.
|
||||
</member>
|
||||
<member name="point_count" type="int" setter="set_point_count" getter="get_point_count" default="0">
|
||||
The number of points describing the curve.
|
||||
</member>
|
||||
</members>
|
||||
<signals>
|
||||
<signal name="range_changed">
|
||||
|
@ -55,12 +55,6 @@
|
||||
[code]to_point[/code] must be in this curve's local space.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_point_count" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the number of points describing the curve.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_point_in" qualifiers="const">
|
||||
<return type="Vector2" />
|
||||
<argument index="0" name="idx" type="int" />
|
||||
@ -155,5 +149,8 @@
|
||||
<member name="bake_interval" type="float" setter="set_bake_interval" getter="get_bake_interval" default="5.0">
|
||||
The distance in pixels between two adjacent cached points. Changing it forces the cache to be recomputed the next time the [method get_baked_points] or [method get_baked_length] function is called. The smaller the distance, the more points in the cache and the more memory it will consume, so use with care.
|
||||
</member>
|
||||
<member name="point_count" type="int" setter="set_point_count" getter="get_point_count" default="0">
|
||||
The number of points describing the curve.
|
||||
</member>
|
||||
</members>
|
||||
</class>
|
||||
|
@ -68,12 +68,6 @@
|
||||
[code]to_point[/code] must be in this curve's local space.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_point_count" qualifiers="const">
|
||||
<return type="int" />
|
||||
<description>
|
||||
Returns the number of points describing the curve.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_point_in" qualifiers="const">
|
||||
<return type="Vector3" />
|
||||
<argument index="0" name="idx" type="int" />
|
||||
@ -194,6 +188,9 @@
|
||||
<member name="bake_interval" type="float" setter="set_bake_interval" getter="get_bake_interval" default="0.2">
|
||||
The distance in meters between two adjacent cached points. Changing it forces the cache to be recomputed the next time the [method get_baked_points] or [method get_baked_length] function is called. The smaller the distance, the more points in the cache and the more memory it will consume, so use with care.
|
||||
</member>
|
||||
<member name="point_count" type="int" setter="set_point_count" getter="get_point_count" default="0">
|
||||
The number of points describing the curve.
|
||||
</member>
|
||||
<member name="up_vector_enabled" type="bool" setter="set_up_vector_enabled" getter="is_up_vector_enabled" default="true">
|
||||
If [code]true[/code], the curve will bake up vectors used for orientation. This is used when [member PathFollow3D.rotation_mode] is set to [constant PathFollow3D.ROTATION_ORIENTED]. Changing it forces the cache to be recomputed.
|
||||
</member>
|
||||
|
@ -49,6 +49,18 @@ const char *Curve::SIGNAL_RANGE_CHANGED = "range_changed";
|
||||
Curve::Curve() {
|
||||
}
|
||||
|
||||
void Curve::set_point_count(int p_count) {
|
||||
ERR_FAIL_COND(p_count < 0);
|
||||
if (_points.size() >= p_count) {
|
||||
_points.resize(p_count);
|
||||
mark_dirty();
|
||||
} else {
|
||||
for (int i = p_count - _points.size(); i > 0; i--) {
|
||||
add_point(Vector2());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Curve::add_point(Vector2 p_position, real_t p_left_tangent, real_t p_right_tangent, TangentMode p_left_mode, TangentMode p_right_mode) {
|
||||
// Add a point and preserve order
|
||||
|
||||
@ -358,6 +370,7 @@ real_t Curve::interpolate_local_nocheck(int p_index, real_t p_local_offset) cons
|
||||
void Curve::mark_dirty() {
|
||||
_baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
notify_property_list_changed();
|
||||
}
|
||||
|
||||
Array Curve::get_data() const {
|
||||
@ -409,7 +422,6 @@ void Curve::set_data(const Array p_input) {
|
||||
p.position = p_input[i];
|
||||
p.left_tangent = p_input[i + 1];
|
||||
p.right_tangent = p_input[i + 2];
|
||||
// TODO For some reason the compiler won't convert from Variant to enum
|
||||
int left_mode = p_input[i + 3];
|
||||
int right_mode = p_input[i + 4];
|
||||
p.left_mode = (TangentMode)left_mode;
|
||||
@ -490,8 +502,91 @@ void Curve::ensure_default_setup(real_t p_min, real_t p_max) {
|
||||
}
|
||||
}
|
||||
|
||||
bool Curve::_set(const StringName &p_name, const Variant &p_value) {
|
||||
Vector<String> components = String(p_name).split("/", true, 2);
|
||||
if (components.size() >= 2 && components[0].begins_with("point_") && components[0].trim_prefix("point_").is_valid_int()) {
|
||||
int point_index = components[0].trim_prefix("point_").to_int();
|
||||
String property = components[1];
|
||||
if (property == "position") {
|
||||
Vector2 position = p_value.operator Vector2();
|
||||
set_point_offset(point_index, position.x);
|
||||
set_point_value(point_index, position.y);
|
||||
return true;
|
||||
} else if (property == "left_tangent") {
|
||||
set_point_left_tangent(point_index, p_value);
|
||||
return true;
|
||||
} else if (property == "left_mode") {
|
||||
int mode = p_value;
|
||||
set_point_left_mode(point_index, (TangentMode)mode);
|
||||
return true;
|
||||
} else if (property == "right_tangent") {
|
||||
set_point_right_tangent(point_index, p_value);
|
||||
return true;
|
||||
} else if (property == "right_mode") {
|
||||
int mode = p_value;
|
||||
set_point_right_mode(point_index, (TangentMode)mode);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Curve::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
Vector<String> components = String(p_name).split("/", true, 2);
|
||||
if (components.size() >= 2 && components[0].begins_with("point_") && components[0].trim_prefix("point_").is_valid_int()) {
|
||||
int point_index = components[0].trim_prefix("point_").to_int();
|
||||
String property = components[1];
|
||||
if (property == "position") {
|
||||
r_ret = get_point_position(point_index);
|
||||
return true;
|
||||
} else if (property == "left_tangent") {
|
||||
r_ret = get_point_left_tangent(point_index);
|
||||
return true;
|
||||
} else if (property == "left_mode") {
|
||||
r_ret = get_point_left_mode(point_index);
|
||||
return true;
|
||||
} else if (property == "right_tangent") {
|
||||
r_ret = get_point_right_tangent(point_index);
|
||||
return true;
|
||||
} else if (property == "right_mode") {
|
||||
r_ret = get_point_right_mode(point_index);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Curve::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
for (int i = 0; i < _points.size(); i++) {
|
||||
PropertyInfo pi = PropertyInfo(Variant::VECTOR2, vformat("point_%d/position", i));
|
||||
pi.usage &= ~PROPERTY_USAGE_STORAGE;
|
||||
p_list->push_back(pi);
|
||||
|
||||
if (i != 0) {
|
||||
pi = PropertyInfo(Variant::FLOAT, vformat("point_%d/left_tangent", i));
|
||||
pi.usage &= ~PROPERTY_USAGE_STORAGE;
|
||||
p_list->push_back(pi);
|
||||
|
||||
pi = PropertyInfo(Variant::INT, vformat("point_%d/left_mode", i), PROPERTY_HINT_ENUM, "Free,Linear");
|
||||
pi.usage &= ~PROPERTY_USAGE_STORAGE;
|
||||
p_list->push_back(pi);
|
||||
}
|
||||
|
||||
if (i != _points.size() - 1) {
|
||||
pi = PropertyInfo(Variant::FLOAT, vformat("point_%d/right_tangent", i));
|
||||
pi.usage &= ~PROPERTY_USAGE_STORAGE;
|
||||
p_list->push_back(pi);
|
||||
|
||||
pi = PropertyInfo(Variant::INT, vformat("point_%d/right_mode", i), PROPERTY_HINT_ENUM, "Free,Linear");
|
||||
pi.usage &= ~PROPERTY_USAGE_STORAGE;
|
||||
p_list->push_back(pi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Curve::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_point_count"), &Curve::get_point_count);
|
||||
ClassDB::bind_method(D_METHOD("set_point_count", "count"), &Curve::set_point_count);
|
||||
ClassDB::bind_method(D_METHOD("add_point", "position", "left_tangent", "right_tangent", "left_mode", "right_mode"), &Curve::add_point, DEFVAL(0), DEFVAL(0), DEFVAL(TANGENT_FREE), DEFVAL(TANGENT_FREE));
|
||||
ClassDB::bind_method(D_METHOD("remove_point", "index"), &Curve::remove_point);
|
||||
ClassDB::bind_method(D_METHOD("clear_points"), &Curve::clear_points);
|
||||
@ -523,6 +618,7 @@ void Curve::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_value", PROPERTY_HINT_RANGE, "-1024,1024,0.01"), "set_max_value", "get_max_value");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "bake_resolution", PROPERTY_HINT_RANGE, "1,1000,1"), "set_bake_resolution", "get_bake_resolution");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
|
||||
ADD_ARRAY_COUNT("Points", "point_count", "set_point_count", "get_point_count", "point_");
|
||||
|
||||
ADD_SIGNAL(MethodInfo(SIGNAL_RANGE_CHANGED));
|
||||
|
||||
@ -535,6 +631,20 @@ int Curve2D::get_point_count() const {
|
||||
return points.size();
|
||||
}
|
||||
|
||||
void Curve2D::set_point_count(int p_count) {
|
||||
ERR_FAIL_COND(p_count < 0);
|
||||
if (points.size() >= p_count) {
|
||||
points.resize(p_count);
|
||||
mark_dirty();
|
||||
baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
} else {
|
||||
for (int i = p_count - points.size(); i > 0; i--) {
|
||||
add_point(Vector2());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Curve2D::add_point(const Vector2 &p_position, const Vector2 &p_in, const Vector2 &p_out, int p_atpos) {
|
||||
Point n;
|
||||
n.position = p_position;
|
||||
@ -546,16 +656,14 @@ void Curve2D::add_point(const Vector2 &p_position, const Vector2 &p_in, const Ve
|
||||
points.push_back(n);
|
||||
}
|
||||
|
||||
baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
mark_dirty();
|
||||
}
|
||||
|
||||
void Curve2D::set_point_position(int p_index, const Vector2 &p_position) {
|
||||
ERR_FAIL_INDEX(p_index, points.size());
|
||||
|
||||
points.write[p_index].position = p_position;
|
||||
baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
mark_dirty();
|
||||
}
|
||||
|
||||
Vector2 Curve2D::get_point_position(int p_index) const {
|
||||
@ -567,8 +675,7 @@ void Curve2D::set_point_in(int p_index, const Vector2 &p_in) {
|
||||
ERR_FAIL_INDEX(p_index, points.size());
|
||||
|
||||
points.write[p_index].in = p_in;
|
||||
baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
mark_dirty();
|
||||
}
|
||||
|
||||
Vector2 Curve2D::get_point_in(int p_index) const {
|
||||
@ -580,8 +687,7 @@ void Curve2D::set_point_out(int p_index, const Vector2 &p_out) {
|
||||
ERR_FAIL_INDEX(p_index, points.size());
|
||||
|
||||
points.write[p_index].out = p_out;
|
||||
baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
mark_dirty();
|
||||
}
|
||||
|
||||
Vector2 Curve2D::get_point_out(int p_index) const {
|
||||
@ -592,15 +698,13 @@ Vector2 Curve2D::get_point_out(int p_index) const {
|
||||
void Curve2D::remove_point(int p_index) {
|
||||
ERR_FAIL_INDEX(p_index, points.size());
|
||||
points.remove_at(p_index);
|
||||
baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
mark_dirty();
|
||||
}
|
||||
|
||||
void Curve2D::clear_points() {
|
||||
if (!points.is_empty()) {
|
||||
points.clear();
|
||||
baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
mark_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
@ -632,6 +736,12 @@ Vector2 Curve2D::interpolatef(real_t p_findex) const {
|
||||
return interpolate((int)p_findex, Math::fmod(p_findex, (real_t)1.0));
|
||||
}
|
||||
|
||||
void Curve2D::mark_dirty() {
|
||||
baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
notify_property_list_changed();
|
||||
}
|
||||
|
||||
void Curve2D::_bake_segment2d(RBMap<real_t, Vector2> &r_bake, real_t p_begin, real_t p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, real_t p_tol) const {
|
||||
real_t mp = p_begin + (p_end - p_begin) * 0.5;
|
||||
Vector2 beg = _bezier_interp(p_begin, p_a, p_a + p_out, p_b + p_in, p_b);
|
||||
@ -825,8 +935,7 @@ PackedVector2Array Curve2D::get_baked_points() const {
|
||||
|
||||
void Curve2D::set_bake_interval(real_t p_tolerance) {
|
||||
bake_interval = p_tolerance;
|
||||
baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
mark_dirty();
|
||||
}
|
||||
|
||||
real_t Curve2D::get_bake_interval() const {
|
||||
@ -985,8 +1094,67 @@ PackedVector2Array Curve2D::tessellate(int p_max_stages, real_t p_tolerance) con
|
||||
return tess;
|
||||
}
|
||||
|
||||
bool Curve2D::_set(const StringName &p_name, const Variant &p_value) {
|
||||
Vector<String> components = String(p_name).split("/", true, 2);
|
||||
if (components.size() >= 2 && components[0].begins_with("point_") && components[0].trim_prefix("point_").is_valid_int()) {
|
||||
int point_index = components[0].trim_prefix("point_").to_int();
|
||||
String property = components[1];
|
||||
if (property == "position") {
|
||||
set_point_position(point_index, p_value);
|
||||
return true;
|
||||
} else if (property == "in") {
|
||||
set_point_in(point_index, p_value);
|
||||
return true;
|
||||
} else if (property == "out") {
|
||||
set_point_out(point_index, p_value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Curve2D::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
Vector<String> components = String(p_name).split("/", true, 2);
|
||||
if (components.size() >= 2 && components[0].begins_with("point_") && components[0].trim_prefix("point_").is_valid_int()) {
|
||||
int point_index = components[0].trim_prefix("point_").to_int();
|
||||
String property = components[1];
|
||||
if (property == "position") {
|
||||
r_ret = get_point_position(point_index);
|
||||
return true;
|
||||
} else if (property == "in") {
|
||||
r_ret = get_point_in(point_index);
|
||||
return true;
|
||||
} else if (property == "out") {
|
||||
r_ret = get_point_out(point_index);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Curve2D::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
for (int i = 0; i < points.size(); i++) {
|
||||
PropertyInfo pi = PropertyInfo(Variant::VECTOR2, vformat("point_%d/position", i));
|
||||
pi.usage &= ~PROPERTY_USAGE_STORAGE;
|
||||
p_list->push_back(pi);
|
||||
|
||||
if (i != 0) {
|
||||
pi = PropertyInfo(Variant::VECTOR2, vformat("point_%d/in", i));
|
||||
pi.usage &= ~PROPERTY_USAGE_STORAGE;
|
||||
p_list->push_back(pi);
|
||||
}
|
||||
|
||||
if (i != points.size() - 1) {
|
||||
pi = PropertyInfo(Variant::VECTOR2, vformat("point_%d/out", i));
|
||||
pi.usage &= ~PROPERTY_USAGE_STORAGE;
|
||||
p_list->push_back(pi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Curve2D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_point_count"), &Curve2D::get_point_count);
|
||||
ClassDB::bind_method(D_METHOD("set_point_count", "count"), &Curve2D::set_point_count);
|
||||
ClassDB::bind_method(D_METHOD("add_point", "position", "in", "out", "at_position"), &Curve2D::add_point, DEFVAL(Vector2()), DEFVAL(Vector2()), DEFVAL(-1));
|
||||
ClassDB::bind_method(D_METHOD("set_point_position", "idx", "position"), &Curve2D::set_point_position);
|
||||
ClassDB::bind_method(D_METHOD("get_point_position", "idx"), &Curve2D::get_point_position);
|
||||
@ -1014,6 +1182,7 @@ void Curve2D::_bind_methods() {
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bake_interval", PROPERTY_HINT_RANGE, "0.01,512,0.01"), "set_bake_interval", "get_bake_interval");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
|
||||
ADD_ARRAY_COUNT("Points", "point_count", "set_point_count", "get_point_count", "point_");
|
||||
}
|
||||
|
||||
Curve2D::Curve2D() {}
|
||||
@ -1029,6 +1198,18 @@ int Curve3D::get_point_count() const {
|
||||
return points.size();
|
||||
}
|
||||
|
||||
void Curve3D::set_point_count(int p_count) {
|
||||
ERR_FAIL_COND(p_count < 0);
|
||||
if (points.size() >= p_count) {
|
||||
points.resize(p_count);
|
||||
mark_dirty();
|
||||
} else {
|
||||
for (int i = p_count - points.size(); i > 0; i--) {
|
||||
add_point(Vector3());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Curve3D::add_point(const Vector3 &p_position, const Vector3 &p_in, const Vector3 &p_out, int p_atpos) {
|
||||
Point n;
|
||||
n.position = p_position;
|
||||
@ -1040,16 +1221,14 @@ void Curve3D::add_point(const Vector3 &p_position, const Vector3 &p_in, const Ve
|
||||
points.push_back(n);
|
||||
}
|
||||
|
||||
baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
mark_dirty();
|
||||
}
|
||||
|
||||
void Curve3D::set_point_position(int p_index, const Vector3 &p_position) {
|
||||
ERR_FAIL_INDEX(p_index, points.size());
|
||||
|
||||
points.write[p_index].position = p_position;
|
||||
baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
mark_dirty();
|
||||
}
|
||||
|
||||
Vector3 Curve3D::get_point_position(int p_index) const {
|
||||
@ -1061,8 +1240,7 @@ void Curve3D::set_point_tilt(int p_index, real_t p_tilt) {
|
||||
ERR_FAIL_INDEX(p_index, points.size());
|
||||
|
||||
points.write[p_index].tilt = p_tilt;
|
||||
baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
mark_dirty();
|
||||
}
|
||||
|
||||
real_t Curve3D::get_point_tilt(int p_index) const {
|
||||
@ -1074,8 +1252,7 @@ void Curve3D::set_point_in(int p_index, const Vector3 &p_in) {
|
||||
ERR_FAIL_INDEX(p_index, points.size());
|
||||
|
||||
points.write[p_index].in = p_in;
|
||||
baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
mark_dirty();
|
||||
}
|
||||
|
||||
Vector3 Curve3D::get_point_in(int p_index) const {
|
||||
@ -1087,8 +1264,7 @@ void Curve3D::set_point_out(int p_index, const Vector3 &p_out) {
|
||||
ERR_FAIL_INDEX(p_index, points.size());
|
||||
|
||||
points.write[p_index].out = p_out;
|
||||
baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
mark_dirty();
|
||||
}
|
||||
|
||||
Vector3 Curve3D::get_point_out(int p_index) const {
|
||||
@ -1099,15 +1275,13 @@ Vector3 Curve3D::get_point_out(int p_index) const {
|
||||
void Curve3D::remove_point(int p_index) {
|
||||
ERR_FAIL_INDEX(p_index, points.size());
|
||||
points.remove_at(p_index);
|
||||
baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
mark_dirty();
|
||||
}
|
||||
|
||||
void Curve3D::clear_points() {
|
||||
if (!points.is_empty()) {
|
||||
points.clear();
|
||||
baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
mark_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1139,6 +1313,12 @@ Vector3 Curve3D::interpolatef(real_t p_findex) const {
|
||||
return interpolate((int)p_findex, Math::fmod(p_findex, (real_t)1.0));
|
||||
}
|
||||
|
||||
void Curve3D::mark_dirty() {
|
||||
baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
notify_property_list_changed();
|
||||
}
|
||||
|
||||
void Curve3D::_bake_segment3d(RBMap<real_t, Vector3> &r_bake, real_t p_begin, real_t p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, real_t p_tol) const {
|
||||
real_t mp = p_begin + (p_end - p_begin) * 0.5;
|
||||
Vector3 beg = _bezier_interp(p_begin, p_a, p_a + p_out, p_b + p_in, p_b);
|
||||
@ -1601,8 +1781,7 @@ real_t Curve3D::get_closest_offset(const Vector3 &p_to_point) const {
|
||||
|
||||
void Curve3D::set_bake_interval(real_t p_tolerance) {
|
||||
bake_interval = p_tolerance;
|
||||
baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
mark_dirty();
|
||||
}
|
||||
|
||||
real_t Curve3D::get_bake_interval() const {
|
||||
@ -1611,8 +1790,7 @@ real_t Curve3D::get_bake_interval() const {
|
||||
|
||||
void Curve3D::set_up_vector_enabled(bool p_enable) {
|
||||
up_vector_enabled = p_enable;
|
||||
baked_cache_dirty = true;
|
||||
emit_signal(CoreStringNames::get_singleton()->changed);
|
||||
mark_dirty();
|
||||
}
|
||||
|
||||
bool Curve3D::is_up_vector_enabled() const {
|
||||
@ -1699,8 +1877,77 @@ PackedVector3Array Curve3D::tessellate(int p_max_stages, real_t p_tolerance) con
|
||||
return tess;
|
||||
}
|
||||
|
||||
bool Curve3D::_set(const StringName &p_name, const Variant &p_value) {
|
||||
Vector<String> components = String(p_name).split("/", true, 2);
|
||||
if (components.size() >= 2 && components[0].begins_with("point_") && components[0].trim_prefix("point_").is_valid_int()) {
|
||||
int point_index = components[0].trim_prefix("point_").to_int();
|
||||
String property = components[1];
|
||||
if (property == "position") {
|
||||
set_point_position(point_index, p_value);
|
||||
return true;
|
||||
} else if (property == "in") {
|
||||
set_point_in(point_index, p_value);
|
||||
return true;
|
||||
} else if (property == "out") {
|
||||
set_point_out(point_index, p_value);
|
||||
return true;
|
||||
} else if (property == "tilt") {
|
||||
set_point_tilt(point_index, p_value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Curve3D::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
Vector<String> components = String(p_name).split("/", true, 2);
|
||||
if (components.size() >= 2 && components[0].begins_with("point_") && components[0].trim_prefix("point_").is_valid_int()) {
|
||||
int point_index = components[0].trim_prefix("point_").to_int();
|
||||
String property = components[1];
|
||||
if (property == "position") {
|
||||
r_ret = get_point_position(point_index);
|
||||
return true;
|
||||
} else if (property == "in") {
|
||||
r_ret = get_point_in(point_index);
|
||||
return true;
|
||||
} else if (property == "out") {
|
||||
r_ret = get_point_out(point_index);
|
||||
return true;
|
||||
} else if (property == "tilt") {
|
||||
r_ret = get_point_tilt(point_index);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Curve3D::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
for (int i = 0; i < points.size(); i++) {
|
||||
PropertyInfo pi = PropertyInfo(Variant::VECTOR3, vformat("point_%d/position", i));
|
||||
pi.usage &= ~PROPERTY_USAGE_STORAGE;
|
||||
p_list->push_back(pi);
|
||||
|
||||
if (i != 0) {
|
||||
pi = PropertyInfo(Variant::VECTOR3, vformat("point_%d/in", i));
|
||||
pi.usage &= ~PROPERTY_USAGE_STORAGE;
|
||||
p_list->push_back(pi);
|
||||
}
|
||||
|
||||
if (i != points.size() - 1) {
|
||||
pi = PropertyInfo(Variant::VECTOR3, vformat("point_%d/out", i));
|
||||
pi.usage &= ~PROPERTY_USAGE_STORAGE;
|
||||
p_list->push_back(pi);
|
||||
}
|
||||
|
||||
pi = PropertyInfo(Variant::FLOAT, vformat("point_%d/tilt", i));
|
||||
pi.usage &= ~PROPERTY_USAGE_STORAGE;
|
||||
p_list->push_back(pi);
|
||||
}
|
||||
}
|
||||
|
||||
void Curve3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_point_count"), &Curve3D::get_point_count);
|
||||
ClassDB::bind_method(D_METHOD("set_point_count", "count"), &Curve3D::set_point_count);
|
||||
ClassDB::bind_method(D_METHOD("add_point", "position", "in", "out", "at_position"), &Curve3D::add_point, DEFVAL(Vector3()), DEFVAL(Vector3()), DEFVAL(-1));
|
||||
ClassDB::bind_method(D_METHOD("set_point_position", "idx", "position"), &Curve3D::set_point_position);
|
||||
ClassDB::bind_method(D_METHOD("get_point_position", "idx"), &Curve3D::get_point_position);
|
||||
@ -1735,6 +1982,7 @@ void Curve3D::_bind_methods() {
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bake_interval", PROPERTY_HINT_RANGE, "0.01,512,0.01"), "set_bake_interval", "get_bake_interval");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
|
||||
ADD_ARRAY_COUNT("Points", "point_count", "set_point_count", "get_point_count", "point_");
|
||||
|
||||
ADD_GROUP("Up Vector", "up_vector_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "up_vector_enabled"), "set_up_vector_enabled", "is_up_vector_enabled");
|
||||
|
@ -76,6 +76,8 @@ public:
|
||||
|
||||
int get_point_count() const { return _points.size(); }
|
||||
|
||||
void set_point_count(int p_count);
|
||||
|
||||
int add_point(Vector2 p_position,
|
||||
real_t left_tangent = 0,
|
||||
real_t right_tangent = 0,
|
||||
@ -126,6 +128,10 @@ public:
|
||||
|
||||
void ensure_default_setup(real_t p_min, real_t p_max);
|
||||
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
@ -164,6 +170,8 @@ class Curve2D : public Resource {
|
||||
mutable Vector<real_t> baked_dist_cache;
|
||||
mutable real_t baked_max_ofs = 0.0;
|
||||
|
||||
void mark_dirty();
|
||||
|
||||
void _bake() const;
|
||||
|
||||
real_t bake_interval = 5.0;
|
||||
@ -172,11 +180,16 @@ class Curve2D : public Resource {
|
||||
Dictionary _get_data() const;
|
||||
void _set_data(const Dictionary &p_data);
|
||||
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
int get_point_count() const;
|
||||
void set_point_count(int p_count);
|
||||
void add_point(const Vector2 &p_position, const Vector2 &p_in = Vector2(), const Vector2 &p_out = Vector2(), int p_atpos = -1);
|
||||
void set_point_position(int p_index, const Vector2 &p_position);
|
||||
Vector2 get_point_position(int p_index) const;
|
||||
@ -228,6 +241,8 @@ class Curve3D : public Resource {
|
||||
mutable Vector<real_t> baked_dist_cache;
|
||||
mutable real_t baked_max_ofs = 0.0;
|
||||
|
||||
void mark_dirty();
|
||||
|
||||
void _bake() const;
|
||||
|
||||
real_t bake_interval = 0.2;
|
||||
@ -237,11 +252,16 @@ class Curve3D : public Resource {
|
||||
Dictionary _get_data() const;
|
||||
void _set_data(const Dictionary &p_data);
|
||||
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
void _get_property_list(List<PropertyInfo> *p_list) const;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
int get_point_count() const;
|
||||
void set_point_count(int p_count);
|
||||
void add_point(const Vector3 &p_position, const Vector3 &p_in = Vector3(), const Vector3 &p_out = Vector3(), int p_atpos = -1);
|
||||
void set_point_position(int p_index, const Vector3 &p_position);
|
||||
Vector3 get_point_position(int p_index) const;
|
||||
|
Loading…
Reference in New Issue
Block a user