r5sdk/r5dev/thirdparty/cppnet/cppkore/VertexBuffer.cpp
2022-05-21 19:58:09 +02:00

217 lines
6.1 KiB
C++

#include "stdafx.h"
#include "VertexBuffer.h"
namespace Assets
{
VertexBuffer::VertexBuffer()
: _Buffer(nullptr), _BufferSize(0), _StoreSize(0), _MaxInfluence(1), _UVLayers(1)
{
}
VertexBuffer::VertexBuffer(uint8_t MaxInfluence, uint8_t UVLayers)
: _Buffer(nullptr), _BufferSize(0), _StoreSize(0), _MaxInfluence(MaxInfluence), _UVLayers(UVLayers)
{
}
VertexBuffer::VertexBuffer(uint32_t InitialSize, uint8_t MaxInfluence, uint8_t UVLayers)
: _Buffer(nullptr), _BufferSize(0), _StoreSize(0), _MaxInfluence(MaxInfluence), _UVLayers(UVLayers)
{
this->EnsureCapacity(InitialSize);
this->_StoreSize = 0; // Must reset this so that we start from 0
}
VertexBuffer& VertexBuffer::operator=(const VertexBuffer& Rhs)
{
if (Rhs._Buffer)
{
auto vSize = Rhs.VertexSize();
this->_Buffer = new uint8_t[vSize * Rhs._BufferSize];
this->_StoreSize = Rhs._StoreSize;
this->_BufferSize = Rhs._BufferSize;
std::memcpy(this->_Buffer, Rhs._Buffer, vSize * Rhs._BufferSize);
}
this->_MaxInfluence = Rhs._MaxInfluence;
this->_UVLayers = Rhs._UVLayers;
return *this;
}
VertexBuffer::~VertexBuffer()
{
if (this->_Buffer)
delete[] this->_Buffer;
this->_Buffer = nullptr;
this->_BufferSize = 0;
this->_StoreSize = 0;
}
void VertexBuffer::EmplaceBack(Vector3 Position, Vector3 Normal, VertexColor Color)
{
uint64_t nPos = this->_StoreSize;
this->EnsureCapacity((uint32_t)nPos + 1);
// Copy the values at expected vertex offset
nPos *= this->VertexSize();
// Copy them
std::memcpy(this->_Buffer + nPos, &Position, sizeof(Vector3));
std::memcpy(this->_Buffer + nPos + sizeof(Vector3), &Normal, sizeof(Vector3));
std::memcpy(this->_Buffer + nPos + (sizeof(Vector3) * 2), &Color, sizeof(VertexColor));
}
Vertex VertexBuffer::Emplace(Vector3 Position, Vector3 Normal, VertexColor Color)
{
uint64_t nPos = this->_StoreSize;
this->EnsureCapacity((uint32_t)nPos + 1);
// Copy the values at expected vertex offset
nPos *= this->VertexSize();
// Copy them
std::memcpy(this->_Buffer + nPos, &Position, sizeof(Vector3));
std::memcpy(this->_Buffer + nPos + sizeof(Vector3), &Normal, sizeof(Vector3));
std::memcpy(this->_Buffer + nPos + (sizeof(Vector3) * 2), &Color, sizeof(VertexColor));
// Return vertex controller
return Vertex(this->_Buffer + nPos, this->_MaxInfluence, this->_UVLayers);
}
void VertexBuffer::EmplaceBack(Vector3 Position, Vector3 Normal, VertexColor Color, Vector2 UVLayer)
{
uint64_t nPos = this->_StoreSize;
this->EnsureCapacity((uint32_t)nPos + 1);
// Copy the values at expected vertex offset
nPos *= this->VertexSize();
// Copy them
std::memcpy(this->_Buffer + nPos, &Position, sizeof(Vector3));
std::memcpy(this->_Buffer + nPos + sizeof(Vector3), &Normal, sizeof(Vector3));
std::memcpy(this->_Buffer + nPos + (sizeof(Vector3) * 2), &Color, sizeof(VertexColor));
std::memcpy(this->_Buffer + nPos + (sizeof(Vector3) * 2) + sizeof(VertexColor), &UVLayer, sizeof(Vector2));
}
Vertex VertexBuffer::Emplace(Vector3 Position, Vector3 Normal, VertexColor Color, Vector2 UVLayer)
{
uint64_t nPos = this->_StoreSize;
this->EnsureCapacity((uint32_t)nPos + 1);
// Copy the values at expected vertex offset
nPos *= this->VertexSize();
// Copy them
std::memcpy(this->_Buffer + nPos, &Position, sizeof(Vector3));
std::memcpy(this->_Buffer + nPos + sizeof(Vector3), &Normal, sizeof(Vector3));
std::memcpy(this->_Buffer + nPos + (sizeof(Vector3) * 2), &Color, sizeof(VertexColor));
std::memcpy(this->_Buffer + nPos + (sizeof(Vector3) * 2) + sizeof(VertexColor), &UVLayer, sizeof(Vector2));
// Return vertex controller
return Vertex(this->_Buffer + nPos, this->_MaxInfluence, this->_UVLayers);
}
void VertexBuffer::Clear()
{
if (this->_Buffer)
delete[] this->_Buffer;
this->_Buffer = nullptr;
this->_BufferSize = 0;
this->_StoreSize = 0;
}
void VertexBuffer::RemoveAt(uint32_t Index)
{
if (Index >= this->_StoreSize)
return;
auto vSize = this->VertexSize();
this->_StoreSize--;
if (Index < this->_StoreSize)
std::memcpy(this->_Buffer + Index, this->_Buffer + (Index + 1), (this->_StoreSize - Index) * vSize);
std::memset(&this->_Buffer[this->_StoreSize], 0, vSize);
}
const uint8_t VertexBuffer::UVLayerCount() const
{
return this->_UVLayers;
}
const uint8_t VertexBuffer::WeightCount() const
{
return this->_MaxInfluence;
}
uint32_t VertexBuffer::Count() const
{
return this->_StoreSize;
}
bool VertexBuffer::Empty() const
{
return (this->_StoreSize == 0);
}
Vertex VertexBuffer::begin() const noexcept
{
return Vertex(this->_Buffer, this->_MaxInfluence, this->_UVLayers);
}
Vertex VertexBuffer::end() const noexcept
{
return Vertex(this->_Buffer + (this->_StoreSize * this->VertexSize()), this->_MaxInfluence, this->_UVLayers);
}
Vertex VertexBuffer::operator[](uint32_t Index)
{
return Vertex(this->_Buffer + (Index * this->VertexSize()), this->_MaxInfluence, this->_UVLayers);
}
const Vertex VertexBuffer::operator[](uint32_t Index) const
{
return Vertex(this->_Buffer + (Index * this->VertexSize()), this->_MaxInfluence, this->_UVLayers);
}
void VertexBuffer::EnsureCapacity(uint32_t Capacity)
{
// Ensure that we have a proper buffer size for the string here, this is in units, NOT bytes...
// Check to ensure we aren't wasting our time first...
if (Capacity <= this->_BufferSize)
{
this->_StoreSize = Capacity;
return;
}
// Pre-calculate the size of a single vertex (Position Normal) (UVLayers) (Weights) (Colors)
auto vSize = this->VertexSize();
auto nCapacity = Capacity;
if (nCapacity < 16)
nCapacity = 16;
if (nCapacity < (this->_BufferSize + (this->_BufferSize / 2)))
nCapacity = (this->_BufferSize + (this->_BufferSize / 2));
auto tBuffer = this->_Buffer;
this->_Buffer = new uint8_t[nCapacity * vSize]();
if (tBuffer)
{
std::memcpy(this->_Buffer, tBuffer, this->_BufferSize * vSize);
delete[] tBuffer;
}
this->_BufferSize = nCapacity;
this->_StoreSize = Capacity;
}
uint32_t VertexBuffer::VertexSize() const
{
return (sizeof(Vector3) * 2) + (sizeof(Vector2) * this->_UVLayers) + (sizeof(VertexWeight) * this->_MaxInfluence) + sizeof(VertexColor) + sizeof(uint8_t);
}
}