107 lines
5.1 KiB
C++
107 lines
5.1 KiB
C++
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
|
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#pragma once
|
|
|
|
#include <Jolt/Core/StaticArray.h>
|
|
#include <Jolt/Physics/Collision/BackFaceMode.h>
|
|
#include <Jolt/Physics/Collision/ActiveEdgeMode.h>
|
|
#include <Jolt/Physics/Collision/CollectFacesMode.h>
|
|
#include <Jolt/Physics/Collision/Shape/SubShapeID.h>
|
|
#include <Jolt/Physics/Body/BodyID.h>
|
|
#include <Jolt/Physics/PhysicsSettings.h>
|
|
|
|
JPH_NAMESPACE_BEGIN
|
|
|
|
/// Class that contains all information of two colliding shapes
|
|
class CollideShapeResult
|
|
{
|
|
public:
|
|
JPH_OVERRIDE_NEW_DELETE
|
|
|
|
/// Default constructor
|
|
CollideShapeResult() = default;
|
|
|
|
/// Constructor
|
|
CollideShapeResult(Vec3Arg inContactPointOn1, Vec3Arg inContactPointOn2, Vec3Arg inPenetrationAxis, float inPenetrationDepth, const SubShapeID &inSubShapeID1, const SubShapeID &inSubShapeID2, const BodyID &inBodyID2) :
|
|
mContactPointOn1(inContactPointOn1),
|
|
mContactPointOn2(inContactPointOn2),
|
|
mPenetrationAxis(inPenetrationAxis),
|
|
mPenetrationDepth(inPenetrationDepth),
|
|
mSubShapeID1(inSubShapeID1),
|
|
mSubShapeID2(inSubShapeID2),
|
|
mBodyID2(inBodyID2)
|
|
{
|
|
}
|
|
|
|
/// Function required by the CollisionCollector. A smaller fraction is considered to be a 'better hit'. We use -penetration depth to get the hit with the biggest penetration depth
|
|
inline float GetEarlyOutFraction() const { return -mPenetrationDepth; }
|
|
|
|
/// Reverses the hit result, swapping contact point 1 with contact point 2 etc.
|
|
inline CollideShapeResult Reversed() const
|
|
{
|
|
CollideShapeResult result;
|
|
result.mContactPointOn2 = mContactPointOn1;
|
|
result.mContactPointOn1 = mContactPointOn2;
|
|
result.mPenetrationAxis = -mPenetrationAxis;
|
|
result.mPenetrationDepth = mPenetrationDepth;
|
|
result.mSubShapeID2 = mSubShapeID1;
|
|
result.mSubShapeID1 = mSubShapeID2;
|
|
result.mBodyID2 = mBodyID2;
|
|
result.mShape2Face = mShape1Face;
|
|
result.mShape1Face = mShape2Face;
|
|
return result;
|
|
}
|
|
|
|
using Face = StaticArray<Vec3, 32>;
|
|
|
|
Vec3 mContactPointOn1; ///< Contact point on the surface of shape 1 (in world space or relative to base offset)
|
|
Vec3 mContactPointOn2; ///< Contact point on the surface of shape 2 (in world space or relative to base offset). If the penetration depth is 0, this will be the same as mContactPointOn1.
|
|
Vec3 mPenetrationAxis; ///< Direction to move shape 2 out of collision along the shortest path (magnitude is meaningless, in world space). You can use -mPenetrationAxis.Normalized() as contact normal.
|
|
float mPenetrationDepth; ///< Penetration depth (move shape 2 by this distance to resolve the collision). If CollideShapeSettings::mMaxSeparationDistance > 0 this number can be negative to indicate that the objects are separated by -mPenetrationDepth. The contact points are the closest points in that case.
|
|
SubShapeID mSubShapeID1; ///< Sub shape ID that identifies the face on shape 1
|
|
SubShapeID mSubShapeID2; ///< Sub shape ID that identifies the face on shape 2
|
|
BodyID mBodyID2; ///< BodyID to which shape 2 belongs to
|
|
Face mShape1Face; ///< Colliding face on shape 1 (optional result, in world space or relative to base offset)
|
|
Face mShape2Face; ///< Colliding face on shape 2 (optional result, in world space or relative to base offset)
|
|
};
|
|
|
|
/// Settings to be passed with a collision query
|
|
class CollideSettingsBase
|
|
{
|
|
public:
|
|
JPH_OVERRIDE_NEW_DELETE
|
|
|
|
/// How active edges (edges that a moving object should bump into) are handled
|
|
EActiveEdgeMode mActiveEdgeMode = EActiveEdgeMode::CollideOnlyWithActive;
|
|
|
|
/// If colliding faces should be collected or only the collision point
|
|
ECollectFacesMode mCollectFacesMode = ECollectFacesMode::NoFaces;
|
|
|
|
/// If objects are closer than this distance, they are considered to be colliding (used for GJK) (unit: meter)
|
|
float mCollisionTolerance = cDefaultCollisionTolerance;
|
|
|
|
/// A factor that determines the accuracy of the penetration depth calculation. If the change of the squared distance is less than tolerance * current_penetration_depth^2 the algorithm will terminate. (unit: dimensionless)
|
|
float mPenetrationTolerance = cDefaultPenetrationTolerance;
|
|
|
|
/// When mActiveEdgeMode is CollideOnlyWithActive a movement direction can be provided. When hitting an inactive edge, the system will select the triangle normal as penetration depth only if it impedes the movement less than with the calculated penetration depth.
|
|
Vec3 mActiveEdgeMovementDirection = Vec3::sZero();
|
|
};
|
|
|
|
/// Settings to be passed with a collision query
|
|
class CollideShapeSettings : public CollideSettingsBase
|
|
{
|
|
public:
|
|
JPH_OVERRIDE_NEW_DELETE
|
|
|
|
/// When > 0 contacts in the vicinity of the query shape can be found. All nearest contacts that are not further away than this distance will be found.
|
|
/// Note that in this case CollideShapeResult::mPenetrationDepth can become negative to indicate that objects are not overlapping. (unit: meter)
|
|
float mMaxSeparationDistance = 0.0f;
|
|
|
|
/// How backfacing triangles should be treated
|
|
EBackFaceMode mBackFaceMode = EBackFaceMode::IgnoreBackFaces;
|
|
};
|
|
|
|
JPH_NAMESPACE_END
|