1 /** 2 Describes a Bezier curve in 2D space. 3 4 Copyright: 5 Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. 6 Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) 7 Copyright (c) 2017-2018 Godot-D contributors 8 9 License: $(LINK2 https://opensource.org/licenses/MIT, MIT License) 10 11 12 */ 13 module godot.curve2d; 14 import std.meta : AliasSeq, staticIndexOf; 15 import std.traits : Unqual; 16 import godot.d.meta; 17 import godot.core; 18 import godot.c; 19 import godot.d.bind; 20 import godot.d.reference; 21 import godot.object; 22 import godot.classdb; 23 import godot.resource; 24 import godot.reference; 25 /** 26 Describes a Bezier curve in 2D space. 27 28 This class describes a Bezier curve in 2D space. It is mainly used to give a shape to a $(D Path2D), but can be manually sampled for other purposes. 29 It keeps a cache of precalculated points along the curve, to speed further calculations up. 30 */ 31 @GodotBaseClass struct Curve2D 32 { 33 enum string _GODOT_internal_name = "Curve2D"; 34 public: 35 @nogc nothrow: 36 union { godot_object _godot_object; Resource _GODOT_base; } 37 alias _GODOT_base this; 38 alias BaseClasses = AliasSeq!(typeof(_GODOT_base), typeof(_GODOT_base).BaseClasses); 39 package(godot) __gshared bool _classBindingInitialized = false; 40 package(godot) static struct _classBinding 41 { 42 __gshared: 43 @GodotName("get_point_count") GodotMethod!(long) getPointCount; 44 @GodotName("add_point") GodotMethod!(void, Vector2, Vector2, Vector2, long) addPoint; 45 @GodotName("set_point_position") GodotMethod!(void, long, Vector2) setPointPosition; 46 @GodotName("get_point_position") GodotMethod!(Vector2, long) getPointPosition; 47 @GodotName("set_point_in") GodotMethod!(void, long, Vector2) setPointIn; 48 @GodotName("get_point_in") GodotMethod!(Vector2, long) getPointIn; 49 @GodotName("set_point_out") GodotMethod!(void, long, Vector2) setPointOut; 50 @GodotName("get_point_out") GodotMethod!(Vector2, long) getPointOut; 51 @GodotName("remove_point") GodotMethod!(void, long) removePoint; 52 @GodotName("clear_points") GodotMethod!(void) clearPoints; 53 @GodotName("interpolate") GodotMethod!(Vector2, long, double) interpolate; 54 @GodotName("interpolatef") GodotMethod!(Vector2, double) interpolatef; 55 @GodotName("set_bake_interval") GodotMethod!(void, double) setBakeInterval; 56 @GodotName("get_bake_interval") GodotMethod!(double) getBakeInterval; 57 @GodotName("get_baked_length") GodotMethod!(double) getBakedLength; 58 @GodotName("interpolate_baked") GodotMethod!(Vector2, double, bool) interpolateBaked; 59 @GodotName("get_baked_points") GodotMethod!(PoolVector2Array) getBakedPoints; 60 @GodotName("get_closest_point") GodotMethod!(Vector2, Vector2) getClosestPoint; 61 @GodotName("get_closest_offset") GodotMethod!(double, Vector2) getClosestOffset; 62 @GodotName("tessellate") GodotMethod!(PoolVector2Array, long, double) tessellate; 63 @GodotName("_get_data") GodotMethod!(Dictionary) _getData; 64 @GodotName("_set_data") GodotMethod!(void, Dictionary) _setData; 65 } 66 bool opEquals(in Curve2D other) const { return _godot_object.ptr is other._godot_object.ptr; } 67 Curve2D opAssign(T : typeof(null))(T n) { _godot_object.ptr = null; } 68 bool opEquals(typeof(null) n) const { return _godot_object.ptr is null; } 69 mixin baseCasts; 70 static Curve2D _new() 71 { 72 static godot_class_constructor constructor; 73 if(constructor is null) constructor = _godot_api.godot_get_class_constructor("Curve2D"); 74 if(constructor is null) return typeof(this).init; 75 return cast(Curve2D)(constructor()); 76 } 77 @disable new(size_t s); 78 /** 79 Returns the number of points describing the curve. 80 */ 81 long getPointCount() const 82 { 83 checkClassBinding!(typeof(this))(); 84 return ptrcall!(long)(_classBinding.getPointCount, _godot_object); 85 } 86 /** 87 Adds a point to a curve, at "position", with control points "in" and "out". 88 If "at_position" is given, the point is inserted before the point number "at_position", moving that point (and every point after) after the inserted point. If "at_position" is not given, or is an illegal value (at_position <0 or at_position >= $(D getPointCount)), the point will be appended at the end of the point list. 89 */ 90 void addPoint(in Vector2 position, in Vector2 _in = Vector2(0, 0), in Vector2 _out = Vector2(0, 0), in long at_position = -1) 91 { 92 checkClassBinding!(typeof(this))(); 93 ptrcall!(void)(_classBinding.addPoint, _godot_object, position, _in, _out, at_position); 94 } 95 /** 96 Sets the position for the vertex "idx". If the index is out of bounds, the function sends an error to the console. 97 */ 98 void setPointPosition(in long idx, in Vector2 position) 99 { 100 checkClassBinding!(typeof(this))(); 101 ptrcall!(void)(_classBinding.setPointPosition, _godot_object, idx, position); 102 } 103 /** 104 Returns the position of the vertex "idx". If the index is out of bounds, the function sends an error to the console, and returns (0, 0). 105 */ 106 Vector2 getPointPosition(in long idx) const 107 { 108 checkClassBinding!(typeof(this))(); 109 return ptrcall!(Vector2)(_classBinding.getPointPosition, _godot_object, idx); 110 } 111 /** 112 Sets the position of the control point leading to the vertex "idx". If the index is out of bounds, the function sends an error to the console. 113 */ 114 void setPointIn(in long idx, in Vector2 position) 115 { 116 checkClassBinding!(typeof(this))(); 117 ptrcall!(void)(_classBinding.setPointIn, _godot_object, idx, position); 118 } 119 /** 120 Returns the position of the control point leading to the vertex "idx". If the index is out of bounds, the function sends an error to the console, and returns (0, 0). 121 */ 122 Vector2 getPointIn(in long idx) const 123 { 124 checkClassBinding!(typeof(this))(); 125 return ptrcall!(Vector2)(_classBinding.getPointIn, _godot_object, idx); 126 } 127 /** 128 Sets the position of the control point leading out of the vertex "idx". If the index is out of bounds, the function sends an error to the console. 129 */ 130 void setPointOut(in long idx, in Vector2 position) 131 { 132 checkClassBinding!(typeof(this))(); 133 ptrcall!(void)(_classBinding.setPointOut, _godot_object, idx, position); 134 } 135 /** 136 Returns the position of the control point leading out of the vertex "idx". If the index is out of bounds, the function sends an error to the console, and returns (0, 0). 137 */ 138 Vector2 getPointOut(in long idx) const 139 { 140 checkClassBinding!(typeof(this))(); 141 return ptrcall!(Vector2)(_classBinding.getPointOut, _godot_object, idx); 142 } 143 /** 144 Deletes the point "idx" from the curve. Sends an error to the console if "idx" is out of bounds. 145 */ 146 void removePoint(in long idx) 147 { 148 checkClassBinding!(typeof(this))(); 149 ptrcall!(void)(_classBinding.removePoint, _godot_object, idx); 150 } 151 /** 152 Removes all points from the curve. 153 */ 154 void clearPoints() 155 { 156 checkClassBinding!(typeof(this))(); 157 ptrcall!(void)(_classBinding.clearPoints, _godot_object); 158 } 159 /** 160 Returns the position between the vertex "idx" and the vertex "idx"+1, where "t" controls if the point is the first vertex (t = 0.0), the last vertex (t = 1.0), or in between. Values of "t" outside the range (0.0 >= t <=1) give strange, but predictable results. 161 If "idx" is out of bounds it is truncated to the first or last vertex, and "t" is ignored. If the curve has no points, the function sends an error to the console, and returns (0, 0). 162 */ 163 Vector2 interpolate(in long idx, in double t) const 164 { 165 checkClassBinding!(typeof(this))(); 166 return ptrcall!(Vector2)(_classBinding.interpolate, _godot_object, idx, t); 167 } 168 /** 169 Returns the position at the vertex "fofs". It calls $(D interpolate) using the integer part of fofs as "idx", and its fractional part as "t". 170 */ 171 Vector2 interpolatef(in double fofs) const 172 { 173 checkClassBinding!(typeof(this))(); 174 return ptrcall!(Vector2)(_classBinding.interpolatef, _godot_object, fofs); 175 } 176 /** 177 178 */ 179 void setBakeInterval(in double distance) 180 { 181 checkClassBinding!(typeof(this))(); 182 ptrcall!(void)(_classBinding.setBakeInterval, _godot_object, distance); 183 } 184 /** 185 186 */ 187 double getBakeInterval() const 188 { 189 checkClassBinding!(typeof(this))(); 190 return ptrcall!(double)(_classBinding.getBakeInterval, _godot_object); 191 } 192 /** 193 Returns the total length of the curve, based on the cached points. Given enough density (see $(D setBakeInterval)), it should be approximate enough. 194 */ 195 double getBakedLength() const 196 { 197 checkClassBinding!(typeof(this))(); 198 return ptrcall!(double)(_classBinding.getBakedLength, _godot_object); 199 } 200 /** 201 Returns a point within the curve at position "offset", where "offset" is measured as a pixel distance along the curve. 202 To do that, it finds the two cached points where the "offset" lies between, then interpolates the values. This interpolation is cubic if "cubic" is set to true, or linear if set to false. 203 Cubic interpolation tends to follow the curves better, but linear is faster (and often, precise enough). 204 */ 205 Vector2 interpolateBaked(in double offset, in bool cubic = false) const 206 { 207 checkClassBinding!(typeof(this))(); 208 return ptrcall!(Vector2)(_classBinding.interpolateBaked, _godot_object, offset, cubic); 209 } 210 /** 211 Returns the cache of points as a $(D PoolVector2Array). 212 */ 213 PoolVector2Array getBakedPoints() const 214 { 215 checkClassBinding!(typeof(this))(); 216 return ptrcall!(PoolVector2Array)(_classBinding.getBakedPoints, _godot_object); 217 } 218 /** 219 Returns the closest point (in curve's local space) to `to_point`. 220 `to_point` must be in this curve's local space. 221 */ 222 Vector2 getClosestPoint(in Vector2 to_point) const 223 { 224 checkClassBinding!(typeof(this))(); 225 return ptrcall!(Vector2)(_classBinding.getClosestPoint, _godot_object, to_point); 226 } 227 /** 228 Returns the closest offset to `to_point`. This offset is meant to be used in $(D interpolateBaked). 229 `to_point` must be in this curve's local space. 230 */ 231 double getClosestOffset(in Vector2 to_point) const 232 { 233 checkClassBinding!(typeof(this))(); 234 return ptrcall!(double)(_classBinding.getClosestOffset, _godot_object, to_point); 235 } 236 /** 237 Returns a list of points along the curve, with a curvature controlled point density. That is, the curvier parts will have more points than the straighter parts. 238 This approximation makes straight segments between each point, then subdivides those segments until the resulting shape is similar enough. 239 "max_stages" controls how many subdivisions a curve segment may face before it is considered approximate enough. Each subdivision splits the segment in half, so the default 5 stages may mean up to 32 subdivisions per curve segment. Increase with care! 240 "tolerance_degrees" controls how many degrees the midpoint of a segment may deviate from the real curve, before the segment has to be subdivided. 241 */ 242 PoolVector2Array tessellate(in long max_stages = 5, in double tolerance_degrees = 4) const 243 { 244 checkClassBinding!(typeof(this))(); 245 return ptrcall!(PoolVector2Array)(_classBinding.tessellate, _godot_object, max_stages, tolerance_degrees); 246 } 247 /** 248 249 */ 250 Dictionary _getData() const 251 { 252 Array _GODOT_args = Array.empty_array; 253 String _GODOT_method_name = String("_get_data"); 254 return this.callv(_GODOT_method_name, _GODOT_args).as!(RefOrT!Dictionary); 255 } 256 /** 257 258 */ 259 void _setData(in Dictionary arg0) 260 { 261 Array _GODOT_args = Array.empty_array; 262 _GODOT_args.append(arg0); 263 String _GODOT_method_name = String("_set_data"); 264 this.callv(_GODOT_method_name, _GODOT_args); 265 } 266 /** 267 The distance in pixels between two adjacent cached points. Changing it forces the cache to be recomputed the next time the $(D getBakedPoints) or $(D getBakedLength) function is called. The smaller the distance, the more points in the cache and the more memory it will consume, so use with care. 268 */ 269 @property double bakeInterval() 270 { 271 return getBakeInterval(); 272 } 273 /// ditto 274 @property void bakeInterval(double v) 275 { 276 setBakeInterval(v); 277 } 278 /** 279 280 */ 281 @property Dictionary _data() 282 { 283 return _getData(); 284 } 285 /// ditto 286 @property void _data(Dictionary v) 287 { 288 _setData(v); 289 } 290 }