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.raycast; 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.spatial; 25 /** 26 Query the closest object intersecting a ray. 27 28 A RayCast represents a line from its origin to its destination position, `cast_to`. It is used to query the 3D space in order to find the closest object along the path of the ray. 29 RayCast can ignore some objects by adding them to the exception list via `add_exception` or by setting proper filtering with collision layers and masks. 30 RayCast can be configured to report collisions with $(D Area)s ($(D collideWithAreas)) and/or $(D PhysicsBody)s ($(D collideWithBodies)). 31 Only enabled raycasts will be able to query the space and report collisions. 32 RayCast 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. 33 */ 34 @GodotBaseClass struct RayCast 35 { 36 package(godot) enum string _GODOT_internal_name = "RayCast"; 37 public: 38 @nogc nothrow: 39 union { /** */ godot_object _godot_object; /** */ Spatial _GODOT_base; } 40 alias _GODOT_base this; 41 alias BaseClasses = AliasSeq!(typeof(_GODOT_base), typeof(_GODOT_base).BaseClasses); 42 package(godot) __gshared bool _classBindingInitialized = false; 43 package(godot) static struct GDNativeClassBinding 44 { 45 __gshared: 46 @GodotName("add_exception") GodotMethod!(void, GodotObject) addException; 47 @GodotName("add_exception_rid") GodotMethod!(void, RID) addExceptionRid; 48 @GodotName("clear_exceptions") GodotMethod!(void) clearExceptions; 49 @GodotName("force_raycast_update") GodotMethod!(void) forceRaycastUpdate; 50 @GodotName("get_cast_to") GodotMethod!(Vector3) getCastTo; 51 @GodotName("get_collider") GodotMethod!(GodotObject) getCollider; 52 @GodotName("get_collider_shape") GodotMethod!(long) getColliderShape; 53 @GodotName("get_collision_mask") GodotMethod!(long) getCollisionMask; 54 @GodotName("get_collision_mask_bit") GodotMethod!(bool, long) getCollisionMaskBit; 55 @GodotName("get_collision_normal") GodotMethod!(Vector3) getCollisionNormal; 56 @GodotName("get_collision_point") GodotMethod!(Vector3) getCollisionPoint; 57 @GodotName("get_exclude_parent_body") GodotMethod!(bool) getExcludeParentBody; 58 @GodotName("is_collide_with_areas_enabled") GodotMethod!(bool) isCollideWithAreasEnabled; 59 @GodotName("is_collide_with_bodies_enabled") GodotMethod!(bool) isCollideWithBodiesEnabled; 60 @GodotName("is_colliding") GodotMethod!(bool) isColliding; 61 @GodotName("is_enabled") GodotMethod!(bool) isEnabled; 62 @GodotName("remove_exception") GodotMethod!(void, GodotObject) removeException; 63 @GodotName("remove_exception_rid") GodotMethod!(void, RID) removeExceptionRid; 64 @GodotName("set_cast_to") GodotMethod!(void, Vector3) setCastTo; 65 @GodotName("set_collide_with_areas") GodotMethod!(void, bool) setCollideWithAreas; 66 @GodotName("set_collide_with_bodies") GodotMethod!(void, bool) setCollideWithBodies; 67 @GodotName("set_collision_mask") GodotMethod!(void, long) setCollisionMask; 68 @GodotName("set_collision_mask_bit") GodotMethod!(void, long, bool) setCollisionMaskBit; 69 @GodotName("set_enabled") GodotMethod!(void, bool) setEnabled; 70 @GodotName("set_exclude_parent_body") GodotMethod!(void, bool) setExcludeParentBody; 71 } 72 /// 73 pragma(inline, true) bool opEquals(in RayCast other) const 74 { return _godot_object.ptr is other._godot_object.ptr; } 75 /// 76 pragma(inline, true) typeof(null) opAssign(typeof(null) n) 77 { _godot_object.ptr = n; return null; } 78 /// 79 pragma(inline, true) bool opEquals(typeof(null) n) const 80 { return _godot_object.ptr is n; } 81 /// 82 size_t toHash() const @trusted { return cast(size_t)_godot_object.ptr; } 83 mixin baseCasts; 84 /// Construct a new instance of RayCast. 85 /// Note: use `memnew!RayCast` instead. 86 static RayCast _new() 87 { 88 static godot_class_constructor constructor; 89 if(constructor is null) constructor = _godot_api.godot_get_class_constructor("RayCast"); 90 if(constructor is null) return typeof(this).init; 91 return cast(RayCast)(constructor()); 92 } 93 @disable new(size_t s); 94 /** 95 Adds a collision exception so the ray does not report collisions with the specified node. 96 */ 97 void addException(GodotObject node) 98 { 99 checkClassBinding!(typeof(this))(); 100 ptrcall!(void)(GDNativeClassBinding.addException, _godot_object, node); 101 } 102 /** 103 Adds a collision exception so the ray does not report collisions with the specified $(D RID). 104 */ 105 void addExceptionRid(in RID rid) 106 { 107 checkClassBinding!(typeof(this))(); 108 ptrcall!(void)(GDNativeClassBinding.addExceptionRid, _godot_object, rid); 109 } 110 /** 111 Removes all collision exceptions for this ray. 112 */ 113 void clearExceptions() 114 { 115 checkClassBinding!(typeof(this))(); 116 ptrcall!(void)(GDNativeClassBinding.clearExceptions, _godot_object); 117 } 118 /** 119 Updates the collision information for the ray. 120 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. 121 $(B Note:) `enabled` is not required for this to work. 122 */ 123 void forceRaycastUpdate() 124 { 125 checkClassBinding!(typeof(this))(); 126 ptrcall!(void)(GDNativeClassBinding.forceRaycastUpdate, _godot_object); 127 } 128 /** 129 130 */ 131 Vector3 getCastTo() const 132 { 133 checkClassBinding!(typeof(this))(); 134 return ptrcall!(Vector3)(GDNativeClassBinding.getCastTo, _godot_object); 135 } 136 /** 137 Returns the first object that the ray intersects, or `null` if no object is intersecting the ray (i.e. $(D isColliding) returns `false`). 138 */ 139 GodotObject getCollider() const 140 { 141 checkClassBinding!(typeof(this))(); 142 return ptrcall!(GodotObject)(GDNativeClassBinding.getCollider, _godot_object); 143 } 144 /** 145 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`). 146 */ 147 long getColliderShape() const 148 { 149 checkClassBinding!(typeof(this))(); 150 return ptrcall!(long)(GDNativeClassBinding.getColliderShape, _godot_object); 151 } 152 /** 153 154 */ 155 long getCollisionMask() const 156 { 157 checkClassBinding!(typeof(this))(); 158 return ptrcall!(long)(GDNativeClassBinding.getCollisionMask, _godot_object); 159 } 160 /** 161 Returns `true` if the bit index passed is turned on. 162 $(B Note:) Bit indices range from 0-19. 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 Vector3 getCollisionNormal() const 173 { 174 checkClassBinding!(typeof(this))(); 175 return ptrcall!(Vector3)(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 Vector3 getCollisionPoint() const 182 { 183 checkClassBinding!(typeof(this))(); 184 return ptrcall!(Vector3)(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 Vector3 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 the bit index passed to the `value` passed. 276 $(B Note:) Bit indexes range from 0-19. 277 */ 278 void setCollisionMaskBit(in long bit, in bool value) 279 { 280 checkClassBinding!(typeof(this))(); 281 ptrcall!(void)(GDNativeClassBinding.setCollisionMaskBit, _godot_object, bit, value); 282 } 283 /** 284 285 */ 286 void setEnabled(in bool enabled) 287 { 288 checkClassBinding!(typeof(this))(); 289 ptrcall!(void)(GDNativeClassBinding.setEnabled, _godot_object, enabled); 290 } 291 /** 292 293 */ 294 void setExcludeParentBody(in bool mask) 295 { 296 checkClassBinding!(typeof(this))(); 297 ptrcall!(void)(GDNativeClassBinding.setExcludeParentBody, _godot_object, mask); 298 } 299 /** 300 The ray's destination point, relative to the RayCast's `position`. 301 */ 302 @property Vector3 castTo() 303 { 304 return getCastTo(); 305 } 306 /// ditto 307 @property void castTo(Vector3 v) 308 { 309 setCastTo(v); 310 } 311 /** 312 If `true`, collision with $(D Area)s will be reported. 313 */ 314 @property bool collideWithAreas() 315 { 316 return isCollideWithAreasEnabled(); 317 } 318 /// ditto 319 @property void collideWithAreas(bool v) 320 { 321 setCollideWithAreas(v); 322 } 323 /** 324 If `true`, collision with $(D PhysicsBody)s will be reported. 325 */ 326 @property bool collideWithBodies() 327 { 328 return isCollideWithBodiesEnabled(); 329 } 330 /// ditto 331 @property void collideWithBodies(bool v) 332 { 333 setCollideWithBodies(v); 334 } 335 /** 336 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. 337 */ 338 @property long collisionMask() 339 { 340 return getCollisionMask(); 341 } 342 /// ditto 343 @property void collisionMask(long v) 344 { 345 setCollisionMask(v); 346 } 347 /** 348 If `true`, collisions will be reported. 349 */ 350 @property bool enabled() 351 { 352 return isEnabled(); 353 } 354 /// ditto 355 @property void enabled(bool v) 356 { 357 setEnabled(v); 358 } 359 /** 360 If `true`, collisions will be ignored for this RayCast's immediate parent. 361 */ 362 @property bool excludeParent() 363 { 364 return getExcludeParentBody(); 365 } 366 /// ditto 367 @property void excludeParent(bool v) 368 { 369 setExcludeParentBody(v); 370 } 371 }