You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

94 lines
3.2 KiB

// David Eberly, Geometric Tools, Redmond WA 98052
// Copyright (c) 1998-2021
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
// https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
// Version: 4.0.2019.08.13
#pragma once
#include <Mathematics/DistPointOrientedBox.h>
#include <Mathematics/IntrAlignedBox3Sphere3.h>
namespace gte
{
template <typename Real>
class TIQuery<Real, OrientedBox3<Real>, Sphere3<Real>>
:
public TIQuery<Real, AlignedBox3<Real>, Sphere3<Real>>
{
public:
// The intersection query considers the box and sphere to be solids.
// For example, if the sphere is strictly inside the box (does not
// touch the box faces), the objects intersect.
struct Result
:
public TIQuery<Real, AlignedBox3<Real>, Sphere3<Real>>::Result
{
// No additional information to compute.
};
Result operator()(OrientedBox3<Real> const& box, Sphere3<Real> const& sphere)
{
DCPQuery<Real, Vector3<Real>, OrientedBox3<Real>> pbQuery;
auto pbResult = pbQuery(sphere.center, box);
Result result;
result.intersect = (pbResult.sqrDistance <= sphere.radius * sphere.radius);
return result;
}
};
template <typename Real>
class FIQuery<Real, OrientedBox3<Real>, Sphere3<Real>>
:
public FIQuery<Real, AlignedBox3<Real>, Sphere3<Real>>
{
public:
// Currently, only a dynamic query is supported. The static query
// must compute the intersection set of (solid) box and sphere.
struct Result
:
public FIQuery<Real, AlignedBox3<Real>, Sphere3<Real>>::Result
{
// No additional information to compute.
};
Result operator()(OrientedBox3<Real> const& box, Vector3<Real> const& boxVelocity,
Sphere3<Real> const& sphere, Vector3<Real> const& sphereVelocity)
{
Result result;
result.intersectionType = 0;
result.contactTime = (Real)0;
result.contactPoint = { (Real)0, (Real)0, (Real)0 };
// Transform the sphere and box so that the box center becomes
// the origin and the box is axis aligned. Compute the velocity
// of the sphere relative to the box.
Vector3<Real> temp = sphere.center - box.center;
Vector3<Real> C
{
Dot(temp, box.axis[0]),
Dot(temp, box.axis[1]),
Dot(temp, box.axis[2])
};
temp = sphereVelocity - boxVelocity;
Vector3<Real> V
{
Dot(temp, box.axis[0]),
Dot(temp, box.axis[1]),
Dot(temp, box.axis[2])
};
this->DoQuery(box.extent, C, sphere.radius, V, result);
// Transform back to the original coordinate system.
if (result.intersectionType != 0)
{
auto& P = result.contactPoint;
P = box.center + P[0] * box.axis[0] + P[1] * box.axis[1] + P[2] * box.axis[2];
}
return result;
}
};
}