Path: blob/master/thirdparty/jolt_physics/Jolt/Physics/Collision/CollisionCollectorImpl.h
9912 views
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)1// SPDX-FileCopyrightText: 2021 Jorrit Rouwe2// SPDX-License-Identifier: MIT34#pragma once56#include <Jolt/Physics/Collision/CollisionCollector.h>7#include <Jolt/Core/QuickSort.h>89JPH_NAMESPACE_BEGIN1011/// Simple implementation that collects all hits and optionally sorts them on distance12template <class CollectorType>13class AllHitCollisionCollector : public CollectorType14{15public:16/// Redeclare ResultType17using ResultType = typename CollectorType::ResultType;1819// See: CollectorType::Reset20virtual void Reset() override21{22CollectorType::Reset();2324mHits.clear();25}2627// See: CollectorType::AddHit28virtual void AddHit(const ResultType &inResult) override29{30mHits.push_back(inResult);31}3233/// Order hits on closest first34void Sort()35{36QuickSort(mHits.begin(), mHits.end(), [](const ResultType &inLHS, const ResultType &inRHS) { return inLHS.GetEarlyOutFraction() < inRHS.GetEarlyOutFraction(); });37}3839/// Check if any hits were collected40inline bool HadHit() const41{42return !mHits.empty();43}4445Array<ResultType> mHits;46};4748/// Simple implementation that collects the closest / deepest hit49template <class CollectorType>50class ClosestHitCollisionCollector : public CollectorType51{52public:53/// Redeclare ResultType54using ResultType = typename CollectorType::ResultType;5556// See: CollectorType::Reset57virtual void Reset() override58{59CollectorType::Reset();6061mHadHit = false;62}6364// See: CollectorType::AddHit65virtual void AddHit(const ResultType &inResult) override66{67float early_out = inResult.GetEarlyOutFraction();68if (!mHadHit || early_out < mHit.GetEarlyOutFraction())69{70// Update early out fraction71CollectorType::UpdateEarlyOutFraction(early_out);7273// Store hit74mHit = inResult;75mHadHit = true;76}77}7879/// Check if this collector has had a hit80inline bool HadHit() const81{82return mHadHit;83}8485ResultType mHit;8687private:88bool mHadHit = false;89};9091/// Implementation that collects the closest / deepest hit for each body and optionally sorts them on distance92template <class CollectorType>93class ClosestHitPerBodyCollisionCollector : public CollectorType94{95public:96/// Redeclare ResultType97using ResultType = typename CollectorType::ResultType;9899// See: CollectorType::Reset100virtual void Reset() override101{102CollectorType::Reset();103104mHits.clear();105mHadHit = false;106}107108// See: CollectorType::OnBody109virtual void OnBody(const Body &inBody) override110{111// Store the early out fraction so we can restore it after we've collected all hits for this body112mPreviousEarlyOutFraction = CollectorType::GetEarlyOutFraction();113}114115// See: CollectorType::AddHit116virtual void AddHit(const ResultType &inResult) override117{118float early_out = inResult.GetEarlyOutFraction();119if (!mHadHit || early_out < CollectorType::GetEarlyOutFraction())120{121// Update early out fraction to avoid spending work on collecting further hits for this body122CollectorType::UpdateEarlyOutFraction(early_out);123124if (!mHadHit)125{126// First time we have a hit we append it to the array127mHits.push_back(inResult);128mHadHit = true;129}130else131{132// Closer hits will override the previous one133mHits.back() = inResult;134}135}136}137138// See: CollectorType::OnBodyEnd139virtual void OnBodyEnd() override140{141if (mHadHit)142{143// Reset the early out fraction to the configured value so that we will continue144// to collect hits at any distance for other bodies145JPH_ASSERT(mPreviousEarlyOutFraction != -FLT_MAX); // Check that we got a call to OnBody146CollectorType::ResetEarlyOutFraction(mPreviousEarlyOutFraction);147mHadHit = false;148}149150// For asserting purposes we reset the stored early out fraction so we can detect that OnBody was called151JPH_IF_ENABLE_ASSERTS(mPreviousEarlyOutFraction = -FLT_MAX;)152}153154/// Order hits on closest first155void Sort()156{157QuickSort(mHits.begin(), mHits.end(), [](const ResultType &inLHS, const ResultType &inRHS) { return inLHS.GetEarlyOutFraction() < inRHS.GetEarlyOutFraction(); });158}159160/// Check if any hits were collected161inline bool HadHit() const162{163return !mHits.empty();164}165166Array<ResultType> mHits;167168private:169// Store early out fraction that was initially configured for the collector170float mPreviousEarlyOutFraction = -FLT_MAX;171172// Flag to indicate if we have a hit for the current body173bool mHadHit = false;174};175176/// Simple implementation that collects any hit177template <class CollectorType>178class AnyHitCollisionCollector : public CollectorType179{180public:181/// Redeclare ResultType182using ResultType = typename CollectorType::ResultType;183184// See: CollectorType::Reset185virtual void Reset() override186{187CollectorType::Reset();188189mHadHit = false;190}191192// See: CollectorType::AddHit193virtual void AddHit(const ResultType &inResult) override194{195// Test that the collector is not collecting more hits after forcing an early out196JPH_ASSERT(!mHadHit);197198// Abort any further testing199CollectorType::ForceEarlyOut();200201// Store hit202mHit = inResult;203mHadHit = true;204}205206/// Check if this collector has had a hit207inline bool HadHit() const208{209return mHadHit;210}211212ResultType mHit;213214private:215bool mHadHit = false;216};217218JPH_NAMESPACE_END219220221