Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Collision/CastConvexVsTriangles.cpp
9912 views
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)1// SPDX-FileCopyrightText: 2021 Jorrit Rouwe2// SPDX-License-Identifier: MIT34#include <Jolt/Jolt.h>56#include <Jolt/Physics/Collision/CastConvexVsTriangles.h>7#include <Jolt/Physics/Collision/TransformedShape.h>8#include <Jolt/Physics/Collision/Shape/ScaleHelpers.h>9#include <Jolt/Physics/Collision/ActiveEdges.h>10#include <Jolt/Physics/Collision/NarrowPhaseStats.h>11#include <Jolt/Geometry/EPAPenetrationDepth.h>1213JPH_NAMESPACE_BEGIN1415CastConvexVsTriangles::CastConvexVsTriangles(const ShapeCast &inShapeCast, const ShapeCastSettings &inShapeCastSettings, Vec3Arg inScale, Mat44Arg inCenterOfMassTransform2, const SubShapeIDCreator &inSubShapeIDCreator1, CastShapeCollector &ioCollector) :16mShapeCast(inShapeCast),17mShapeCastSettings(inShapeCastSettings),18mCenterOfMassTransform2(inCenterOfMassTransform2),19mScale(inScale),20mSubShapeIDCreator1(inSubShapeIDCreator1),21mCollector(ioCollector)22{23JPH_ASSERT(inShapeCast.mShape->GetType() == EShapeType::Convex);2425// Determine if shape is inside out or not26mScaleSign = ScaleHelpers::IsInsideOut(inScale)? -1.0f : 1.0f;27}2829void CastConvexVsTriangles::Cast(Vec3Arg inV0, Vec3Arg inV1, Vec3Arg inV2, uint8 inActiveEdges, const SubShapeID &inSubShapeID2)30{31JPH_PROFILE_FUNCTION();3233// Scale triangle34Vec3 v0 = mScale * inV0;35Vec3 v1 = mScale * inV1;36Vec3 v2 = mScale * inV2;3738// Calculate triangle normal39Vec3 triangle_normal = mScaleSign * (v1 - v0).Cross(v2 - v0);4041// Backface check42bool back_facing = triangle_normal.Dot(mShapeCast.mDirection) > 0.0f;43if (mShapeCastSettings.mBackFaceModeTriangles == EBackFaceMode::IgnoreBackFaces && back_facing)44return;4546// Create triangle support function47TriangleConvexSupport triangle { v0, v1, v2 };4849// Check if we already created the cast shape support function50if (mSupport == nullptr)51{52// Determine if we want to use the actual shape or a shrunken shape with convex radius53ConvexShape::ESupportMode support_mode = mShapeCastSettings.mUseShrunkenShapeAndConvexRadius? ConvexShape::ESupportMode::ExcludeConvexRadius : ConvexShape::ESupportMode::Default;5455// Create support function56mSupport = static_cast<const ConvexShape *>(mShapeCast.mShape)->GetSupportFunction(support_mode, mSupportBuffer, mShapeCast.mScale);57}5859EPAPenetrationDepth epa;60float fraction = mCollector.GetEarlyOutFraction();61Vec3 contact_point_a, contact_point_b, contact_normal;62if (epa.CastShape(mShapeCast.mCenterOfMassStart, mShapeCast.mDirection, mShapeCastSettings.mCollisionTolerance, mShapeCastSettings.mPenetrationTolerance, *mSupport, triangle, mSupport->GetConvexRadius(), 0.0f, mShapeCastSettings.mReturnDeepestPoint, fraction, contact_point_a, contact_point_b, contact_normal))63{64// Check if we have enabled active edge detection65if (mShapeCastSettings.mActiveEdgeMode == EActiveEdgeMode::CollideOnlyWithActive && inActiveEdges != 0b111)66{67// Convert the active edge velocity hint to local space68Vec3 active_edge_movement_direction = mCenterOfMassTransform2.Multiply3x3Transposed(mShapeCastSettings.mActiveEdgeMovementDirection);6970// Update the contact normal to account for active edges71// Note that we flip the triangle normal as the penetration axis is pointing towards the triangle instead of away72contact_normal = ActiveEdges::FixNormal(v0, v1, v2, back_facing? triangle_normal : -triangle_normal, inActiveEdges, contact_point_b, contact_normal, active_edge_movement_direction);73}7475// Convert to world space76contact_point_a = mCenterOfMassTransform2 * contact_point_a;77contact_point_b = mCenterOfMassTransform2 * contact_point_b;78Vec3 contact_normal_world = mCenterOfMassTransform2.Multiply3x3(contact_normal);7980// Its a hit, store the sub shape id's81ShapeCastResult result(fraction, contact_point_a, contact_point_b, contact_normal_world, back_facing, mSubShapeIDCreator1.GetID(), inSubShapeID2, TransformedShape::sGetBodyID(mCollector.GetContext()));8283// Early out if this hit is deeper than the collector's early out value84if (fraction == 0.0f && -result.mPenetrationDepth >= mCollector.GetEarlyOutFraction())85return;8687// Gather faces88if (mShapeCastSettings.mCollectFacesMode == ECollectFacesMode::CollectFaces)89{90// Get supporting face of shape 191Mat44 transform_1_to_2 = mShapeCast.mCenterOfMassStart;92transform_1_to_2.SetTranslation(transform_1_to_2.GetTranslation() + fraction * mShapeCast.mDirection);93static_cast<const ConvexShape *>(mShapeCast.mShape)->GetSupportingFace(SubShapeID(), transform_1_to_2.Multiply3x3Transposed(-contact_normal), mShapeCast.mScale, mCenterOfMassTransform2 * transform_1_to_2, result.mShape1Face);9495// Get face of the triangle96triangle.GetSupportingFace(contact_normal, result.mShape2Face);9798// Convert to world space99for (Vec3 &p : result.mShape2Face)100p = mCenterOfMassTransform2 * p;101}102103JPH_IF_TRACK_NARROWPHASE_STATS(TrackNarrowPhaseCollector track;)104mCollector.AddHit(result);105}106}107108JPH_NAMESPACE_END109110111