Skip to content

Commit

Permalink
Merge pull request #124 from rayshader/curvedata
Browse files Browse the repository at this point in the history
Decode CurveData<T> with RawBuffer.
  • Loading branch information
psiberx authored May 22, 2024
2 parents 1c283c3 + ebea151 commit e5f9b10
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 7 deletions.
65 changes: 65 additions & 0 deletions include/RED4ext/NativeTypes-inl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,3 +288,68 @@ RED4EXT_INLINE bool RED4ext::Variant::CanBeInlined(const RED4ext::CBaseRTTIType*
{
return aType->GetSize() <= InlineSize && aType->GetAlignment() <= InlineAlignment;
}

template<typename T>
RED4EXT_INLINE float* RED4ext::CurveBuffer<T>::GetPoints() noexcept
{
return reinterpret_cast<float*>(reinterpret_cast<uint8_t*>(this) + offsetPoints);
}

template<typename T>
RED4EXT_INLINE T* RED4ext::CurveBuffer<T>::GetValues() noexcept
{
return reinterpret_cast<T*>(reinterpret_cast<uint8_t*>(this) + offsetValues);
}

template<typename T>
RED4EXT_INLINE RED4ext::CurveBuffer<T>* RED4ext::CurveData<T>::GetCurve() const noexcept
{
return reinterpret_cast<RED4ext::CurveBuffer<T>*>(buffer.data);
}

template<typename T>
RED4EXT_INLINE uint32_t RED4ext::CurveData<T>::GetSize() const noexcept
{
return GetCurve()->size;
}

template<typename T>
RED4EXT_INLINE RED4ext::CurvePoint<T> RED4ext::CurveData<T>::GetPoint(uint32_t aIndex) const noexcept
{
if (aIndex >= GetSize())
{
return {.point = std::numeric_limits<float>::infinity(), .value = T()};
}
const CurveBuffer<T>* curve = GetCurve();
const float* points = curve->GetPoints();
const T* values = curve->GetValues();

return {points[aIndex], values[aIndex]};
}

template<typename T>
RED4EXT_INLINE void RED4ext::CurveData<T>::SetPoint(uint32_t aIndex, const RED4ext::CurvePoint<T>& acPoint) noexcept
{
SetPoint(aIndex, acPoint.point, acPoint.value);
}

template<typename T>
RED4EXT_INLINE void RED4ext::CurveData<T>::SetPoint(uint32_t aIndex, float aPoint, const T& acValue) noexcept
{
if (aIndex >= GetSize())
{
return;
}
const CurveBuffer<T>* curve = GetCurve();
float* points = curve->GetPoints();
T* values = curve->GetValues();

points[aIndex] = aPoint;
values[aIndex] = acValue;
}

template<typename T>
RED4EXT_INLINE RED4ext::CurvePoint<T> RED4ext::CurveData<T>::operator[](uint32_t aIndex) const noexcept
{
return GetPoint(aIndex);
}
54 changes: 47 additions & 7 deletions include/RED4ext/NativeTypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <array>
#include <cstdint>
#include <limits>
#include <string_view>

#include <RED4ext/Buffer.hpp>
Expand All @@ -13,6 +14,8 @@
#include <RED4ext/InstanceType.hpp>
#include <RED4ext/NodeRef.hpp>
#include <RED4ext/ResourceReference.hpp>
#include <RED4ext/Scripting/Natives/Generated/curve/EInterpolationType.hpp>
#include <RED4ext/Scripting/Natives/Generated/curve/ESegmentsLinkType.hpp>

namespace RED4ext
{
Expand Down Expand Up @@ -209,18 +212,55 @@ static_assert(sizeof(StaticArray<std::array<uint8_t, 5>, 32>) ==
template<typename T, uint32_t MAX_LEN>
using NativeArray = std::array<T, MAX_LEN>;

template<typename T>
struct CurvePoint
{
float point;
T value;
};

template<typename T>
struct CurveBuffer
{
[[nodiscard]] float* GetPoints() noexcept;
[[nodiscard]] T* GetValues() noexcept;

uint32_t size; // 00
uint32_t unk04; // 04
uint32_t offsetPoints; // 08
uint32_t offsetValues; // 12
// float points[size]; // 16
// T values[size]; // 16 + size * sizeof(float)
};
RED4EXT_ASSERT_SIZE(CurveBuffer<float>, 0x10);
RED4EXT_ASSERT_OFFSET(CurveBuffer<float>, size, 0x00);
RED4EXT_ASSERT_OFFSET(CurveBuffer<float>, offsetPoints, 0x08);
RED4EXT_ASSERT_OFFSET(CurveBuffer<float>, offsetValues, 0x0C);

template<typename T>
struct CurveData
{
uint64_t unk00; // 00
uint64_t unk08; // 08
uint64_t unk10; // 10
uint64_t unk18; // 18
uint64_t unk20; // 20
uint64_t unk28; // 28
uint64_t unk30; // 30
[[nodiscard]] CurveBuffer<T>* GetCurve() const noexcept;
[[nodiscard]] uint32_t GetSize() const noexcept;

[[nodiscard]] CurvePoint<T> GetPoint(uint32_t aIndex) const noexcept;
void SetPoint(uint32_t aIndex, const CurvePoint<T>& acPoint) noexcept;
void SetPoint(uint32_t aIndex, float aPoint, const T& acValue) noexcept;

[[nodiscard]] inline CurvePoint<T> operator[](uint32_t aIndex) const noexcept;

CName name; // 00
RawBuffer buffer; // 08
CBaseRTTIType* valueType; // 40
curve::EInterpolationType interpolationType; // 48
curve::ESegmentsLinkType linkType; // 49
};
RED4EXT_ASSERT_SIZE(CurveData<float>, 0x38);
RED4EXT_ASSERT_OFFSET(CurveData<float>, name, 0x00);
RED4EXT_ASSERT_OFFSET(CurveData<float>, buffer, 0x08);
RED4EXT_ASSERT_OFFSET(CurveData<float>, valueType, 0x28);
RED4EXT_ASSERT_OFFSET(CurveData<float>, interpolationType, 0x30);
RED4EXT_ASSERT_OFFSET(CurveData<float>, linkType, 0x31);

template<typename T>
struct ScriptRef
Expand Down

0 comments on commit e5f9b10

Please sign in to comment.