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