1 /** 2 Describes a Bézier 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.traits; 17 import godot.core; 18 import godot.c; 19 import godot.d.bind; 20 import godot.d.reference; 21 import godot.globalenums; 22 import godot.object; 23 import godot.classdb; 24 import godot.resource; 25 /** 26 Describes a Bézier curve in 2D space. 27 28 This class describes a Bézier 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 up further calculations. 30 */ 31 @GodotBaseClass struct Curve2D 32 { 33 package(godot) 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 GDNativeClassBinding 41 { 42 __gshared: 43 @GodotName("_get_data") GodotMethod!(Dictionary) _getData; 44 @GodotName("_set_data") GodotMethod!(void, Dictionary) _setData; 45 @GodotName("add_point") GodotMethod!(void, Vector2, Vector2, Vector2, long) addPoint; 46 @GodotName("clear_points") GodotMethod!(void) clearPoints; 47 @GodotName("get_bake_interval") GodotMethod!(double) getBakeInterval; 48 @GodotName("get_baked_length") GodotMethod!(double) getBakedLength; 49 @GodotName("get_baked_points") GodotMethod!(PoolVector2Array) getBakedPoints; 50 @GodotName("get_closest_offset") GodotMethod!(double, Vector2) getClosestOffset; 51 @GodotName("get_closest_point") GodotMethod!(Vector2, Vector2) getClosestPoint; 52 @GodotName("get_point_count") GodotMethod!(long) getPointCount; 53 @GodotName("get_point_in") GodotMethod!(Vector2, long) getPointIn; 54 @GodotName("get_point_out") GodotMethod!(Vector2, long) getPointOut; 55 @GodotName("get_point_position") GodotMethod!(Vector2, long) getPointPosition; 56 @GodotName("interpolate") GodotMethod!(Vector2, long, double) interpolate; 57 @GodotName("interpolate_baked") GodotMethod!(Vector2, double, bool) interpolateBaked; 58 @GodotName("interpolatef") GodotMethod!(Vector2, double) interpolatef; 59 @GodotName("remove_point") GodotMethod!(void, long) removePoint; 60 @GodotName("set_bake_interval") GodotMethod!(void, double) setBakeInterval; 61 @GodotName("set_point_in") GodotMethod!(void, long, Vector2) setPointIn; 62 @GodotName("set_point_out") GodotMethod!(void, long, Vector2) setPointOut; 63 @GodotName("set_point_position") GodotMethod!(void, long, Vector2) setPointPosition; 64 @GodotName("tessellate") GodotMethod!(PoolVector2Array, long, double) tessellate; 65 } 66 /// 67 pragma(inline, true) bool opEquals(in Curve2D other) const 68 { return _godot_object.ptr is other._godot_object.ptr; } 69 /// 70 pragma(inline, true) typeof(null) opAssign(typeof(null) n) 71 { _godot_object.ptr = n; return null; } 72 /// 73 pragma(inline, true) bool opEquals(typeof(null) n) const 74 { return _godot_object.ptr is n; } 75 /// 76 size_t toHash() const @trusted { return cast(size_t)_godot_object.ptr; } 77 mixin baseCasts; 78 /// Construct a new instance of Curve2D. 79 /// Note: use `memnew!Curve2D` instead. 80 static Curve2D _new() 81 { 82 static godot_class_constructor constructor; 83 if(constructor is null) constructor = _godot_api.godot_get_class_constructor("Curve2D"); 84 if(constructor is null) return typeof(this).init; 85 return cast(Curve2D)(constructor()); 86 } 87 @disable new(size_t s); 88 /** 89 90 */ 91 Dictionary _getData() const 92 { 93 Array _GODOT_args = Array.make(); 94 String _GODOT_method_name = String("_get_data"); 95 return this.callv(_GODOT_method_name, _GODOT_args).as!(RefOrT!Dictionary); 96 } 97 /** 98 99 */ 100 void _setData(in Dictionary arg0) 101 { 102 Array _GODOT_args = Array.make(); 103 _GODOT_args.append(arg0); 104 String _GODOT_method_name = String("_set_data"); 105 this.callv(_GODOT_method_name, _GODOT_args); 106 } 107 /** 108 Adds a point to a curve at `position`, with control points `in` and `out`. 109 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. 110 */ 111 void addPoint(in Vector2 position, in Vector2 _in = Vector2(0, 0), in Vector2 _out = Vector2(0, 0), in long at_position = -1) 112 { 113 checkClassBinding!(typeof(this))(); 114 ptrcall!(void)(GDNativeClassBinding.addPoint, _godot_object, position, _in, _out, at_position); 115 } 116 /** 117 Removes all points from the curve. 118 */ 119 void clearPoints() 120 { 121 checkClassBinding!(typeof(this))(); 122 ptrcall!(void)(GDNativeClassBinding.clearPoints, _godot_object); 123 } 124 /** 125 126 */ 127 double getBakeInterval() const 128 { 129 checkClassBinding!(typeof(this))(); 130 return ptrcall!(double)(GDNativeClassBinding.getBakeInterval, _godot_object); 131 } 132 /** 133 Returns the total length of the curve, based on the cached points. Given enough density (see $(D bakeInterval)), it should be approximate enough. 134 */ 135 double getBakedLength() const 136 { 137 checkClassBinding!(typeof(this))(); 138 return ptrcall!(double)(GDNativeClassBinding.getBakedLength, _godot_object); 139 } 140 /** 141 Returns the cache of points as a $(D PoolVector2Array). 142 */ 143 PoolVector2Array getBakedPoints() const 144 { 145 checkClassBinding!(typeof(this))(); 146 return ptrcall!(PoolVector2Array)(GDNativeClassBinding.getBakedPoints, _godot_object); 147 } 148 /** 149 Returns the closest offset to `to_point`. This offset is meant to be used in $(D interpolateBaked). 150 `to_point` must be in this curve's local space. 151 */ 152 double getClosestOffset(in Vector2 to_point) const 153 { 154 checkClassBinding!(typeof(this))(); 155 return ptrcall!(double)(GDNativeClassBinding.getClosestOffset, _godot_object, to_point); 156 } 157 /** 158 Returns the closest baked point (in curve's local space) to `to_point`. 159 `to_point` must be in this curve's local space. 160 */ 161 Vector2 getClosestPoint(in Vector2 to_point) const 162 { 163 checkClassBinding!(typeof(this))(); 164 return ptrcall!(Vector2)(GDNativeClassBinding.getClosestPoint, _godot_object, to_point); 165 } 166 /** 167 Returns the number of points describing the curve. 168 */ 169 long getPointCount() const 170 { 171 checkClassBinding!(typeof(this))(); 172 return ptrcall!(long)(GDNativeClassBinding.getPointCount, _godot_object); 173 } 174 /** 175 Returns the position of the control point leading to the vertex `idx`. The returned position is relative to the vertex `idx`. If the index is out of bounds, the function sends an error to the console, and returns `(0, 0)`. 176 */ 177 Vector2 getPointIn(in long idx) const 178 { 179 checkClassBinding!(typeof(this))(); 180 return ptrcall!(Vector2)(GDNativeClassBinding.getPointIn, _godot_object, idx); 181 } 182 /** 183 Returns the position of the control point leading out of the vertex `idx`. The returned position is relative to the vertex `idx`. If the index is out of bounds, the function sends an error to the console, and returns `(0, 0)`. 184 */ 185 Vector2 getPointOut(in long idx) const 186 { 187 checkClassBinding!(typeof(this))(); 188 return ptrcall!(Vector2)(GDNativeClassBinding.getPointOut, _godot_object, idx); 189 } 190 /** 191 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)`. 192 */ 193 Vector2 getPointPosition(in long idx) const 194 { 195 checkClassBinding!(typeof(this))(); 196 return ptrcall!(Vector2)(GDNativeClassBinding.getPointPosition, _godot_object, idx); 197 } 198 /** 199 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. 200 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)`. 201 */ 202 Vector2 interpolate(in long idx, in double t) const 203 { 204 checkClassBinding!(typeof(this))(); 205 return ptrcall!(Vector2)(GDNativeClassBinding.interpolate, _godot_object, idx, t); 206 } 207 /** 208 Returns a point within the curve at position `offset`, where `offset` is measured as a pixel distance along the curve. 209 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`. 210 Cubic interpolation tends to follow the curves better, but linear is faster (and often, precise enough). 211 */ 212 Vector2 interpolateBaked(in double offset, in bool cubic = false) const 213 { 214 checkClassBinding!(typeof(this))(); 215 return ptrcall!(Vector2)(GDNativeClassBinding.interpolateBaked, _godot_object, offset, cubic); 216 } 217 /** 218 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`. 219 */ 220 Vector2 interpolatef(in double fofs) const 221 { 222 checkClassBinding!(typeof(this))(); 223 return ptrcall!(Vector2)(GDNativeClassBinding.interpolatef, _godot_object, fofs); 224 } 225 /** 226 Deletes the point `idx` from the curve. Sends an error to the console if `idx` is out of bounds. 227 */ 228 void removePoint(in long idx) 229 { 230 checkClassBinding!(typeof(this))(); 231 ptrcall!(void)(GDNativeClassBinding.removePoint, _godot_object, idx); 232 } 233 /** 234 235 */ 236 void setBakeInterval(in double distance) 237 { 238 checkClassBinding!(typeof(this))(); 239 ptrcall!(void)(GDNativeClassBinding.setBakeInterval, _godot_object, distance); 240 } 241 /** 242 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. The position is relative to the vertex. 243 */ 244 void setPointIn(in long idx, in Vector2 position) 245 { 246 checkClassBinding!(typeof(this))(); 247 ptrcall!(void)(GDNativeClassBinding.setPointIn, _godot_object, idx, position); 248 } 249 /** 250 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. The position is relative to the vertex. 251 */ 252 void setPointOut(in long idx, in Vector2 position) 253 { 254 checkClassBinding!(typeof(this))(); 255 ptrcall!(void)(GDNativeClassBinding.setPointOut, _godot_object, idx, position); 256 } 257 /** 258 Sets the position for the vertex `idx`. If the index is out of bounds, the function sends an error to the console. 259 */ 260 void setPointPosition(in long idx, in Vector2 position) 261 { 262 checkClassBinding!(typeof(this))(); 263 ptrcall!(void)(GDNativeClassBinding.setPointPosition, _godot_object, idx, position); 264 } 265 /** 266 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. 267 This approximation makes straight segments between each point, then subdivides those segments until the resulting shape is similar enough. 268 `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! 269 `tolerance_degrees` controls how many degrees the midpoint of a segment may deviate from the real curve, before the segment has to be subdivided. 270 */ 271 PoolVector2Array tessellate(in long max_stages = 5, in double tolerance_degrees = 4) const 272 { 273 checkClassBinding!(typeof(this))(); 274 return ptrcall!(PoolVector2Array)(GDNativeClassBinding.tessellate, _godot_object, max_stages, tolerance_degrees); 275 } 276 /** 277 278 */ 279 @property Dictionary _data() 280 { 281 return _getData(); 282 } 283 /// ditto 284 @property void _data(Dictionary v) 285 { 286 _setData(v); 287 } 288 /** 289 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. 290 */ 291 @property double bakeInterval() 292 { 293 return getBakeInterval(); 294 } 295 /// ditto 296 @property void bakeInterval(double v) 297 { 298 setBakeInterval(v); 299 } 300 }