From ec69aba0a9afcfe30d56a077a19bbf37305896f5 Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 29 Jan 2024 15:23:34 -0800 Subject: [PATCH] MathLib: added WrapToRange function --- Common/interface/BasicMath.hpp | 14 ++++++++ .../src/Common/MathLibTest.cpp | 34 ++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/Common/interface/BasicMath.hpp b/Common/interface/BasicMath.hpp index 736c65f13..8e5125409 100644 --- a/Common/interface/BasicMath.hpp +++ b/Common/interface/BasicMath.hpp @@ -2668,6 +2668,20 @@ typename std::enable_if::value, T>::type ExtractLSB(T& bits) return static_cast(ExtractLSB(reinterpret_cast::type&>(bits))); } +/// Wraps Value to the range [Min, Min + Range) +template +T WrapToRange(T Value, T Min, T Range) +{ + VERIFY_EXPR(Range >= 0); + if (Range <= 0) + return Min; + + T Result = (Value - Min) % Range; + if (Result < 0) + Result += Range; + + return Result + Min; +} inline std::ostream& operator<<(std::ostream& os, const float4& vec) { diff --git a/Tests/DiligentCoreTest/src/Common/MathLibTest.cpp b/Tests/DiligentCoreTest/src/Common/MathLibTest.cpp index c135b8731..8397a4b7b 100644 --- a/Tests/DiligentCoreTest/src/Common/MathLibTest.cpp +++ b/Tests/DiligentCoreTest/src/Common/MathLibTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 Diligent Graphics LLC + * Copyright 2019-2024 Diligent Graphics LLC * Copyright 2015-2019 Egor Yusov * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -2292,6 +2292,38 @@ TEST(Common_BasicMath, VectorAll) EXPECT_FALSE(all(double4{1, 1, 1, 0})); } + +TEST(Common_BasicMath, Wrap) +{ + EXPECT_EQ(WrapToRange(10, 1, 0), 1); + EXPECT_EQ(WrapToRange(10, 1, 1), 1); + EXPECT_EQ(WrapToRange(-10, 1, 0), 1); + EXPECT_EQ(WrapToRange(-10, 1, 1), 1); + + EXPECT_EQ(WrapToRange(0, 200, 10), 200); + EXPECT_EQ(WrapToRange(1, 200, 10), 201); + EXPECT_EQ(WrapToRange(9, 200, 10), 209); + EXPECT_EQ(WrapToRange(10, 200, 10), 200); + + EXPECT_EQ(WrapToRange(-1, 200, 10), 209); + EXPECT_EQ(WrapToRange(-9, 200, 10), 201); + EXPECT_EQ(WrapToRange(-10, 200, 10), 200); + + for (int Range : {1, 2, 7, 8, 9, 10, 15, 16, 17}) + { + int Min = -Range / 2; + for (int i = -2; i <= 2; ++i) + { + for (int Ref = Min; Ref < Min + Range; ++Ref) + { + int Value = i * Range + Ref; + EXPECT_EQ(WrapToRange(Value, Min, Range), Ref) << Value << " " << Min << " " << Range; + } + } + } +} + + TEST(Common_AdvancedMath, IsPointInsideTriangleF) { {