init
This commit is contained in:
9
TempleWare-CS2/source/templeware/utils/math/math.h
Normal file
9
TempleWare-CS2/source/templeware/utils/math/math.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include <algorithm>
|
||||
|
||||
namespace Math {
|
||||
template <typename T>
|
||||
T clamp(T value, T min, T max) {
|
||||
return std::min(std::max(value, min), max);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,622 @@
|
||||
#pragma once
|
||||
#include <cstddef>
|
||||
#define debug(EXPRESSION) static_cast<void>(0)
|
||||
|
||||
#pragma warning (disable:4100)
|
||||
#pragma warning (disable:4514)
|
||||
|
||||
template <class T>
|
||||
inline void V_swap(T& x, T& y)
|
||||
{
|
||||
T temp = x;
|
||||
x = y;
|
||||
y = temp;
|
||||
}
|
||||
|
||||
template <class T, class N = size_t>
|
||||
class CUtlMemory
|
||||
{
|
||||
enum
|
||||
{
|
||||
EXTERNAL_BUFFER_MARKER = -1,
|
||||
EXTERNAL_CONST_BUFFER_MARKER = -2,
|
||||
};
|
||||
|
||||
public:
|
||||
class Iterator_t
|
||||
{
|
||||
public:
|
||||
Iterator_t(const N nIndex) :
|
||||
nIndex(nIndex) { }
|
||||
|
||||
bool operator==(const Iterator_t it) const
|
||||
{
|
||||
return nIndex == it.nIndex;
|
||||
}
|
||||
|
||||
bool operator!=(const Iterator_t it) const
|
||||
{
|
||||
return nIndex != it.nIndex;
|
||||
}
|
||||
|
||||
N nIndex;
|
||||
};
|
||||
|
||||
|
||||
CUtlMemory() :
|
||||
pMemory(nullptr), nAllocationCount(0), nGrowSize(0) { }
|
||||
|
||||
CUtlMemory& operator=(const CUtlMemory& rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
{
|
||||
|
||||
pMemory = rhs.pMemory;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
CUtlMemory(const int nInitialGrowSize, const int nAllocationCount) :
|
||||
pMemory(nullptr), nAllocationCount(nAllocationCount), nGrowSize(nInitialGrowSize)
|
||||
{
|
||||
|
||||
if (nAllocationCount > 0)
|
||||
pMemory = static_cast<T*>(alloca(nAllocationCount * sizeof(T)));
|
||||
}
|
||||
|
||||
CUtlMemory(T* pMemory, const int nElements) :
|
||||
pMemory(pMemory), nAllocationCount(nElements), nGrowSize(EXTERNAL_BUFFER_MARKER) { }
|
||||
|
||||
CUtlMemory(T* pMemory, const void* pElements, size_t size) :
|
||||
pMemory(pMemory), nAllocationCount(static_cast<N>(pElements / sizeof(T))), nGrowSize(size)
|
||||
{
|
||||
if (pElements != nullptr)
|
||||
{
|
||||
memcpy(pMemory, pElements, size);
|
||||
}
|
||||
}
|
||||
|
||||
~CUtlMemory()
|
||||
{
|
||||
Purge();
|
||||
}
|
||||
template<class T, class N>
|
||||
inline CUtlMemory(CUtlMemory&& moveFrom)
|
||||
{
|
||||
moveFrom.pMemory = nullptr;
|
||||
moveFrom.nAllocationCount = 0;
|
||||
moveFrom.nGrowSize = 0;
|
||||
}
|
||||
|
||||
template<class T, class N>
|
||||
inline CUtlMemory& operator=(CUtlMemory&& moveFrom)
|
||||
{
|
||||
T* pMemoryTemp = moveFrom.pMemory;
|
||||
const int nAllocationCountTemp = moveFrom.nAllocationCount;
|
||||
const int nGrowSizeTemp = moveFrom.nGrowSize;
|
||||
|
||||
moveFrom.pMemory = nullptr;
|
||||
moveFrom.nAllocationCount = 0;
|
||||
moveFrom.nGrowSize = 0;
|
||||
|
||||
Purge();
|
||||
|
||||
pMemory = pMemoryTemp;
|
||||
nAllocationCount = nAllocationCountTemp;
|
||||
nGrowSize = nGrowSizeTemp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] T& operator[](const N nIndex)
|
||||
{
|
||||
return pMemory[nIndex];
|
||||
}
|
||||
|
||||
[[nodiscard]] const T& operator[](const N nIndex) const
|
||||
{
|
||||
return pMemory[nIndex];
|
||||
}
|
||||
|
||||
[[nodiscard]] T& Element(const N nIndex)
|
||||
{
|
||||
return pMemory[nIndex];
|
||||
}
|
||||
|
||||
[[nodiscard]] const T& Element(const N nIndex) const
|
||||
{
|
||||
return pMemory[nIndex];
|
||||
}
|
||||
|
||||
[[nodiscard]] T* Base()
|
||||
{
|
||||
return pMemory;
|
||||
}
|
||||
|
||||
[[nodiscard]] const T* Base() const
|
||||
{
|
||||
return pMemory;
|
||||
}
|
||||
|
||||
[[nodiscard]] int AllocationCount() const
|
||||
{
|
||||
return nAllocationCount;
|
||||
}
|
||||
int AllocationNum() const
|
||||
{
|
||||
return nAllocationCount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
[[nodiscard]] bool IsExternallyAllocated() const
|
||||
{
|
||||
return nGrowSize <= EXTERNAL_BUFFER_MARKER;
|
||||
}
|
||||
|
||||
[[nodiscard]] static N InvalidIndex()
|
||||
{
|
||||
return static_cast<N>(-1);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsValidIndex(N nIndex) const
|
||||
{
|
||||
return (nIndex >= 0) && (nIndex < nAllocationCount);
|
||||
}
|
||||
|
||||
[[nodiscard]] Iterator_t First() const
|
||||
{
|
||||
return Iterator_t(IsValidIndex(0) ? 0 : InvalidIndex());
|
||||
}
|
||||
|
||||
[[nodiscard]] Iterator_t Next(const Iterator_t& it) const
|
||||
{
|
||||
return Iterator_t(IsValidIndex(it.nIndex + 1) ? it.nIndex + 1 : InvalidIndex());
|
||||
}
|
||||
|
||||
|
||||
[[nodiscard]] N GetIndex(const Iterator_t& it) const
|
||||
{
|
||||
return it.nIndex;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsIndexAfter(N nIndex, const Iterator_t& it) const
|
||||
{
|
||||
return nIndex > it.nIndex;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsValidIterator(const Iterator_t& it) const
|
||||
{
|
||||
return IsValidIndex(it.index);
|
||||
}
|
||||
|
||||
[[nodiscard]] Iterator_t InvalidIterator() const
|
||||
{
|
||||
return Iterator_t(InvalidIndex());
|
||||
}
|
||||
|
||||
void Grow(const int nCount = 1)
|
||||
{
|
||||
if (IsExternallyAllocated())
|
||||
return;
|
||||
|
||||
int nAllocationRequested = nAllocationCount + nCount;
|
||||
int nNewAllocationCount = 0;
|
||||
|
||||
if (nGrowSize)
|
||||
nAllocationCount = ((1 + ((nAllocationRequested - 1) / nGrowSize)) * nGrowSize);
|
||||
else
|
||||
{
|
||||
if (nAllocationCount == 0)
|
||||
nAllocationCount = (31 + sizeof(T)) / sizeof(T);
|
||||
|
||||
while (nAllocationCount < nAllocationRequested)
|
||||
nAllocationCount <<= 1;
|
||||
}
|
||||
|
||||
if (static_cast<int>(static_cast<N>(nNewAllocationCount)) < nAllocationRequested)
|
||||
{
|
||||
if (static_cast<int>(static_cast<N>(nNewAllocationCount)) == 0 && static_cast<int>(static_cast<N>(nNewAllocationCount - 1)) >= nAllocationRequested)
|
||||
--nNewAllocationCount;
|
||||
else
|
||||
{
|
||||
if (static_cast<int>(static_cast<N>(nAllocationRequested)) != nAllocationRequested)
|
||||
return;
|
||||
|
||||
while (static_cast<int>(static_cast<N>(nNewAllocationCount)) < nAllocationRequested)
|
||||
nNewAllocationCount = (nNewAllocationCount + nAllocationRequested) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
nAllocationCount = nNewAllocationCount;
|
||||
|
||||
// @test: we can always call realloc, since it must allocate instead when passed null ptr
|
||||
if (pMemory != nullptr)
|
||||
pMemory = static_cast<T*>(realloc(pMemory, nAllocationCount * sizeof(T)));
|
||||
else
|
||||
pMemory = static_cast<T*>(alloca(nAllocationCount * sizeof(T)));
|
||||
}
|
||||
|
||||
void EnsureCapacity(const int nCapacity)
|
||||
{
|
||||
if (nAllocationCount >= nCapacity)
|
||||
return;
|
||||
|
||||
if (IsExternallyAllocated())
|
||||
{
|
||||
// can't grow a buffer whose memory was externally allocated
|
||||
debug(false);
|
||||
return;
|
||||
}
|
||||
|
||||
nAllocationCount = nCapacity;
|
||||
|
||||
// @test: we can always call realloc, since it must allocate instead when passed null ptr
|
||||
if (pMemory != nullptr)
|
||||
pMemory = static_cast<T*>(realloc(pMemory, nAllocationCount * sizeof(T)));
|
||||
else
|
||||
pMemory = static_cast<T*>(alloca(nAllocationCount * sizeof(T)));
|
||||
}
|
||||
|
||||
void ConvertToGrowableMemory(int nInitialGrowSize)
|
||||
{
|
||||
if (!IsExternallyAllocated())
|
||||
return;
|
||||
|
||||
nGrowSize = nInitialGrowSize;
|
||||
|
||||
if (nAllocationCount > 0)
|
||||
{
|
||||
const int nByteCount = nAllocationCount * sizeof(T);
|
||||
T* pGrowableMemory = static_cast<T*>(alloca(nByteCount));
|
||||
memcpy(pGrowableMemory, pMemory, nByteCount);
|
||||
pMemory = pGrowableMemory;
|
||||
}
|
||||
else
|
||||
pMemory = nullptr;
|
||||
}
|
||||
|
||||
void Purge()
|
||||
{
|
||||
if (IsExternallyAllocated())
|
||||
return;
|
||||
|
||||
if (pMemory != nullptr)
|
||||
{
|
||||
free(static_cast<void*>(pMemory));
|
||||
pMemory = nullptr;
|
||||
}
|
||||
|
||||
nAllocationCount = 0;
|
||||
}
|
||||
void Init(size_t nGrowSize, size_t nInitSize);
|
||||
|
||||
void SetExternalBuffer(T* pMemory, size_t numElements);
|
||||
|
||||
void AssumeMemory(T* pMemory, size_t numElements);
|
||||
|
||||
void* DetachMemory();
|
||||
|
||||
T* Detach();
|
||||
|
||||
CUtlMemory(const T* pMemory, size_t numElements);
|
||||
|
||||
void Swap(CUtlMemory< T, N >& mem);
|
||||
|
||||
void Purge(const int nElements)
|
||||
{
|
||||
debug(nElements >= 0);
|
||||
|
||||
if (nElements > nAllocationCount)
|
||||
{
|
||||
// ensure this isn't a grow request in disguise
|
||||
debug(nElements <= nAllocationCount);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nElements == 0)
|
||||
{
|
||||
Purge();
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsExternallyAllocated() || nElements == nAllocationCount)
|
||||
return;
|
||||
|
||||
if (pMemory == nullptr)
|
||||
{
|
||||
// allocation count is non zero, but memory is null
|
||||
debug(false);
|
||||
return;
|
||||
}
|
||||
|
||||
nAllocationCount = nElements;
|
||||
pMemory = static_cast<T*>(realloc(pMemory, nAllocationCount * sizeof(T)));
|
||||
}
|
||||
|
||||
public:
|
||||
T* pMemory; // 0x00
|
||||
int nAllocationCount; // 0x04
|
||||
int nGrowSize;
|
||||
// 0x08
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Attaches the buffer to external memory....
|
||||
//-----------------------------------------------------------------------------
|
||||
template< class T, class N >
|
||||
void CUtlMemory<T, N>::SetExternalBuffer(T* pMemory, size_t numElements)
|
||||
{
|
||||
// Blow away any existing allocated memory
|
||||
Purge();
|
||||
|
||||
pMemory = pMemory;
|
||||
nAllocationCount = numElements;
|
||||
|
||||
// Indicate that we don't own the memory
|
||||
nGrowSize = EXTERNAL_BUFFER_MARKER;
|
||||
}
|
||||
|
||||
template< class T, class N >
|
||||
void CUtlMemory<T, N>::AssumeMemory(T* pMemory, size_t numElements)
|
||||
{
|
||||
// Blow away any existing allocated memory
|
||||
Purge();
|
||||
|
||||
// Simply take the pointer but don't mark us as external
|
||||
pMemory = pMemory;
|
||||
nAllocationCount = numElements;
|
||||
}
|
||||
|
||||
template< class T, class N >
|
||||
void* CUtlMemory<T, N>::DetachMemory()
|
||||
{
|
||||
if (IsExternallyAllocated())
|
||||
return NULL;
|
||||
|
||||
void* pMemory = pMemory;
|
||||
pMemory = 0;
|
||||
nAllocationCount = 0;
|
||||
return pMemory;
|
||||
}
|
||||
|
||||
template< class T, class N >
|
||||
inline T* CUtlMemory<T, N>::Detach()
|
||||
{
|
||||
return (T*)DetachMemory();
|
||||
}
|
||||
|
||||
|
||||
template<class T, class N>
|
||||
inline CUtlMemory<T, N>::CUtlMemory(const T* pMemory, size_t numElements) : nAllocationCount(static_cast<N>(numElements))
|
||||
{
|
||||
// Special marker indicating externally supplied modifiable memory
|
||||
this->pMemory = (T*)pMemory;
|
||||
nGrowSize = -2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template< class T, class I >
|
||||
void CUtlMemory<T, I>::Init(size_t nGrowSize /*= 0*/, size_t nInitSize /*= 0*/)
|
||||
{
|
||||
Purge();
|
||||
nGrowSize = nGrowSize;
|
||||
nAllocationCount = nInitSize;
|
||||
ConvertToGrowableMemory(nGrowSize);
|
||||
if (nAllocationCount)
|
||||
{
|
||||
pMemory = (T*)malloc(nAllocationCount * sizeof(T));
|
||||
}
|
||||
}
|
||||
|
||||
template< class T, class N >
|
||||
void CUtlMemory<T, N>::Swap(CUtlMemory<T, N>& mem)
|
||||
{
|
||||
V_swap(nGrowSize, mem.nGrowSize);
|
||||
V_swap(pMemory, mem.pMemory);
|
||||
V_swap(nAllocationCount, mem.nAllocationCount);
|
||||
}
|
||||
|
||||
template <class T, int nAlignment>
|
||||
class CUtlMemoryAligned : public CUtlMemory<T>
|
||||
{
|
||||
public:
|
||||
// @note: not implemented
|
||||
};
|
||||
|
||||
template <class T, std::size_t SIZE, class I = int>
|
||||
class CUtlMemoryFixedGrowable : public CUtlMemory<T, I>
|
||||
{
|
||||
typedef CUtlMemory<T, I> BaseClass;
|
||||
|
||||
public:
|
||||
CUtlMemoryFixedGrowable(int nInitialGrowSize = 0, int nInitialSize = SIZE) :
|
||||
BaseClass(arrFixedMemory, SIZE)
|
||||
{
|
||||
debug(nInitialSize == 0 || nInitialSize == SIZE);
|
||||
nMallocGrowSize = nInitialGrowSize;
|
||||
}
|
||||
|
||||
void Grow(int nCount = 1)
|
||||
{
|
||||
if (this->IsExternallyAllocated())
|
||||
this->ConvertToGrowableMemory(nMallocGrowSize);
|
||||
|
||||
BaseClass::Grow(nCount);
|
||||
}
|
||||
|
||||
void EnsureCapacity(int nCapacity)
|
||||
{
|
||||
if (CUtlMemory<T>::nAllocationCount >= nCapacity)
|
||||
return;
|
||||
|
||||
if (this->IsExternallyAllocated())
|
||||
// can't grow a buffer whose memory was externally allocated
|
||||
this->ConvertToGrowableMemory(nMallocGrowSize);
|
||||
|
||||
BaseClass::EnsureCapacity(nCapacity);
|
||||
}
|
||||
|
||||
private:
|
||||
int nMallocGrowSize;
|
||||
T arrFixedMemory[SIZE];
|
||||
};
|
||||
|
||||
template <typename T, std::size_t SIZE, int nAlignment = 0>
|
||||
class CUtlMemoryFixed
|
||||
{
|
||||
public:
|
||||
CUtlMemoryFixed(const int nGrowSize = 0, const int nInitialCapacity = 0)
|
||||
{
|
||||
debug(nInitialCapacity == 0 || nInitialCapacity == SIZE);
|
||||
}
|
||||
|
||||
CUtlMemoryFixed(const T* pMemory, const int nElements)
|
||||
{
|
||||
debug(false);
|
||||
}
|
||||
|
||||
[[nodiscard]] static constexpr bool IsValidIndex(const int nIndex)
|
||||
{
|
||||
return (nIndex >= 0) && (nIndex < SIZE);
|
||||
}
|
||||
|
||||
// specify the invalid ('null') index that we'll only return on failure
|
||||
static constexpr int INVALID_INDEX = -1;
|
||||
|
||||
[[nodiscard]] static constexpr int InvalidIndex()
|
||||
{
|
||||
return INVALID_INDEX;
|
||||
}
|
||||
|
||||
[[nodiscard]] T* Base()
|
||||
{
|
||||
if (nAlignment == 0)
|
||||
return reinterpret_cast<T*>(&pMemory[0]);
|
||||
|
||||
return reinterpret_cast<T*>((reinterpret_cast<std::uintptr_t>(&pMemory[0]) + nAlignment - 1) & ~(nAlignment - 1));
|
||||
}
|
||||
|
||||
[[nodiscard]] const T* Base() const
|
||||
{
|
||||
if (nAlignment == 0)
|
||||
return reinterpret_cast<T*>(&pMemory[0]);
|
||||
|
||||
return reinterpret_cast<T*>((reinterpret_cast<std::uintptr_t>(&pMemory[0]) + nAlignment - 1) & ~(nAlignment - 1));
|
||||
}
|
||||
|
||||
[[nodiscard]] T& operator[](int nIndex)
|
||||
{
|
||||
debug(IsValidIndex(nIndex));
|
||||
return Base()[nIndex];
|
||||
}
|
||||
|
||||
[[nodiscard]] const T& operator[](int nIndex) const
|
||||
{
|
||||
debug(IsValidIndex(nIndex));
|
||||
return Base()[nIndex];
|
||||
}
|
||||
|
||||
[[nodiscard]] T& Element(int nIndex)
|
||||
{
|
||||
debug(IsValidIndex(nIndex));
|
||||
return Base()[nIndex];
|
||||
}
|
||||
|
||||
[[nodiscard]] const T& Element(int nIndex) const
|
||||
{
|
||||
debug(IsValidIndex(nIndex));
|
||||
return Base()[nIndex];
|
||||
}
|
||||
|
||||
[[nodiscard]] int AllocationCount() const
|
||||
{
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
[[nodiscard]] int Count() const
|
||||
{
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
void Grow(int nCount = 1)
|
||||
{
|
||||
debug(false);
|
||||
}
|
||||
|
||||
void EnsureCapacity(const int nCapacity)
|
||||
{
|
||||
debug(nCapacity <= SIZE);
|
||||
}
|
||||
|
||||
void Purge() { }
|
||||
|
||||
void Purge(const int nElements)
|
||||
{
|
||||
debug(false);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsExternallyAllocated() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
class Iterator_t
|
||||
{
|
||||
public:
|
||||
Iterator_t(const int nIndex) :
|
||||
nIndex(nIndex) { }
|
||||
|
||||
bool operator==(const Iterator_t it) const
|
||||
{
|
||||
return nIndex == it.nIndex;
|
||||
}
|
||||
|
||||
bool operator!=(const Iterator_t it) const
|
||||
{
|
||||
return nIndex != it.nIndex;
|
||||
}
|
||||
|
||||
int nIndex;
|
||||
};
|
||||
|
||||
[[nodiscard]] Iterator_t First() const
|
||||
{
|
||||
return Iterator_t(IsValidIndex(0) ? 0 : InvalidIndex());
|
||||
}
|
||||
|
||||
[[nodiscard]] Iterator_t Next(const Iterator_t& it) const
|
||||
{
|
||||
return Iterator_t(IsValidIndex(it.nIndex + 1) ? it.nIndex + 1 : InvalidIndex());
|
||||
}
|
||||
|
||||
[[nodiscard]] int GetIndex(const Iterator_t& it) const
|
||||
{
|
||||
return it.nIndex;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsIndexAfter(int i, const Iterator_t& it) const
|
||||
{
|
||||
return i > it.nIndex;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsValidIterator(const Iterator_t& it) const
|
||||
{
|
||||
return IsValidIndex(it.nIndex);
|
||||
}
|
||||
|
||||
[[nodiscard]] Iterator_t InvalidIterator() const
|
||||
{
|
||||
return Iterator_t(InvalidIndex());
|
||||
}
|
||||
|
||||
private:
|
||||
char pMemory[SIZE * sizeof(T) + nAlignment];
|
||||
};
|
||||
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
template <size_t SIZE = 256>
|
||||
struct String_t
|
||||
{
|
||||
char szBuffer[SIZE];
|
||||
|
||||
// Constructor for formatting a string
|
||||
String_t(const char* szFormat, const char* arg1, const char* arg2)
|
||||
{
|
||||
CustomFormat(szFormat, arg1, arg2);
|
||||
}
|
||||
|
||||
// Custom format function (simplified for two arguments)
|
||||
void CustomFormat(const char* szFormat, const char* arg1, const char* arg2)
|
||||
{
|
||||
size_t idx = 0;
|
||||
const char* ptr = szFormat;
|
||||
|
||||
// Loop through the format string
|
||||
while (*ptr != '\0' && idx < SIZE - 1)
|
||||
{
|
||||
if (*ptr == '%' && *(ptr + 1) == 's') // Handle first "%s"
|
||||
{
|
||||
ptr += 2; // Skip "%s"
|
||||
const char* strArg = arg1;
|
||||
while (*strArg != '\0' && idx < SIZE - 1)
|
||||
{
|
||||
szBuffer[idx++] = *strArg++;
|
||||
}
|
||||
}
|
||||
else if (*ptr == '%' && *(ptr + 1) == 's') // Handle second "%s"
|
||||
{
|
||||
ptr += 2; // Skip "%s"
|
||||
const char* strArg = arg2;
|
||||
while (*strArg != '\0' && idx < SIZE - 1)
|
||||
{
|
||||
szBuffer[idx++] = *strArg++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
szBuffer[idx++] = *ptr++; // Copy the current character
|
||||
}
|
||||
}
|
||||
|
||||
szBuffer[idx] = '\0'; // Null terminate the string
|
||||
}
|
||||
|
||||
// Getter for the formatted data
|
||||
const char* Data() const
|
||||
{
|
||||
return this->szBuffer;
|
||||
}
|
||||
|
||||
// Clear the buffer
|
||||
void Clear()
|
||||
{
|
||||
szBuffer[0] = '\0';
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
struct ResourceBinding_t
|
||||
{
|
||||
void* pData;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class CStrongHandle
|
||||
{
|
||||
public:
|
||||
operator T* () const
|
||||
{
|
||||
if (pBinding == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return static_cast<T*>(pBinding->pData);
|
||||
}
|
||||
|
||||
T* operator->() const
|
||||
{
|
||||
if (pBinding == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return static_cast<T*>(pBinding->pData);
|
||||
}
|
||||
|
||||
const ResourceBinding_t* pBinding;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,336 @@
|
||||
#pragma once
|
||||
#include <cstddef>
|
||||
#include "..\utlmemory\utlmemory.h"
|
||||
|
||||
|
||||
template <class T, class A = CUtlMemory<T>>
|
||||
class CUtlVector
|
||||
{
|
||||
using CAllocator = A;
|
||||
|
||||
public:
|
||||
explicit CUtlVector(const int nGrowSize = 0, const int nInitialCapacity = 0) :
|
||||
memory(nGrowSize, nInitialCapacity), nSize(0), pElements(memory.Base()) { }
|
||||
|
||||
CUtlVector(T* pMemory, const int nInitialCapacity, const int nInitialCount = 0) :
|
||||
memory(pMemory, nInitialCapacity), nSize(nInitialCount), pElements(memory.Base()) { }
|
||||
|
||||
CUtlVector(const CUtlVector&) = delete;
|
||||
|
||||
~CUtlVector()
|
||||
{
|
||||
Purge();
|
||||
}
|
||||
|
||||
CUtlVector& operator=(const CUtlVector& vecOther)
|
||||
{
|
||||
debug(&vecOther != this);
|
||||
|
||||
const int nSourceCount = vecOther.Count();
|
||||
SetCount(nSourceCount);
|
||||
|
||||
for (int i = 0; i < nSourceCount; i++)
|
||||
(*this)[i] = vecOther[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] T& operator[](const int nIndex)
|
||||
{
|
||||
debug(IsValidIndex(nIndex));
|
||||
return memory[nIndex];
|
||||
}
|
||||
|
||||
[[nodiscard]] const T& operator[](const int nIndex) const
|
||||
{
|
||||
debug(IsValidIndex(nIndex));
|
||||
return memory[nIndex];
|
||||
}
|
||||
|
||||
[[nodiscard]] T& Element2(int nIndex) const
|
||||
{
|
||||
debug(IsValidIndex(nIndex));
|
||||
return memory[nIndex];
|
||||
}
|
||||
[[nodiscard]] T& Element(const int nIndex)
|
||||
{
|
||||
debug(IsValidIndex(nIndex));
|
||||
return memory[nIndex];
|
||||
}
|
||||
|
||||
[[nodiscard]] const T& Element(const int nIndex) const
|
||||
{
|
||||
debug(IsValidIndex(nIndex));
|
||||
return memory[nIndex];
|
||||
}
|
||||
|
||||
[[nodiscard]] T* Base()
|
||||
{
|
||||
return memory.Base();
|
||||
}
|
||||
|
||||
[[nodiscard]] const T* Base() const
|
||||
{
|
||||
return memory.Base();
|
||||
}
|
||||
|
||||
[[nodiscard]] int Count() const
|
||||
{
|
||||
return nSize;
|
||||
}
|
||||
|
||||
[[nodiscard]] int& Size()
|
||||
{
|
||||
return nSize;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsValidIndex(const int nIndex) const
|
||||
{
|
||||
return (nIndex >= 0) && (nIndex < nSize);
|
||||
}
|
||||
|
||||
void CopyFromArray(const T* pArraySource, int nArraySize)
|
||||
{
|
||||
|
||||
debug(memory.Base() == nullptr || pArraySource == nullptr || begin() >= (pArraySource + nArraySize) || pArraySource >= end());
|
||||
|
||||
|
||||
SetCount(nArraySize);
|
||||
|
||||
for (int i = 0; i < nArraySize; i++)
|
||||
(*this)[i] = pArraySource[i];
|
||||
}
|
||||
|
||||
void GrowVector(const int nCount = 1)
|
||||
{
|
||||
if (nSize + nCount > memory.AllocationCount())
|
||||
memory.Grow(nSize + nCount - memory.AllocationCount());
|
||||
|
||||
nSize += nCount;
|
||||
pElements = memory.Base();
|
||||
}
|
||||
|
||||
void EnsureCapacity(int nCapacity)
|
||||
{
|
||||
memory.EnsureCapacity(nCapacity);
|
||||
pElements = memory.Base();
|
||||
}
|
||||
|
||||
void Purge()
|
||||
{
|
||||
RemoveAll();
|
||||
memory.Purge();
|
||||
pElements = memory.Base();
|
||||
}
|
||||
|
||||
void ShiftElementsRight(const int nElement, const int nShift = 1)
|
||||
{
|
||||
debug(IsValidIndex(nElement) || nSize == 0 || nShift == 0);
|
||||
|
||||
if (const int nToMove = nSize - nElement - nShift; nToMove > 0 && nShift > 0)
|
||||
memmove(&Element(nElement + nShift), &Element(nElement), nToMove * sizeof(T));
|
||||
}
|
||||
|
||||
void ShiftElementsLeft(const int nElement, const int nShift = 1)
|
||||
{
|
||||
debug(IsValidIndex(nElement) || nSize == 0 || nShift == 0);
|
||||
|
||||
if (const int nToMove = nSize - nElement - nShift; nToMove > 0 && nShift > 0)
|
||||
memmove(&Element(nElement), &Element(nElement + nShift), nToMove * sizeof(T));
|
||||
}
|
||||
|
||||
int AddToHead()
|
||||
{
|
||||
return InsertBefore(0);
|
||||
}
|
||||
|
||||
int AddToHead(const T& source)
|
||||
{
|
||||
// can't insert something that's in the list. reallocation may hose us
|
||||
debug(memory.Base() == nullptr || &source < begin() || &source >= end());
|
||||
return InsertBefore(0, source);
|
||||
}
|
||||
|
||||
int AddMultipleToHead(const int nCount)
|
||||
{
|
||||
return InsertMultipleBefore(0, nCount);
|
||||
}
|
||||
|
||||
int AddToTail()
|
||||
{
|
||||
return InsertBefore(nSize);
|
||||
}
|
||||
|
||||
int AddToTail(const T& source)
|
||||
{
|
||||
// can't insert something that's in the list. reallocation may hose us
|
||||
debug(memory.Base() == nullptr || &source < begin() || &source >= end());
|
||||
return InsertBefore(nSize, source);
|
||||
}
|
||||
|
||||
int AddMultipleToTail(const int nCount)
|
||||
{
|
||||
return InsertMultipleBefore(nSize, nCount);
|
||||
}
|
||||
|
||||
void SetCount(const int nCount)
|
||||
{
|
||||
RemoveAll();
|
||||
AddMultipleToTail(nCount);
|
||||
}
|
||||
|
||||
int InsertBefore(const int nElement)
|
||||
{
|
||||
// can insert at the end
|
||||
debug(nElement == nSize || IsValidIndex(nElement));
|
||||
|
||||
GrowVector();
|
||||
ShiftElementsRight(nElement);
|
||||
new (&Element(nElement)) T;
|
||||
return nElement;
|
||||
}
|
||||
|
||||
int InsertMultipleBefore(const int nElement, const int nCount)
|
||||
{
|
||||
if (nCount == 0)
|
||||
return nElement;
|
||||
|
||||
|
||||
debug(nElement == nSize || IsValidIndex(nElement));
|
||||
|
||||
GrowVector(nCount);
|
||||
ShiftElementsRight(nElement, nCount);
|
||||
|
||||
|
||||
for (int i = 0; i < nElement; ++i)
|
||||
new (&Element(nElement + i)) T;
|
||||
|
||||
return nElement;
|
||||
}
|
||||
|
||||
int InsertBefore(const int nElement, const T& source)
|
||||
{
|
||||
|
||||
debug(memory.Base() == nullptr || &source < begin() || &source >= end());
|
||||
|
||||
debug(nElement == nSize || IsValidIndex(nElement));
|
||||
|
||||
GrowVector();
|
||||
ShiftElementsRight(nElement);
|
||||
new (&Element(nElement)) T(source);
|
||||
return nElement;
|
||||
}
|
||||
|
||||
int InsertMultipleBefore(const int nElement, const int nCount, const T* pSource)
|
||||
{
|
||||
if (nCount == 0)
|
||||
return nElement;
|
||||
|
||||
debug(nElement == nSize || IsValidIndex(nElement));
|
||||
|
||||
GrowVector(nCount);
|
||||
ShiftElementsRight(nElement, nCount);
|
||||
|
||||
if (pSource == nullptr)
|
||||
{
|
||||
for (int i = 0; i < nCount; ++i)
|
||||
new (&Element(nElement + i)) T;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < nCount; i++)
|
||||
new (&Element(nElement)) T(pSource[i]);
|
||||
}
|
||||
|
||||
return nElement;
|
||||
}
|
||||
|
||||
[[nodiscard]] int Find(const T& source) const
|
||||
{
|
||||
for (int i = 0; i < nSize; ++i)
|
||||
{
|
||||
if (Element(i) == source)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool FindAndRemove(const T& source)
|
||||
{
|
||||
if (const int nElement = Find(source); nElement != -1)
|
||||
{
|
||||
Remove(nElement);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Remove(const int nElement)
|
||||
{
|
||||
(&Element(nElement))->~T();
|
||||
ShiftElementsLeft(nElement);
|
||||
--nSize;
|
||||
}
|
||||
|
||||
void RemoveAll()
|
||||
{
|
||||
for (int i = nSize; --i >= 0;)
|
||||
(&Element(i))->~T();
|
||||
|
||||
nSize = 0;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto begin() noexcept
|
||||
{
|
||||
return memory.Base();
|
||||
}
|
||||
|
||||
[[nodiscard]] auto end() noexcept
|
||||
{
|
||||
return memory.Base() + nSize;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto begin() const noexcept
|
||||
{
|
||||
return memory.Base();
|
||||
}
|
||||
|
||||
[[nodiscard]] auto end() const noexcept
|
||||
{
|
||||
return memory.Base() + nSize;
|
||||
}
|
||||
|
||||
protected:
|
||||
int nSize;
|
||||
CAllocator memory;
|
||||
T* pElements;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class CUtlVectorAligned : public CUtlVector<T, CUtlMemoryAligned<T, alignof(T)>>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
template <class T, std::size_t MAX_SIZE>
|
||||
class CUtlVectorFixed : public CUtlVector<T, CUtlMemoryFixed<T, MAX_SIZE>>
|
||||
{
|
||||
using CBaseClass = CUtlVector<T, CUtlMemoryFixed<T, MAX_SIZE>>;
|
||||
|
||||
public:
|
||||
explicit CUtlVectorFixed(int nGrowSize = 0, int nInitialCapacity = 0) :
|
||||
CBaseClass(nGrowSize, nInitialCapacity) { }
|
||||
|
||||
CUtlVectorFixed(T* pMemory, int nElements) :
|
||||
CBaseClass(pMemory, nElements) { }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class C_NetworkUtlVectorBase
|
||||
{
|
||||
public:
|
||||
std::uint32_t nSize;
|
||||
T* pElements;
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
#include "vector.h"
|
||||
392
TempleWare-CS2/source/templeware/utils/math/vector/vector.h
Normal file
392
TempleWare-CS2/source/templeware/utils/math/vector/vector.h
Normal file
@@ -0,0 +1,392 @@
|
||||
#pragma once
|
||||
#include "../../module/module.h"
|
||||
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
|
||||
|
||||
struct QAngle_t;
|
||||
struct Matrix3x4_t;
|
||||
|
||||
struct Vector2D_t {
|
||||
constexpr Vector2D_t(const float x = 0.0f, const float y = 0.0f) :
|
||||
x(x), y(y) {
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsZero() const {
|
||||
return (this->x == 0.0f && this->y == 0.0f);
|
||||
}
|
||||
|
||||
float x = 0.0f, y = 0.0f;
|
||||
};
|
||||
|
||||
struct Vector_t {
|
||||
public:
|
||||
constexpr Vector_t(const float x = 0.0f, const float y = 0.0f, const float z = 0.0f) :
|
||||
x(x), y(y), z(z) {
|
||||
}
|
||||
|
||||
constexpr Vector_t(const float* arrVector) :
|
||||
x(arrVector[0]), y(arrVector[1]), z(arrVector[2]) {
|
||||
}
|
||||
|
||||
constexpr Vector_t(const Vector2D_t& vecBase2D) :
|
||||
x(vecBase2D.x), y(vecBase2D.y) {
|
||||
}
|
||||
|
||||
|
||||
[[nodiscard]] float& operator[](const int nIndex) {
|
||||
return reinterpret_cast<float*>(this)[nIndex];
|
||||
}
|
||||
|
||||
[[nodiscard]] const float& operator[](const int nIndex) const {
|
||||
return reinterpret_cast<const float*>(this)[nIndex];
|
||||
}
|
||||
|
||||
constexpr Vector_t& operator=(const Vector_t& vecBase) {
|
||||
this->x = vecBase.x;
|
||||
this->y = vecBase.y;
|
||||
this->z = vecBase.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Vector_t& operator=(const Vector2D_t& vecBase2D) {
|
||||
this->x = vecBase2D.x;
|
||||
this->y = vecBase2D.y;
|
||||
this->z = 0.0f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Vector_t& operator+=(const Vector_t& vecBase) {
|
||||
this->x += vecBase.x;
|
||||
this->y += vecBase.y;
|
||||
this->z += vecBase.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Vector_t& operator-=(const Vector_t& vecBase) {
|
||||
this->x -= vecBase.x;
|
||||
this->y -= vecBase.y;
|
||||
this->z -= vecBase.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Vector_t& operator*=(const Vector_t& vecBase) {
|
||||
this->x *= vecBase.x;
|
||||
this->y *= vecBase.y;
|
||||
this->z *= vecBase.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Vector_t& operator/=(const Vector_t& vecBase) {
|
||||
this->x /= vecBase.x;
|
||||
this->y /= vecBase.y;
|
||||
this->z /= vecBase.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Vector_t& operator+=(const float flAdd) {
|
||||
this->x += flAdd;
|
||||
this->y += flAdd;
|
||||
this->z += flAdd;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Vector_t& operator-=(const float flSubtract) {
|
||||
this->x -= flSubtract;
|
||||
this->y -= flSubtract;
|
||||
this->z -= flSubtract;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Vector_t& operator*=(const float flMultiply) {
|
||||
this->x *= flMultiply;
|
||||
this->y *= flMultiply;
|
||||
this->z *= flMultiply;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Vector_t& operator/=(const float flDivide) {
|
||||
this->x /= flDivide;
|
||||
this->y /= flDivide;
|
||||
this->z /= flDivide;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Vector_t& operator-() {
|
||||
this->x = -this->x;
|
||||
this->y = -this->y;
|
||||
this->z = -this->z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Vector_t operator-() const {
|
||||
return { -this->x, -this->y, -this->z };
|
||||
}
|
||||
|
||||
Vector_t operator+(const Vector_t& vecAdd) const {
|
||||
return { this->x + vecAdd.x, this->y + vecAdd.y, this->z + vecAdd.z };
|
||||
}
|
||||
|
||||
Vector_t operator-(const Vector_t& vecSubtract) const {
|
||||
return { this->x - vecSubtract.x, this->y - vecSubtract.y, this->z - vecSubtract.z };
|
||||
}
|
||||
|
||||
Vector_t operator*(const Vector_t& vecMultiply) const {
|
||||
return { this->x * vecMultiply.x, this->y * vecMultiply.y, this->z * vecMultiply.z };
|
||||
}
|
||||
|
||||
Vector_t operator/(const Vector_t& vecDivide) const {
|
||||
return { this->x / vecDivide.x, this->y / vecDivide.y, this->z / vecDivide.z };
|
||||
}
|
||||
|
||||
Vector_t operator+(const float flAdd) const {
|
||||
return { this->x + flAdd, this->y + flAdd, this->z + flAdd };
|
||||
}
|
||||
|
||||
Vector_t operator-(const float flSubtract) const {
|
||||
return { this->x - flSubtract, this->y - flSubtract, this->z - flSubtract };
|
||||
}
|
||||
|
||||
Vector_t operator*(const float flMultiply) const {
|
||||
return { this->x * flMultiply, this->y * flMultiply, this->z * flMultiply };
|
||||
}
|
||||
|
||||
Vector_t operator/(const float flDivide) const {
|
||||
return { this->x / flDivide, this->y / flDivide, this->z / flDivide };
|
||||
}
|
||||
Vector_t Normalize() const {
|
||||
float len = Length();
|
||||
if (len != 0)
|
||||
return { x / len, y / len, z / len };
|
||||
return { 0, 0, 0 };
|
||||
}
|
||||
float Length() const {
|
||||
return std::sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
float Distance(const Vector_t& other) const {
|
||||
return std::sqrt((x - other.x) * (x - other.x) +
|
||||
(y - other.y) * (y - other.y) +
|
||||
(z - other.z) * (z - other.z));
|
||||
}
|
||||
|
||||
float x = 0.0f, y = 0.0f, z = 0.0f;
|
||||
};
|
||||
|
||||
struct Vector4D_t {
|
||||
constexpr Vector4D_t(const float x = 0.0f, const float y = 0.0f, const float z = 0.0f, const float w = 0.0f) :
|
||||
x(x), y(y), z(z), w(w) {
|
||||
}
|
||||
|
||||
float x = 0.0f, y = 0.0f, z = 0.0f, w = 0.0f;
|
||||
};
|
||||
|
||||
struct alignas(16) VectorAligned_t : Vector_t {
|
||||
VectorAligned_t() = default;
|
||||
|
||||
explicit VectorAligned_t(const Vector_t& vecBase) {
|
||||
this->x = vecBase.x;
|
||||
this->y = vecBase.y;
|
||||
this->z = vecBase.z;
|
||||
this->w = 0.0f;
|
||||
}
|
||||
|
||||
constexpr VectorAligned_t& operator=(const Vector_t& vecBase) {
|
||||
this->x = vecBase.x;
|
||||
this->y = vecBase.y;
|
||||
this->z = vecBase.z;
|
||||
this->w = 0.0f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
float w = 0.0f;
|
||||
};
|
||||
|
||||
struct Matrix3x4_t;
|
||||
|
||||
struct QAngle_t {
|
||||
constexpr QAngle_t(float x = 0.f, float y = 0.f, float z = 0.f) :
|
||||
x(x), y(y), z(z) {
|
||||
}
|
||||
|
||||
constexpr QAngle_t(const float* arrAngles) :
|
||||
x(arrAngles[0]), y(arrAngles[1]), z(arrAngles[2]) {
|
||||
}
|
||||
|
||||
#pragma region qangle_array_operators
|
||||
|
||||
[[nodiscard]] float& operator[](const int nIndex) {
|
||||
return reinterpret_cast<float*>(this)[nIndex];
|
||||
}
|
||||
|
||||
[[nodiscard]] const float& operator[](const int nIndex) const {
|
||||
return reinterpret_cast<const float*>(this)[nIndex];
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region qangle_relational_operators
|
||||
|
||||
bool operator==(const QAngle_t& angBase) const {
|
||||
return this->IsEqual(angBase);
|
||||
}
|
||||
|
||||
bool operator!=(const QAngle_t& angBase) const {
|
||||
return !this->IsEqual(angBase);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region qangle_assignment_operators
|
||||
|
||||
constexpr QAngle_t& operator=(const QAngle_t& angBase) {
|
||||
this->x = angBase.x;
|
||||
this->y = angBase.y;
|
||||
this->z = angBase.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region qangle_arithmetic_assignment_operators
|
||||
|
||||
constexpr QAngle_t& operator+=(const QAngle_t& angBase) {
|
||||
this->x += angBase.x;
|
||||
this->y += angBase.y;
|
||||
this->z += angBase.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr QAngle_t& operator-=(const QAngle_t& angBase) {
|
||||
this->x -= angBase.x;
|
||||
this->y -= angBase.y;
|
||||
this->z -= angBase.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr QAngle_t& operator*=(const QAngle_t& angBase) {
|
||||
this->x *= angBase.x;
|
||||
this->y *= angBase.y;
|
||||
this->z *= angBase.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr QAngle_t& operator/=(const QAngle_t& angBase) {
|
||||
this->x /= angBase.x;
|
||||
this->y /= angBase.y;
|
||||
this->z /= angBase.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr QAngle_t& operator+=(const float flAdd) {
|
||||
this->x += flAdd;
|
||||
this->y += flAdd;
|
||||
this->z += flAdd;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr QAngle_t& operator-=(const float flSubtract) {
|
||||
this->x -= flSubtract;
|
||||
this->y -= flSubtract;
|
||||
this->z -= flSubtract;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr QAngle_t& operator*=(const float flMultiply) {
|
||||
this->x *= flMultiply;
|
||||
this->y *= flMultiply;
|
||||
this->z *= flMultiply;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr QAngle_t& operator/=(const float flDivide) {
|
||||
this->x /= flDivide;
|
||||
this->y /= flDivide;
|
||||
this->z /= flDivide;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region qangle_arithmetic_unary_operators
|
||||
|
||||
constexpr QAngle_t& operator-() {
|
||||
this->x = -this->x;
|
||||
this->y = -this->y;
|
||||
this->z = -this->z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr QAngle_t operator-() const {
|
||||
return { -this->x, -this->y, -this->z };
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region qangle_arithmetic_ternary_operators
|
||||
|
||||
constexpr QAngle_t operator+(const QAngle_t& angAdd) const {
|
||||
return { this->x + angAdd.x, this->y + angAdd.y, this->z + angAdd.z };
|
||||
}
|
||||
|
||||
constexpr QAngle_t operator-(const QAngle_t& angSubtract) const {
|
||||
return { this->x - angSubtract.x, this->y - angSubtract.y, this->z - angSubtract.z };
|
||||
}
|
||||
|
||||
constexpr QAngle_t operator*(const QAngle_t& angMultiply) const {
|
||||
return { this->x * angMultiply.x, this->y * angMultiply.y, this->z * angMultiply.z };
|
||||
}
|
||||
|
||||
constexpr QAngle_t operator/(const QAngle_t& angDivide) const {
|
||||
return { this->x / angDivide.x, this->y / angDivide.y, this->z / angDivide.z };
|
||||
}
|
||||
|
||||
constexpr QAngle_t operator+(const float flAdd) const {
|
||||
return { this->x + flAdd, this->y + flAdd, this->z + flAdd };
|
||||
}
|
||||
|
||||
constexpr QAngle_t operator-(const float flSubtract) const {
|
||||
return { this->x - flSubtract, this->y - flSubtract, this->z - flSubtract };
|
||||
}
|
||||
|
||||
constexpr QAngle_t operator*(const float flMultiply) const {
|
||||
return { this->x * flMultiply, this->y * flMultiply, this->z * flMultiply };
|
||||
}
|
||||
|
||||
constexpr QAngle_t operator/(const float flDivide) const {
|
||||
return { this->x / flDivide, this->y / flDivide, this->z / flDivide };
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
[[nodiscard]] bool IsValid() const {
|
||||
return (std::isfinite(this->x) && std::isfinite(this->y) && std::isfinite(this->z));
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsEqual(const QAngle_t& angEqual, const float flErrorMargin = std::numeric_limits<float>::epsilon()) const {
|
||||
return (std::fabsf(this->x - angEqual.x) < flErrorMargin && std::fabsf(this->y - angEqual.y) < flErrorMargin && std::fabsf(this->z - angEqual.z) < flErrorMargin);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsZero() const {
|
||||
return (this->x == 0.0f && this->y == 0.0f && this->z == 0.0f);
|
||||
}
|
||||
|
||||
/// @returns: length of hypotenuse
|
||||
[[nodiscard]] float Length2D() const {
|
||||
return std::sqrtf(x * x + y * y);
|
||||
}
|
||||
|
||||
QAngle_t& Normalize() {
|
||||
this->x = std::remainderf(this->x, 360.f);
|
||||
this->y = std::remainderf(this->y, 360.f);
|
||||
this->z = std::remainderf(this->z, 360.f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ToDirections(Vector_t* pvecForward, Vector_t* pvecRight = nullptr, Vector_t* pvecUp = nullptr) const;
|
||||
|
||||
[[nodiscard]] Matrix3x4_t ToMatrix(const Vector_t& vecOrigin = {}) const;
|
||||
|
||||
public:
|
||||
float x = 0.0f, y = 0.0f, z = 0.0f;
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
#include "viewmatrix.h"
|
||||
|
||||
#include "../../../../../external/imgui/imgui.h"
|
||||
#include <iostream>
|
||||
|
||||
bool ViewMatrix::WorldToScreen(const Vector_t& position, Vector_t& out) const {
|
||||
const float w = viewMatrix->matrix[3][0] * position.x + viewMatrix->matrix[3][1] * position.y + viewMatrix->matrix[3][2] * position.z + viewMatrix->matrix[3][3];
|
||||
if (w <= 0.001f)
|
||||
return false;
|
||||
|
||||
const float invW = 1.0f / w;
|
||||
|
||||
ImVec2 wS = ImGui::GetIO().DisplaySize;
|
||||
|
||||
const float centerX = static_cast<float>(wS.x) / 2;
|
||||
const float centerY = static_cast<float>(wS.y) / 2;
|
||||
|
||||
out.x = centerX + ((viewMatrix->matrix[0][0] * position.x + viewMatrix->matrix[0][1] * position.y + viewMatrix->matrix[0][2] * position.z + viewMatrix->matrix[0][3]) * invW * centerX);
|
||||
out.y = centerY - ((viewMatrix->matrix[1][0] * position.x + viewMatrix->matrix[1][1] * position.y + viewMatrix->matrix[1][2] * position.z + viewMatrix->matrix[1][3]) * invW * centerY);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../../../cs2/datatypes/viewmatrix/viewmatrix.h"
|
||||
#include "../vector/vector.h"
|
||||
|
||||
class ViewMatrix {
|
||||
public:
|
||||
//Vector_t WorldToScreen(const Vector_t& position) const;
|
||||
bool WorldToScreen(const Vector_t& position, Vector_t& out) const;
|
||||
|
||||
viewmatrix_t* viewMatrix;
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user