1 /** 2 Describes a Bézier curve in 3D 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.curve3d; 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 3D space. 27 28 This class describes a Bézier curve in 3D space. It is mainly used to give a shape to a $(D Path), 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 Curve3D 32 { 33 package(godot) enum string _GODOT_internal_name = "Curve3D"; 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, Vector3, Vector3, Vector3, 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!(PoolVector3Array) getBakedPoints; 50 @GodotName("get_baked_tilts") GodotMethod!(PoolRealArray) getBakedTilts; 51 @GodotName("get_baked_up_vectors") GodotMethod!(PoolVector3Array) getBakedUpVectors; 52 @GodotName("get_closest_offset") GodotMethod!(double, Vector3) getClosestOffset; 53 @GodotName("get_closest_point") GodotMethod!(Vector3, Vector3) getClosestPoint; 54 @GodotName("get_point_count") GodotMethod!(long) getPointCount; 55 @GodotName("get_point_in") GodotMethod!(Vector3, long) getPointIn; 56 @GodotName("get_point_out") GodotMethod!(Vector3, long) getPointOut; 57 @GodotName("get_point_position") GodotMethod!(Vector3, long) getPointPosition; 58 @GodotName("get_point_tilt") GodotMethod!(double, long) getPointTilt; 59 @GodotName("interpolate") GodotMethod!(Vector3, long, double) interpolate; 60 @GodotName("interpolate_baked") GodotMethod!(Vector3, double, bool) interpolateBaked; 61 @GodotName("interpolate_baked_up_vector") GodotMethod!(Vector3, double, bool) interpolateBakedUpVector; 62 @GodotName("interpolatef") GodotMethod!(Vector3, double) interpolatef; 63 @GodotName("is_up_vector_enabled") GodotMethod!(bool) isUpVectorEnabled; 64 @GodotName("remove_point") GodotMethod!(void, long) removePoint; 65 @GodotName("set_bake_interval") GodotMethod!(void, double) setBakeInterval; 66 @GodotName("set_point_in") GodotMethod!(void, long, Vector3) setPointIn; 67 @GodotName("set_point_out") GodotMethod!(void, long, Vector3) setPointOut; 68 @GodotName("set_point_position") GodotMethod!(void, long, Vector3) setPointPosition; 69 @GodotName("set_point_tilt") GodotMethod!(void, long, double) setPointTilt; 70 @GodotName("set_up_vector_enabled") GodotMethod!(void, bool) setUpVectorEnabled; 71 @GodotName("tessellate") GodotMethod!(PoolVector3Array, long, double) tessellate; 72 } 73 /// 74 pragma(inline, true) bool opEquals(in Curve3D other) const 75 { return _godot_object.ptr is other._godot_object.ptr; } 76 /// 77 pragma(inline, true) typeof(null) opAssign(typeof(null) n) 78 { _godot_object.ptr = n; return null; } 79 /// 80 pragma(inline, true) bool opEquals(typeof(null) n) const 81 { return _godot_object.ptr is n; } 82 /// 83 size_t toHash() const @trusted { return cast(size_t)_godot_object.ptr; } 84 mixin baseCasts; 85 /// Construct a new instance of Curve3D. 86 /// Note: use `memnew!Curve3D` instead. 87 static Curve3D _new() 88 { 89 static godot_class_constructor constructor; 90 if(constructor is null) constructor = _godot_api.godot_get_class_constructor("Curve3D"); 91 if(constructor is null) return typeof(this).init; 92 return cast(Curve3D)(constructor()); 93 } 94 @disable new(size_t s); 95 /** 96 97 */ 98 Dictionary _getData() const 99 { 100 Array _GODOT_args = Array.make(); 101 String _GODOT_method_name = String("_get_data"); 102 return this.callv(_GODOT_method_name, _GODOT_args).as!(RefOrT!Dictionary); 103 } 104 /** 105 106 */ 107 void _setData(in Dictionary arg0) 108 { 109 Array _GODOT_args = Array.make(); 110 _GODOT_args.append(arg0); 111 String _GODOT_method_name = String("_set_data"); 112 this.callv(_GODOT_method_name, _GODOT_args); 113 } 114 /** 115 Adds a point to a curve at `position`, with control points `in` and `out`. 116 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. 117 */ 118 void addPoint(in Vector3 position, in Vector3 _in = Vector3(0, 0, 0), in Vector3 _out = Vector3(0, 0, 0), in long at_position = -1) 119 { 120 checkClassBinding!(typeof(this))(); 121 ptrcall!(void)(GDNativeClassBinding.addPoint, _godot_object, position, _in, _out, at_position); 122 } 123 /** 124 Removes all points from the curve. 125 */ 126 void clearPoints() 127 { 128 checkClassBinding!(typeof(this))(); 129 ptrcall!(void)(GDNativeClassBinding.clearPoints, _godot_object); 130 } 131 /** 132 133 */ 134 double getBakeInterval() const 135 { 136 checkClassBinding!(typeof(this))(); 137 return ptrcall!(double)(GDNativeClassBinding.getBakeInterval, _godot_object); 138 } 139 /** 140 Returns the total length of the curve, based on the cached points. Given enough density (see $(D bakeInterval)), it should be approximate enough. 141 */ 142 double getBakedLength() const 143 { 144 checkClassBinding!(typeof(this))(); 145 return ptrcall!(double)(GDNativeClassBinding.getBakedLength, _godot_object); 146 } 147 /** 148 Returns the cache of points as a $(D PoolVector3Array). 149 */ 150 PoolVector3Array getBakedPoints() const 151 { 152 checkClassBinding!(typeof(this))(); 153 return ptrcall!(PoolVector3Array)(GDNativeClassBinding.getBakedPoints, _godot_object); 154 } 155 /** 156 Returns the cache of tilts as a $(D PoolRealArray). 157 */ 158 PoolRealArray getBakedTilts() const 159 { 160 checkClassBinding!(typeof(this))(); 161 return ptrcall!(PoolRealArray)(GDNativeClassBinding.getBakedTilts, _godot_object); 162 } 163 /** 164 Returns the cache of up vectors as a $(D PoolVector3Array). 165 If $(D upVectorEnabled) is `false`, the cache will be empty. 166 */ 167 PoolVector3Array getBakedUpVectors() const 168 { 169 checkClassBinding!(typeof(this))(); 170 return ptrcall!(PoolVector3Array)(GDNativeClassBinding.getBakedUpVectors, _godot_object); 171 } 172 /** 173 Returns the closest offset to `to_point`. This offset is meant to be used in $(D interpolateBaked) or $(D interpolateBakedUpVector). 174 `to_point` must be in this curve's local space. 175 */ 176 double getClosestOffset(in Vector3 to_point) const 177 { 178 checkClassBinding!(typeof(this))(); 179 return ptrcall!(double)(GDNativeClassBinding.getClosestOffset, _godot_object, to_point); 180 } 181 /** 182 Returns the closest baked point (in curve's local space) to `to_point`. 183 `to_point` must be in this curve's local space. 184 */ 185 Vector3 getClosestPoint(in Vector3 to_point) const 186 { 187 checkClassBinding!(typeof(this))(); 188 return ptrcall!(Vector3)(GDNativeClassBinding.getClosestPoint, _godot_object, to_point); 189 } 190 /** 191 Returns the number of points describing the curve. 192 */ 193 long getPointCount() const 194 { 195 checkClassBinding!(typeof(this))(); 196 return ptrcall!(long)(GDNativeClassBinding.getPointCount, _godot_object); 197 } 198 /** 199 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, 0)`. 200 */ 201 Vector3 getPointIn(in long idx) const 202 { 203 checkClassBinding!(typeof(this))(); 204 return ptrcall!(Vector3)(GDNativeClassBinding.getPointIn, _godot_object, idx); 205 } 206 /** 207 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, 0)`. 208 */ 209 Vector3 getPointOut(in long idx) const 210 { 211 checkClassBinding!(typeof(this))(); 212 return ptrcall!(Vector3)(GDNativeClassBinding.getPointOut, _godot_object, idx); 213 } 214 /** 215 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, 0)`. 216 */ 217 Vector3 getPointPosition(in long idx) const 218 { 219 checkClassBinding!(typeof(this))(); 220 return ptrcall!(Vector3)(GDNativeClassBinding.getPointPosition, _godot_object, idx); 221 } 222 /** 223 Returns the tilt angle in radians for the point `idx`. If the index is out of bounds, the function sends an error to the console, and returns `0`. 224 */ 225 double getPointTilt(in long idx) const 226 { 227 checkClassBinding!(typeof(this))(); 228 return ptrcall!(double)(GDNativeClassBinding.getPointTilt, _godot_object, idx); 229 } 230 /** 231 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. 232 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, 0)`. 233 */ 234 Vector3 interpolate(in long idx, in double t) const 235 { 236 checkClassBinding!(typeof(this))(); 237 return ptrcall!(Vector3)(GDNativeClassBinding.interpolate, _godot_object, idx, t); 238 } 239 /** 240 Returns a point within the curve at position `offset`, where `offset` is measured as a distance in 3D units along the curve. 241 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`. 242 Cubic interpolation tends to follow the curves better, but linear is faster (and often, precise enough). 243 */ 244 Vector3 interpolateBaked(in double offset, in bool cubic = false) const 245 { 246 checkClassBinding!(typeof(this))(); 247 return ptrcall!(Vector3)(GDNativeClassBinding.interpolateBaked, _godot_object, offset, cubic); 248 } 249 /** 250 Returns an up vector within the curve at position `offset`, where `offset` is measured as a distance in 3D units along the curve. 251 To do that, it finds the two cached up vectors where the `offset` lies between, then interpolates the values. If `apply_tilt` is `true`, an interpolated tilt is applied to the interpolated up vector. 252 If the curve has no up vectors, the function sends an error to the console, and returns `(0, 1, 0)`. 253 */ 254 Vector3 interpolateBakedUpVector(in double offset, in bool apply_tilt = false) const 255 { 256 checkClassBinding!(typeof(this))(); 257 return ptrcall!(Vector3)(GDNativeClassBinding.interpolateBakedUpVector, _godot_object, offset, apply_tilt); 258 } 259 /** 260 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`. 261 */ 262 Vector3 interpolatef(in double fofs) const 263 { 264 checkClassBinding!(typeof(this))(); 265 return ptrcall!(Vector3)(GDNativeClassBinding.interpolatef, _godot_object, fofs); 266 } 267 /** 268 269 */ 270 bool isUpVectorEnabled() const 271 { 272 checkClassBinding!(typeof(this))(); 273 return ptrcall!(bool)(GDNativeClassBinding.isUpVectorEnabled, _godot_object); 274 } 275 /** 276 Deletes the point `idx` from the curve. Sends an error to the console if `idx` is out of bounds. 277 */ 278 void removePoint(in long idx) 279 { 280 checkClassBinding!(typeof(this))(); 281 ptrcall!(void)(GDNativeClassBinding.removePoint, _godot_object, idx); 282 } 283 /** 284 285 */ 286 void setBakeInterval(in double distance) 287 { 288 checkClassBinding!(typeof(this))(); 289 ptrcall!(void)(GDNativeClassBinding.setBakeInterval, _godot_object, distance); 290 } 291 /** 292 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. 293 */ 294 void setPointIn(in long idx, in Vector3 position) 295 { 296 checkClassBinding!(typeof(this))(); 297 ptrcall!(void)(GDNativeClassBinding.setPointIn, _godot_object, idx, position); 298 } 299 /** 300 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. 301 */ 302 void setPointOut(in long idx, in Vector3 position) 303 { 304 checkClassBinding!(typeof(this))(); 305 ptrcall!(void)(GDNativeClassBinding.setPointOut, _godot_object, idx, position); 306 } 307 /** 308 Sets the position for the vertex `idx`. If the index is out of bounds, the function sends an error to the console. 309 */ 310 void setPointPosition(in long idx, in Vector3 position) 311 { 312 checkClassBinding!(typeof(this))(); 313 ptrcall!(void)(GDNativeClassBinding.setPointPosition, _godot_object, idx, position); 314 } 315 /** 316 Sets the tilt angle in radians for the point `idx`. If the index is out of bounds, the function sends an error to the console. 317 The tilt controls the rotation along the look-at axis an object traveling the path would have. In the case of a curve controlling a $(D PathFollow), this tilt is an offset over the natural tilt the $(D PathFollow) calculates. 318 */ 319 void setPointTilt(in long idx, in double tilt) 320 { 321 checkClassBinding!(typeof(this))(); 322 ptrcall!(void)(GDNativeClassBinding.setPointTilt, _godot_object, idx, tilt); 323 } 324 /** 325 326 */ 327 void setUpVectorEnabled(in bool enable) 328 { 329 checkClassBinding!(typeof(this))(); 330 ptrcall!(void)(GDNativeClassBinding.setUpVectorEnabled, _godot_object, enable); 331 } 332 /** 333 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. 334 This approximation makes straight segments between each point, then subdivides those segments until the resulting shape is similar enough. 335 `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! 336 `tolerance_degrees` controls how many degrees the midpoint of a segment may deviate from the real curve, before the segment has to be subdivided. 337 */ 338 PoolVector3Array tessellate(in long max_stages = 5, in double tolerance_degrees = 4) const 339 { 340 checkClassBinding!(typeof(this))(); 341 return ptrcall!(PoolVector3Array)(GDNativeClassBinding.tessellate, _godot_object, max_stages, tolerance_degrees); 342 } 343 /** 344 345 */ 346 @property Dictionary _data() 347 { 348 return _getData(); 349 } 350 /// ditto 351 @property void _data(Dictionary v) 352 { 353 _setData(v); 354 } 355 /** 356 The distance in meters 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. 357 */ 358 @property double bakeInterval() 359 { 360 return getBakeInterval(); 361 } 362 /// ditto 363 @property void bakeInterval(double v) 364 { 365 setBakeInterval(v); 366 } 367 /** 368 If `true`, the curve will bake up vectors used for orientation. This is used when $(D PathFollow.rotationMode) is set to $(D constant PathFollow.ROTATION_ORIENTED). Changing it forces the cache to be recomputed. 369 */ 370 @property bool upVectorEnabled() 371 { 372 return isUpVectorEnabled(); 373 } 374 /// ditto 375 @property void upVectorEnabled(bool v) 376 { 377 setUpVectorEnabled(v); 378 } 379 }