Handle unsigned VECTOR2 casts

The previous overflow handling code casted the int_min value into an
unsigned, meaning that the min value and max value were almost the same,
clamping the output to unreasonable values.

Updated code handles floating points first, then does integer casting
through int64_t
This commit is contained in:
Seth Hillbrand 2024-06-10 12:37:27 -07:00
parent 1325701956
commit 9d9028c979
1 changed files with 38 additions and 13 deletions

View File

@ -87,13 +87,26 @@ public:
template <typename CastingType>
VECTOR2( const VECTOR2<CastingType>& aVec )
{
if( std::is_same<T, int>::value )
if( std::is_floating_point<T>() )
{
CastingType minI = static_cast<CastingType>( std::numeric_limits<int>::min() );
CastingType maxI = static_cast<CastingType>( std::numeric_limits<int>::max() );
x = static_cast<T>( aVec.x );
y = static_cast<T>( aVec.y );
}
else if( std::is_floating_point<CastingType>() )
{
CastingType minI = static_cast<CastingType>( std::numeric_limits<T>::min() );
CastingType maxI = static_cast<CastingType>( std::numeric_limits<T>::max() );
x = static_cast<int>( Clamp( minI, aVec.x, maxI ) );
y = static_cast<int>( Clamp( minI, aVec.y, maxI ) );
x = static_cast<T>( Clamp( minI, aVec.x, maxI ) );
y = static_cast<T>( Clamp( minI, aVec.y, maxI ) );
}
else if( std::is_integral<T>() && std::is_integral<CastingType>() )
{
int64_t minI = static_cast<int64_t>( std::numeric_limits<T>::min() );
int64_t maxI = static_cast<int64_t>( std::numeric_limits<T>::max() );
x = static_cast<T>( Clamp( minI, static_cast<int64_t>( aVec.x ), maxI ) );
y = static_cast<T>( Clamp( minI, static_cast<int64_t>(aVec.y), maxI ) );
}
else
{
@ -110,20 +123,32 @@ public:
}
/// Cast a vector to another specialized subclass. Beware of rounding issues.
template <typename CastedType>
VECTOR2<CastedType> operator()() const
template <typename U>
VECTOR2<U> operator()() const
{
if( std::is_same<CastedType, int>::value )
if( std::is_floating_point<U>::value )
{
T minI = static_cast<T>( std::numeric_limits<int>::min() );
T maxI = static_cast<T>( std::numeric_limits<int>::max() );
return VECTOR2<U>( static_cast<U>( x ), static_cast<U>( y ) );
}
else if( std::is_floating_point<T>() )
{
T minI = static_cast<T>( std::numeric_limits<U>::min() );
T maxI = static_cast<T>( std::numeric_limits<U>::max() );
return VECTOR2<U>( static_cast<U>( Clamp( minI, x, maxI ) ),
static_cast<U>( Clamp( minI, y, maxI ) ) );
}
else if( std::is_integral<T>() && std::is_integral<U>() )
{
int64_t minI = static_cast<int64_t>( std::numeric_limits<U>::min() );
int64_t maxI = static_cast<int64_t>( std::numeric_limits<U>::max() );
return VECTOR2<int>( static_cast<int>( Clamp( minI, x, maxI ) ),
static_cast<int>( Clamp( minI, y, maxI ) ) );
return VECTOR2<U>(
static_cast<U>( Clamp( minI, static_cast<int64_t>( x ), maxI ) ),
static_cast<U>( Clamp( minI, static_cast<int64_t>( y ), maxI ) ) );
}
else
{
return VECTOR2<CastedType>( static_cast<CastedType>( x ), static_cast<CastedType>( y ) );
return VECTOR2<U>( static_cast<U>( x ), static_cast<U>( y ) );
}
}