Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
RayCylinder.h
Go to the documentation of this file.
1// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
8
10
17JPH_INLINE float RayCylinder(Vec3Arg inRayOrigin, Vec3Arg inRayDirection, float inCylinderRadius)
18{
19 // Remove Y component of ray to see of ray intersects with infinite cylinder
20 UVec4 mask_y = UVec4(0, 0xffffffff, 0, 0);
21 Vec3 origin_xz = Vec3::sSelect(inRayOrigin, Vec3::sZero(), mask_y);
22 float origin_xz_len_sq = origin_xz.LengthSq();
23 float r_sq = Square(inCylinderRadius);
24 if (origin_xz_len_sq > r_sq)
25 {
26 // Ray starts outside of the infinite cylinder
27 // Solve: |RayOrigin_xz + fraction * RayDirection_xz|^2 = r^2 to find fraction
28 Vec3 direction_xz = Vec3::sSelect(inRayDirection, Vec3::sZero(), mask_y);
29 float a = direction_xz.LengthSq();
30 float b = 2.0f * origin_xz.Dot(direction_xz);
31 float c = origin_xz_len_sq - r_sq;
32 float fraction1, fraction2;
33 if (FindRoot(a, b, c, fraction1, fraction2) == 0)
34 return FLT_MAX; // No intersection with infinite cylinder
35
36 // Get fraction corresponding to the ray entering the circle
37 float fraction = min(fraction1, fraction2);
38 if (fraction >= 0.0f)
39 return fraction;
40 }
41 else
42 {
43 // Ray starts inside the infinite cylinder
44 return 0.0f;
45 }
46
47 // No collision
48 return FLT_MAX;
49}
50
57JPH_INLINE float RayCylinder(Vec3Arg inRayOrigin, Vec3Arg inRayDirection, float inCylinderHalfHeight, float inCylinderRadius)
58{
59 // Test infinite cylinder
60 float fraction = RayCylinder(inRayOrigin, inRayDirection, inCylinderRadius);
61 if (fraction == FLT_MAX)
62 return FLT_MAX;
63
64 // If this hit is in the finite cylinder we have our fraction
65 if (abs(inRayOrigin.GetY() + fraction * inRayDirection.GetY()) <= inCylinderHalfHeight)
66 return fraction;
67
68 // Check if ray could hit the top or bottom plane of the cylinder
69 float direction_y = inRayDirection.GetY();
70 if (direction_y != 0.0f)
71 {
72 // Solving line equation: x = ray_origin + fraction * ray_direction
73 // and plane equation: plane_normal . x + plane_constant = 0
74 // fraction = (-plane_constant - plane_normal . ray_origin) / (plane_normal . ray_direction)
75 // when the ray_direction.y < 0:
76 // plane_constant = -cylinder_half_height, plane_normal = (0, 1, 0)
77 // else
78 // plane_constant = -cylinder_half_height, plane_normal = (0, -1, 0)
79 float origin_y = inRayOrigin.GetY();
80 float plane_fraction;
81 if (direction_y < 0.0f)
82 plane_fraction = (inCylinderHalfHeight - origin_y) / direction_y;
83 else
84 plane_fraction = -(inCylinderHalfHeight + origin_y) / direction_y;
85
86 // Check if the hit is in front of the ray
87 if (plane_fraction >= 0.0f)
88 {
89 // Test if this hit is inside the cylinder
90 Vec3 point = inRayOrigin + plane_fraction * inRayDirection;
91 float dist_sq = Square(point.GetX()) + Square(point.GetZ());
92 if (dist_sq <= Square(inCylinderRadius))
93 return plane_fraction;
94 }
95 }
96
97 // No collision
98 return FLT_MAX;
99}
100
#define JPH_NAMESPACE_END
Definition: Core.h:378
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:372
JPH_NAMESPACE_BEGIN int FindRoot(const T inA, const T inB, const T inC, T &outX1, T &outX2)
Definition: FindRoot.h:13
JPH_INLINE constexpr T Square(T inV)
Square a value.
Definition: Math.h:52
JPH_NAMESPACE_BEGIN JPH_INLINE float RayCylinder(Vec3Arg inRayOrigin, Vec3Arg inRayDirection, float inCylinderRadius)
Definition: RayCylinder.h:17
Definition: UVec4.h:12
Definition: Vec3.h:17
JPH_INLINE float Dot(Vec3Arg inV2) const
Dot product.
Definition: Vec3.inl:649
JPH_INLINE float GetX() const
Get individual components.
Definition: Vec3.h:124
JPH_INLINE float GetY() const
Definition: Vec3.h:125
JPH_INLINE float LengthSq() const
Squared length of vector.
Definition: Vec3.inl:665
static JPH_INLINE Vec3 sZero()
Vector with all zeros.
Definition: Vec3.inl:107
static JPH_INLINE Vec3 sSelect(Vec3Arg inNotSet, Vec3Arg inSet, UVec4Arg inControl)
Component wise select, returns inNotSet when highest bit of inControl = 0 and inSet when highest bit ...
Definition: Vec3.inl:269
JPH_INLINE float GetZ() const
Definition: Vec3.h:126