Path: blob/master/thirdparty/jolt_physics/Jolt/Geometry/RaySphere.h
9913 views
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)1// SPDX-FileCopyrightText: 2021 Jorrit Rouwe2// SPDX-License-Identifier: MIT34#pragma once56#include <Jolt/Math/FindRoot.h>78JPH_NAMESPACE_BEGIN910/// Tests a ray starting at inRayOrigin and extending infinitely in inRayDirection against a sphere,11/// @return FLT_MAX if there is no intersection, otherwise the fraction along the ray.12/// @param inRayOrigin Ray origin. If the ray starts inside the sphere, the returned fraction will be 0.13/// @param inRayDirection Ray direction. Does not need to be normalized.14/// @param inSphereCenter Position of the center of the sphere15/// @param inSphereRadius Radius of the sphere16JPH_INLINE float RaySphere(Vec3Arg inRayOrigin, Vec3Arg inRayDirection, Vec3Arg inSphereCenter, float inSphereRadius)17{18// Solve: |RayOrigin + fraction * RayDirection - SphereCenter|^2 = SphereRadius^2 for fraction19Vec3 center_origin = inRayOrigin - inSphereCenter;20float a = inRayDirection.LengthSq();21float b = 2.0f * inRayDirection.Dot(center_origin);22float c = center_origin.LengthSq() - inSphereRadius * inSphereRadius;23float fraction1, fraction2;24if (FindRoot(a, b, c, fraction1, fraction2) == 0)25return c <= 0.0f? 0.0f : FLT_MAX; // Return if origin is inside the sphere2627// Sort so that the smallest is first28if (fraction1 > fraction2)29std::swap(fraction1, fraction2);3031// Test solution with lowest fraction, this will be the ray entering the sphere32if (fraction1 >= 0.0f)33return fraction1; // Sphere is before the ray start3435// Test solution with highest fraction, this will be the ray leaving the sphere36if (fraction2 >= 0.0f)37return 0.0f; // We start inside the sphere3839// No solution40return FLT_MAX;41}4243/// Tests a ray starting at inRayOrigin and extending infinitely in inRayDirection against a sphere.44/// Outputs entry and exit points (outMinFraction and outMaxFraction) along the ray (which could be negative if the hit point is before the start of the ray).45/// @param inRayOrigin Ray origin. If the ray starts inside the sphere, the returned fraction will be 0.46/// @param inRayDirection Ray direction. Does not need to be normalized.47/// @param inSphereCenter Position of the center of the sphere.48/// @param inSphereRadius Radius of the sphere.49/// @param outMinFraction Returned lowest intersection fraction50/// @param outMaxFraction Returned highest intersection fraction51/// @return The amount of intersections with the sphere.52/// If 1 intersection is returned outMinFraction will be equal to outMaxFraction53JPH_INLINE int RaySphere(Vec3Arg inRayOrigin, Vec3Arg inRayDirection, Vec3Arg inSphereCenter, float inSphereRadius, float &outMinFraction, float &outMaxFraction)54{55// Solve: |RayOrigin + fraction * RayDirection - SphereCenter|^2 = SphereRadius^2 for fraction56Vec3 center_origin = inRayOrigin - inSphereCenter;57float a = inRayDirection.LengthSq();58float b = 2.0f * inRayDirection.Dot(center_origin);59float c = center_origin.LengthSq() - inSphereRadius * inSphereRadius;60float fraction1, fraction2;61switch (FindRoot(a, b, c, fraction1, fraction2))62{63case 0:64if (c <= 0.0f)65{66// Origin inside sphere67outMinFraction = outMaxFraction = 0.0f;68return 1;69}70else71{72// Origin outside of the sphere73return 0;74}75break;7677case 1:78// Ray is touching the sphere79outMinFraction = outMaxFraction = fraction1;80return 1;8182default:83// Ray enters and exits the sphere8485// Sort so that the smallest is first86if (fraction1 > fraction2)87std::swap(fraction1, fraction2);8889outMinFraction = fraction1;90outMaxFraction = fraction2;91return 2;92}93}9495JPH_NAMESPACE_END969798