AddDenseVector3i
This commit is contained in:
153
openVulkanoCpp/Math/DenseVector3i.hpp
Normal file
153
openVulkanoCpp/Math/DenseVector3i.hpp
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Math.hpp"
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace openVulkanoCpp::Math
|
||||
{
|
||||
/**
|
||||
* A templated vector implementation that allows for a lower resolution of the y axis.
|
||||
*
|
||||
* @tparam T backing datatype
|
||||
* @tparam REDUCE_Y_RESOLUTION if the y resolution should be reduced
|
||||
* @tparam ASSERT_INPUT_VALUES if input values should be validated before they are used
|
||||
* @tparam BITS_PER_COMPONENT how many bits each component should use. -1 for automatic sizing
|
||||
*/
|
||||
template<typename T = int64_t,
|
||||
bool REDUCE_Y_RESOLUTION = false,
|
||||
bool ASSERT_INPUT_VALUES = false,
|
||||
int BITS_PER_COMPONENT = -1,
|
||||
typename = std::enable_if_t<std::is_signed_v<T> && std::is_integral_v<T>>>
|
||||
class DenseVector3i
|
||||
{
|
||||
typedef DenseVector3i<T, REDUCE_Y_RESOLUTION, ASSERT_INPUT_VALUES, BITS_PER_COMPONENT> DenseVec3;
|
||||
|
||||
static constexpr int GetBitCount()
|
||||
{
|
||||
if (BITS_PER_COMPONENT > 0) return BITS_PER_COMPONENT;
|
||||
if constexpr (std::is_same_v<T, int8_t>)
|
||||
{
|
||||
return REDUCE_Y_RESOLUTION ? 3 : 2;
|
||||
}
|
||||
if constexpr (std::is_same_v<T, int16_t>)
|
||||
{
|
||||
return REDUCE_Y_RESOLUTION ? 6 : 5;
|
||||
}
|
||||
if constexpr (std::is_same_v<T, int32_t>)
|
||||
{
|
||||
return REDUCE_Y_RESOLUTION ? 11 : 10;
|
||||
}
|
||||
return REDUCE_Y_RESOLUTION ? 22 : 21;
|
||||
}
|
||||
|
||||
static constexpr int GetBitCountY()
|
||||
{
|
||||
if (BITS_PER_COMPONENT > 0) return BITS_PER_COMPONENT;
|
||||
if (!REDUCE_Y_RESOLUTION) return GetBitCount();
|
||||
return sizeof(T) * 8 - GetBitCount() * 2;
|
||||
}
|
||||
|
||||
static constexpr int BITS = GetBitCount();
|
||||
static constexpr int BITS_Y = GetBitCountY();
|
||||
static constexpr T BITMASK = (1 << BITS) - 1;
|
||||
static constexpr int MAX_VALUE = (1 << (BITS - 1)) - 1;
|
||||
static constexpr int MAX_VALUE_Y = (1 << (BITS_Y - 1)) - 1;
|
||||
static constexpr int MIN_VALUE = -MAX_VALUE - 1;
|
||||
static constexpr int MIN_VALUE_Y = -MAX_VALUE_Y - 1;
|
||||
|
||||
static constexpr void AssertValue(int value, int maxValue = MAX_VALUE, int minValue = MIN_VALUE)
|
||||
{
|
||||
if (!ASSERT_INPUT_VALUES) return;
|
||||
if (value > maxValue || value < minValue)
|
||||
throw std::range_error("Value to big for DenseVector");
|
||||
}
|
||||
|
||||
T data;
|
||||
|
||||
public:
|
||||
constexpr explicit DenseVector3i(const Math::Vector3i& vec3) : DenseVector3i(vec3.x, vec3.y, vec3.z) {}
|
||||
constexpr explicit DenseVector3i(const Math::Vector3i_SIMD& vec3) : DenseVector3i(vec3.x, vec3.y, vec3.z) {}
|
||||
constexpr DenseVector3i(int x, int y, int z)
|
||||
: data((x & BITMASK) | ((y & BITMASK) << (2 * BITS)) | ((z & BITMASK) << BITS))
|
||||
{
|
||||
AssertValue(x);
|
||||
AssertValue(y, MAX_VALUE_Y, MIN_VALUE_Y);
|
||||
AssertValue(z);
|
||||
}
|
||||
|
||||
constexpr T Data() const { return data; }
|
||||
|
||||
[[nodiscard]] constexpr int X() const { return static_cast<int>(data & BITMASK); }
|
||||
[[nodiscard]] constexpr int Y() const { return static_cast<int>((data >> (2 * BITS)) & BITMASK); }
|
||||
[[nodiscard]] constexpr int Z() const { return static_cast<int>((data >> BITS) & BITMASK); }
|
||||
|
||||
void SetX(int x)
|
||||
{
|
||||
AssertValue(x);
|
||||
data = (data & !BITMASK) | (x & BITMASK);
|
||||
}
|
||||
|
||||
void SetY(int y)
|
||||
{
|
||||
AssertValue(y, MAX_VALUE_Y, MIN_VALUE_Y);
|
||||
data = (data & !(BITMASK << (2 * BITS))) | ((y & BITMASK) << (2 * BITS));
|
||||
}
|
||||
|
||||
void SetZ(int z)
|
||||
{
|
||||
AssertValue(z);
|
||||
data = (data & !(BITMASK << BITS)) | ((z & BITMASK) << BITS);
|
||||
}
|
||||
|
||||
constexpr operator T() const { return data; }
|
||||
|
||||
constexpr bool operator <(DenseVec3 rhs) const
|
||||
{
|
||||
return data < rhs.data;
|
||||
}
|
||||
|
||||
bool operator>(DenseVec3 rhs) const
|
||||
{
|
||||
return rhs < *this;
|
||||
}
|
||||
|
||||
bool operator>=(DenseVec3 rhs) const
|
||||
{
|
||||
return !(*this < rhs);
|
||||
}
|
||||
|
||||
bool operator<=(DenseVec3 rhs) const
|
||||
{
|
||||
return !(rhs < *this);
|
||||
}
|
||||
|
||||
constexpr bool operator ==(DenseVec3 rhs)
|
||||
{
|
||||
return data == rhs.data;
|
||||
}
|
||||
|
||||
constexpr bool operator !=(DenseVec3 rhs)
|
||||
{
|
||||
return data == rhs.data;
|
||||
}
|
||||
|
||||
explicit constexpr operator Math::Vector3i()
|
||||
{
|
||||
return { X(), Y(), Z() };
|
||||
}
|
||||
|
||||
explicit constexpr operator Math::Vector3i_SIMD()
|
||||
{
|
||||
return { X(), Y(), Z() };
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user