@@ -377,16 +377,50 @@ bool BulletCollisionDetector::raycast(
377377 const auto btFrom = convertVector3 (from);
378378 const auto btTo = convertVector3 (to);
379379
380- if (option.mEnableAllHits ) {
380+ const bool needsAllHits
381+ = option.mEnableAllHits || static_cast <bool >(option.mFilter );
382+
383+ if (needsAllHits) {
384+ auto lessFraction = [](const RayHit& a, const RayHit& b) {
385+ return a.mFraction < b.mFraction ;
386+ };
387+
381388 auto callback = btCollisionWorld::AllHitsRayResultCallback (btFrom, btTo);
382389 castedGroup->updateEngineData ();
383390 collisionWorld->rayTest (btFrom, btTo, callback);
384391
385- if (result == nullptr )
386- return callback.hasHit ();
392+ if (result == nullptr ) {
393+ if (!callback.hasHit ())
394+ return false ;
395+
396+ if (!option.mFilter )
397+ return true ;
398+
399+ for (int i = 0 ; i < callback.m_collisionObjects .size (); ++i) {
400+ const auto * collObj = static_cast <BulletCollisionObject*>(
401+ callback.m_collisionObjects [i]->getUserPointer ());
402+ if (option.passesFilter (collObj))
403+ return true ;
404+ }
405+
406+ return false ;
407+ }
387408
388409 if (callback.hasHit ()) {
389410 reportRayHits (callback, option, *result);
411+
412+ if (!option.mEnableAllHits && !result->mRayHits .empty ()) {
413+ if (option.mSortByClosest ) {
414+ result->mRayHits .resize (1 );
415+ } else {
416+ const auto closest = std::min_element (
417+ result->mRayHits .begin (), result->mRayHits .end (), lessFraction);
418+ const RayHit closestHit = *closest;
419+ result->mRayHits .clear ();
420+ result->mRayHits .emplace_back (closestHit);
421+ }
422+ }
423+
390424 return result->hasHit ();
391425 } else {
392426 return false ;
@@ -765,7 +799,7 @@ RayHit convertRayHit(
765799// ==============================================================================
766800void reportRayHits (
767801 const btCollisionWorld::ClosestRayResultCallback callback,
768- const RaycastOption& /* option*/ ,
802+ const RaycastOption& option,
769803 RaycastResult& result)
770804{
771805 // This function shouldn't be called if callback has not ray hit.
@@ -779,7 +813,9 @@ void reportRayHits(
779813
780814 result.mRayHits .clear ();
781815 result.mRayHits .reserve (1 );
782- result.mRayHits .emplace_back (rayHit);
816+
817+ if (option.passesFilter (rayHit.mCollisionObject ))
818+ result.mRayHits .emplace_back (rayHit);
783819}
784820
785821// ==============================================================================
@@ -807,7 +843,8 @@ void reportRayHits(
807843 callback.m_hitPointWorld [i],
808844 callback.m_hitNormalWorld [i],
809845 callback.m_hitFractions [i]);
810- result.mRayHits .emplace_back (rayHit);
846+ if (option.passesFilter (rayHit.mCollisionObject ))
847+ result.mRayHits .emplace_back (rayHit);
811848 }
812849
813850 if (option.mSortByClosest )
0 commit comments