1 /** 2 Query the closest object intersecting a ray. 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.raycast2d; 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.node2d; 25 import godot.canvasitem; 26 import godot.node; 27 /** 28 Query the closest object intersecting a ray. 29 30 A RayCast represents a line from its origin to its destination position, `cast_to`. It is used to query the 2D space in order to find the closest object along the path of the ray. 31 RayCast2D can ignore some objects by adding them to the exception list via `add_exception`, by setting proper filtering with collision layers, or by filtering object types with type masks. 32 RayCast2D can be configured to report collisions with $(D Area2D)s ($(D collideWithAreas)) and/or $(D PhysicsBody2D)s ($(D collideWithBodies)). 33 Only enabled raycasts will be able to query the space and report collisions. 34 RayCast2D calculates intersection every physics frame (see $(D Node)), and the result is cached so it can be used later until the next frame. If multiple queries are required between physics frames (or during the same frame) use $(D forceRaycastUpdate) after adjusting the raycast. 35 */ 36 @GodotBaseClass struct RayCast2D 37 { 38 package(godot) enum string _GODOT_internal_name = "RayCast2D"; 39 public: 40 @nogc nothrow: 41 union { /** */ godot_object _godot_object; /** */ Node2D _GODOT_base; } 42 alias _GODOT_base this; 43 alias BaseClasses = AliasSeq!(typeof(_GODOT_base), typeof(_GODOT_base).BaseClasses); 44 package(godot) __gshared bool _classBindingInitialized = false; 45 package(godot) static struct GDNativeClassBinding 46 { 47 __gshared: 48 @GodotName("add_exception") GodotMethod!(void, GodotObject) addException; 49 @GodotName("add_exception_rid") GodotMethod!(void, RID) addExceptionRid; 50 @GodotName("clear_exceptions") GodotMethod!(void) clearExceptions; 51 @GodotName("force_raycast_update") GodotMethod!(void) forceRaycastUpdate; 52 @GodotName("get_cast_to") GodotMethod!(Vector2) getCastTo; 53 @GodotName("get_collider") GodotMethod!(GodotObject) getCollider; 54 @GodotName("get_collider_shape") GodotMethod!(long) getColliderShape; 55 @GodotName("get_collision_mask") GodotMethod!(long) getCollisionMask; 56 @GodotName("get_collision_mask_bit") GodotMethod!(bool, long) getCollisionMaskBit; 57 @GodotName("get_collision_normal") GodotMethod!(Vector2) getCollisionNormal; 58 @GodotName("get_collision_point") GodotMethod!(Vector2) getCollisionPoint; 59 @GodotName("get_exclude_parent_body") GodotMethod!(bool) getExcludeParentBody; 60 @GodotName("is_collide_with_areas_enabled") GodotMethod!(bool) isCollideWithAreasEnabled; 61 @GodotName("is_collide_with_bodies_enabled") GodotMethod!(bool) isCollideWithBodiesEnabled; 62 @GodotName("is_colliding") GodotMethod!(bool) isColliding; 63 @GodotName("is_enabled") GodotMethod!(bool) isEnabled; 64 @GodotName("remove_exception") GodotMethod!(void, GodotObject) removeException; 65 @GodotName("remove_exception_rid") GodotMethod!(void, RID) removeExceptionRid; 66 @GodotName("set_cast_to") GodotMethod!(void, Vector2) setCastTo; 67 @GodotName("set_collide_with_areas") GodotMethod!(void, bool) setCollideWithAreas; 68 @GodotName("set_collide_with_bodies") GodotMethod!(void, bool) setCollideWithBodies; 69 @GodotName("set_collision_mask") GodotMethod!(void, long) setCollisionMask; 70 @GodotName("set_collision_mask_bit") GodotMethod!(void, long, bool) setCollisionMaskBit; 71 @GodotName("set_enabled") GodotMethod!(void, bool) setEnabled; 72 @GodotName("set_exclude_parent_body") GodotMethod!(void, bool) setExcludeParentBody; 73 } 74 /// 75 pragma(inline, true) bool opEquals(in RayCast2D other) const 76 { return _godot_object.ptr is other._godot_object.ptr; } 77 /// 78 pragma(inline, true) typeof(null) opAssign(typeof(null) n) 79 { _godot_object.ptr = n; return null; } 80 /// 81 pragma(inline, true) bool opEquals(typeof(null) n) const 82 { return _godot_object.ptr is n; } 83 /// 84 size_t toHash() const @trusted { return cast(size_t)_godot_object.ptr; } 85 mixin baseCasts; 86 /// Construct a new instance of RayCast2D. 87 /// Note: use `memnew!RayCast2D` instead. 88 static RayCast2D _new() 89 { 90 static godot_class_constructor constructor; 91 if(constructor is null) constructor = _godot_api.godot_get_class_constructor("RayCast2D"); 92 if(constructor is null) return typeof(this).init; 93 return cast(RayCast2D)(constructor()); 94 } 95 @disable new(size_t s); 96 /** 97 Adds a collision exception so the ray does not report collisions with the specified node. 98 */ 99 void addException(GodotObject node) 100 { 101 checkClassBinding!(typeof(this))(); 102 ptrcall!(void)(GDNativeClassBinding.addException, _godot_object, node); 103 } 104 /** 105 Adds a collision exception so the ray does not report collisions with the specified $(D RID). 106 */ 107 void addExceptionRid(in RID rid) 108 { 109 checkClassBinding!(typeof(this))(); 110 ptrcall!(void)(GDNativeClassBinding.addExceptionRid, _godot_object, rid); 111 } 112 /** 113 Removes all collision exceptions for this ray. 114 */ 115 void clearExceptions() 116 { 117 checkClassBinding!(typeof(this))(); 118 ptrcall!(void)(GDNativeClassBinding.clearExceptions, _godot_object); 119 } 120 /** 121 Updates the collision information for the ray. Use this method to update the collision information immediately instead of waiting for the next `_physics_process` call, for example if the ray or its parent has changed state. 122 $(B Note:) `enabled` is not required for this to work. 123 */ 124 void forceRaycastUpdate() 125 { 126 checkClassBinding!(typeof(this))(); 127 ptrcall!(void)(GDNativeClassBinding.forceRaycastUpdate, _godot_object); 128 } 129 /** 130 131 */ 132 Vector2 getCastTo() const 133 { 134 checkClassBinding!(typeof(this))(); 135 return ptrcall!(Vector2)(GDNativeClassBinding.getCastTo, _godot_object); 136 } 137 /** 138 Returns the first object that the ray intersects, or `null` if no object is intersecting the ray (i.e. $(D isColliding) returns `false`). 139 */ 140 GodotObject getCollider() const 141 { 142 checkClassBinding!(typeof(this))(); 143 return ptrcall!(GodotObject)(GDNativeClassBinding.getCollider, _godot_object); 144 } 145 /** 146 Returns the shape ID of the first object that the ray intersects, or `0` if no object is intersecting the ray (i.e. $(D isColliding) returns `false`). 147 */ 148 long getColliderShape() const 149 { 150 checkClassBinding!(typeof(this))(); 151 return ptrcall!(long)(GDNativeClassBinding.getColliderShape, _godot_object); 152 } 153 /** 154 155 */ 156 long getCollisionMask() const 157 { 158 checkClassBinding!(typeof(this))(); 159 return ptrcall!(long)(GDNativeClassBinding.getCollisionMask, _godot_object); 160 } 161 /** 162 Returns an individual bit on the collision mask. 163 */ 164 bool getCollisionMaskBit(in long bit) const 165 { 166 checkClassBinding!(typeof(this))(); 167 return ptrcall!(bool)(GDNativeClassBinding.getCollisionMaskBit, _godot_object, bit); 168 } 169 /** 170 Returns the normal of the intersecting object's shape at the collision point. 171 */ 172 Vector2 getCollisionNormal() const 173 { 174 checkClassBinding!(typeof(this))(); 175 return ptrcall!(Vector2)(GDNativeClassBinding.getCollisionNormal, _godot_object); 176 } 177 /** 178 Returns the collision point at which the ray intersects the closest object. 179 $(B Note:) this point is in the $(B global) coordinate system. 180 */ 181 Vector2 getCollisionPoint() const 182 { 183 checkClassBinding!(typeof(this))(); 184 return ptrcall!(Vector2)(GDNativeClassBinding.getCollisionPoint, _godot_object); 185 } 186 /** 187 188 */ 189 bool getExcludeParentBody() const 190 { 191 checkClassBinding!(typeof(this))(); 192 return ptrcall!(bool)(GDNativeClassBinding.getExcludeParentBody, _godot_object); 193 } 194 /** 195 196 */ 197 bool isCollideWithAreasEnabled() const 198 { 199 checkClassBinding!(typeof(this))(); 200 return ptrcall!(bool)(GDNativeClassBinding.isCollideWithAreasEnabled, _godot_object); 201 } 202 /** 203 204 */ 205 bool isCollideWithBodiesEnabled() const 206 { 207 checkClassBinding!(typeof(this))(); 208 return ptrcall!(bool)(GDNativeClassBinding.isCollideWithBodiesEnabled, _godot_object); 209 } 210 /** 211 Returns whether any object is intersecting with the ray's vector (considering the vector length). 212 */ 213 bool isColliding() const 214 { 215 checkClassBinding!(typeof(this))(); 216 return ptrcall!(bool)(GDNativeClassBinding.isColliding, _godot_object); 217 } 218 /** 219 220 */ 221 bool isEnabled() const 222 { 223 checkClassBinding!(typeof(this))(); 224 return ptrcall!(bool)(GDNativeClassBinding.isEnabled, _godot_object); 225 } 226 /** 227 Removes a collision exception so the ray does report collisions with the specified node. 228 */ 229 void removeException(GodotObject node) 230 { 231 checkClassBinding!(typeof(this))(); 232 ptrcall!(void)(GDNativeClassBinding.removeException, _godot_object, node); 233 } 234 /** 235 Removes a collision exception so the ray does report collisions with the specified $(D RID). 236 */ 237 void removeExceptionRid(in RID rid) 238 { 239 checkClassBinding!(typeof(this))(); 240 ptrcall!(void)(GDNativeClassBinding.removeExceptionRid, _godot_object, rid); 241 } 242 /** 243 244 */ 245 void setCastTo(in Vector2 local_point) 246 { 247 checkClassBinding!(typeof(this))(); 248 ptrcall!(void)(GDNativeClassBinding.setCastTo, _godot_object, local_point); 249 } 250 /** 251 252 */ 253 void setCollideWithAreas(in bool enable) 254 { 255 checkClassBinding!(typeof(this))(); 256 ptrcall!(void)(GDNativeClassBinding.setCollideWithAreas, _godot_object, enable); 257 } 258 /** 259 260 */ 261 void setCollideWithBodies(in bool enable) 262 { 263 checkClassBinding!(typeof(this))(); 264 ptrcall!(void)(GDNativeClassBinding.setCollideWithBodies, _godot_object, enable); 265 } 266 /** 267 268 */ 269 void setCollisionMask(in long mask) 270 { 271 checkClassBinding!(typeof(this))(); 272 ptrcall!(void)(GDNativeClassBinding.setCollisionMask, _godot_object, mask); 273 } 274 /** 275 Sets or clears individual bits on the collision mask. This makes selecting the areas scanned easier. 276 */ 277 void setCollisionMaskBit(in long bit, in bool value) 278 { 279 checkClassBinding!(typeof(this))(); 280 ptrcall!(void)(GDNativeClassBinding.setCollisionMaskBit, _godot_object, bit, value); 281 } 282 /** 283 284 */ 285 void setEnabled(in bool enabled) 286 { 287 checkClassBinding!(typeof(this))(); 288 ptrcall!(void)(GDNativeClassBinding.setEnabled, _godot_object, enabled); 289 } 290 /** 291 292 */ 293 void setExcludeParentBody(in bool mask) 294 { 295 checkClassBinding!(typeof(this))(); 296 ptrcall!(void)(GDNativeClassBinding.setExcludeParentBody, _godot_object, mask); 297 } 298 /** 299 The ray's destination point, relative to the RayCast's `position`. 300 */ 301 @property Vector2 castTo() 302 { 303 return getCastTo(); 304 } 305 /// ditto 306 @property void castTo(Vector2 v) 307 { 308 setCastTo(v); 309 } 310 /** 311 If `true`, collision with $(D Area2D)s will be reported. 312 */ 313 @property bool collideWithAreas() 314 { 315 return isCollideWithAreasEnabled(); 316 } 317 /// ditto 318 @property void collideWithAreas(bool v) 319 { 320 setCollideWithAreas(v); 321 } 322 /** 323 If `true`, collision with $(D PhysicsBody2D)s will be reported. 324 */ 325 @property bool collideWithBodies() 326 { 327 return isCollideWithBodiesEnabled(); 328 } 329 /// ditto 330 @property void collideWithBodies(bool v) 331 { 332 setCollideWithBodies(v); 333 } 334 /** 335 The ray's collision mask. Only objects in at least one collision layer enabled in the mask will be detected. See $(D url=https://docs.godotengine.org/en/3.3/tutorials/physics/physics_introduction.html#collision-layers-and-masks)Collision layers and masks$(D /url) in the documentation for more information. 336 */ 337 @property long collisionMask() 338 { 339 return getCollisionMask(); 340 } 341 /// ditto 342 @property void collisionMask(long v) 343 { 344 setCollisionMask(v); 345 } 346 /** 347 If `true`, collisions will be reported. 348 */ 349 @property bool enabled() 350 { 351 return isEnabled(); 352 } 353 /// ditto 354 @property void enabled(bool v) 355 { 356 setEnabled(v); 357 } 358 /** 359 If `true`, the parent node will be excluded from collision detection. 360 */ 361 @property bool excludeParent() 362 { 363 return getExcludeParentBody(); 364 } 365 /// ditto 366 @property void excludeParent(bool v) 367 { 368 setExcludeParentBody(v); 369 } 370 }