Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Collision/CollideSoftBodyVerticesVsTriangles.h
9912 views
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)1// SPDX-FileCopyrightText: 2024 Jorrit Rouwe2// SPDX-License-Identifier: MIT34#pragma once56#include <Jolt/Physics/Collision/CollideSoftBodyVertexIterator.h>7#include <Jolt/Geometry/ClosestPoint.h>89JPH_NAMESPACE_BEGIN1011/// Collision detection helper that collides soft body vertices vs triangles12class JPH_EXPORT CollideSoftBodyVerticesVsTriangles13{14public:15CollideSoftBodyVerticesVsTriangles(Mat44Arg inCenterOfMassTransform, Vec3Arg inScale) :16mTransform(inCenterOfMassTransform * Mat44::sScale(inScale)),17mInvTransform(mTransform.Inversed()),18mNormalSign(ScaleHelpers::IsInsideOut(inScale)? -1.0f : 1.0f)19{20}2122JPH_INLINE void StartVertex(const CollideSoftBodyVertexIterator &inVertex)23{24mLocalPosition = mInvTransform * inVertex.GetPosition();25mClosestDistanceSq = FLT_MAX;26}2728JPH_INLINE void ProcessTriangle(Vec3Arg inV0, Vec3Arg inV1, Vec3Arg inV2)29{30// Get the closest point from the vertex to the triangle31uint32 set;32Vec3 closest_point = ClosestPoint::GetClosestPointOnTriangle(inV0 - mLocalPosition, inV1 - mLocalPosition, inV2 - mLocalPosition, set);33float dist_sq = closest_point.LengthSq();34if (dist_sq < mClosestDistanceSq)35{36mV0 = inV0;37mV1 = inV1;38mV2 = inV2;39mClosestPoint = closest_point;40mClosestDistanceSq = dist_sq;41mSet = set;42}43}4445JPH_INLINE void FinishVertex(const CollideSoftBodyVertexIterator &ioVertex, int inCollidingShapeIndex) const46{47if (mClosestDistanceSq < FLT_MAX)48{49// Convert triangle to world space50Vec3 v0 = mTransform * mV0;51Vec3 v1 = mTransform * mV1;52Vec3 v2 = mTransform * mV2;53Vec3 triangle_normal = mNormalSign * (v1 - v0).Cross(v2 - v0).NormalizedOr(Vec3::sAxisY());5455if (mSet == 0b111)56{57// Closest is interior to the triangle, use plane as collision plane but don't allow more than 0.1 m penetration58// because otherwise a triangle half a level a way will have a huge penetration if it is back facing59float penetration = min(triangle_normal.Dot(v0 - ioVertex.GetPosition()), 0.1f);60if (ioVertex.UpdatePenetration(penetration))61ioVertex.SetCollision(Plane::sFromPointAndNormal(v0, triangle_normal), inCollidingShapeIndex);62}63else64{65// Closest point is on an edge or vertex, use closest point as collision plane66Vec3 closest_point = mTransform * (mLocalPosition + mClosestPoint);67Vec3 normal = ioVertex.GetPosition() - closest_point;68if (normal.Dot(triangle_normal) > 0.0f) // Ignore back facing edges69{70float normal_length = normal.Length();71float penetration = -normal_length;72if (ioVertex.UpdatePenetration(penetration))73ioVertex.SetCollision(Plane::sFromPointAndNormal(closest_point, normal_length > 0.0f? normal / normal_length : triangle_normal), inCollidingShapeIndex);74}75}76}77}7879Mat44 mTransform;80Mat44 mInvTransform;81Vec3 mLocalPosition;82Vec3 mV0, mV1, mV2;83Vec3 mClosestPoint;84float mNormalSign;85float mClosestDistanceSq;86uint32 mSet;87};8889JPH_NAMESPACE_END909192