From 67202959a00c92dd2eadfd5fb477cd5ffede8660 Mon Sep 17 00:00:00 2001 From: DaymareOn Date: Fri, 13 May 2022 07:19:26 +0200 Subject: [PATCH] fix: fix sorting algorithm - crashed the debug versions (#26) - Fixed: 2 equal values could return true (sorting algorithms require that 2 equal values return false). This caused a assertion error in debug builds and thus a crash. - Fixed: testing equality of floats with zero. - Simplified a test: knowing that dl > 0 and dr > 0, (cl * cr < 0) ? (cl > cr) : (dl * cr < dr * cl) is equivalent to: (dl * cr < dr * cl) --- hdtSMP64/ActorManager.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/hdtSMP64/ActorManager.cpp b/hdtSMP64/ActorManager.cpp index fb3d735..c7e6dd4 100644 --- a/hdtSMP64/ActorManager.cpp +++ b/hdtSMP64/ActorManager.cpp @@ -164,25 +164,22 @@ namespace hdt auto dl = a_lhs.m_distanceFromCamera2; return // If one of the skeletons is at distance zero (1st person player) from the camera - (dl * dr == 0) + (btFuzzyZero(dl) || btFuzzyZero(dr)) // then it is first. - ? (dl == 0) + ? (dl < dr) - // If one of the skeletons is exacly on the side of the camera (product of cos = 0) - : (cl * cr == 0) + // If one of the skeletons is exacly on the side of the camera (cos = 0) + : (btFuzzyZero(cl) || btFuzzyZero(cr)) // then it is last. - ? (cl != 0) + ? abs(cl) > abs(cr) - // If one of the skeletons is behind the camera and the other in front of the camera (product of cos < 0) - : (cl * cr < 0) - // then the one behind the camera is last (the one with cos(angle) < 0). - ? (cl > cr) - - // Finally, if both are on the same side of the camera (product of cos > 0): + // If both are on the same side of the camera (product of cos > 0): // we want first the smallest angle (so the highest cosinus), and the smallest distance, // so we want the smallest distance / cosinus. // cl = cosinus * distance, dl = distance² => distance / cosinus = dl/cl // So we want dl/cl < dr/cr. + // Moreover, this test manages the case where one of the skeletons is behind the camera and the other in front of the camera too; + // the one behind the camera is last (the one with cos(angle) = cr < 0). : (dl * cr < dr * cl); });