Skip to content

Commit e5f9b10

Browse files
authored
Merge pull request #124 from rayshader/curvedata
Decode CurveData<T> with RawBuffer.
2 parents 1c283c3 + ebea151 commit e5f9b10

File tree

2 files changed

+112
-7
lines changed

2 files changed

+112
-7
lines changed

include/RED4ext/NativeTypes-inl.hpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,3 +288,68 @@ RED4EXT_INLINE bool RED4ext::Variant::CanBeInlined(const RED4ext::CBaseRTTIType*
288288
{
289289
return aType->GetSize() <= InlineSize && aType->GetAlignment() <= InlineAlignment;
290290
}
291+
292+
template<typename T>
293+
RED4EXT_INLINE float* RED4ext::CurveBuffer<T>::GetPoints() noexcept
294+
{
295+
return reinterpret_cast<float*>(reinterpret_cast<uint8_t*>(this) + offsetPoints);
296+
}
297+
298+
template<typename T>
299+
RED4EXT_INLINE T* RED4ext::CurveBuffer<T>::GetValues() noexcept
300+
{
301+
return reinterpret_cast<T*>(reinterpret_cast<uint8_t*>(this) + offsetValues);
302+
}
303+
304+
template<typename T>
305+
RED4EXT_INLINE RED4ext::CurveBuffer<T>* RED4ext::CurveData<T>::GetCurve() const noexcept
306+
{
307+
return reinterpret_cast<RED4ext::CurveBuffer<T>*>(buffer.data);
308+
}
309+
310+
template<typename T>
311+
RED4EXT_INLINE uint32_t RED4ext::CurveData<T>::GetSize() const noexcept
312+
{
313+
return GetCurve()->size;
314+
}
315+
316+
template<typename T>
317+
RED4EXT_INLINE RED4ext::CurvePoint<T> RED4ext::CurveData<T>::GetPoint(uint32_t aIndex) const noexcept
318+
{
319+
if (aIndex >= GetSize())
320+
{
321+
return {.point = std::numeric_limits<float>::infinity(), .value = T()};
322+
}
323+
const CurveBuffer<T>* curve = GetCurve();
324+
const float* points = curve->GetPoints();
325+
const T* values = curve->GetValues();
326+
327+
return {points[aIndex], values[aIndex]};
328+
}
329+
330+
template<typename T>
331+
RED4EXT_INLINE void RED4ext::CurveData<T>::SetPoint(uint32_t aIndex, const RED4ext::CurvePoint<T>& acPoint) noexcept
332+
{
333+
SetPoint(aIndex, acPoint.point, acPoint.value);
334+
}
335+
336+
template<typename T>
337+
RED4EXT_INLINE void RED4ext::CurveData<T>::SetPoint(uint32_t aIndex, float aPoint, const T& acValue) noexcept
338+
{
339+
if (aIndex >= GetSize())
340+
{
341+
return;
342+
}
343+
const CurveBuffer<T>* curve = GetCurve();
344+
float* points = curve->GetPoints();
345+
T* values = curve->GetValues();
346+
347+
points[aIndex] = aPoint;
348+
values[aIndex] = acValue;
349+
}
350+
351+
template<typename T>
352+
RED4EXT_INLINE RED4ext::CurvePoint<T> RED4ext::CurveData<T>::operator[](uint32_t aIndex) const noexcept
353+
{
354+
return GetPoint(aIndex);
355+
}

include/RED4ext/NativeTypes.hpp

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <array>
44
#include <cstdint>
5+
#include <limits>
56
#include <string_view>
67

78
#include <RED4ext/Buffer.hpp>
@@ -13,6 +14,8 @@
1314
#include <RED4ext/InstanceType.hpp>
1415
#include <RED4ext/NodeRef.hpp>
1516
#include <RED4ext/ResourceReference.hpp>
17+
#include <RED4ext/Scripting/Natives/Generated/curve/EInterpolationType.hpp>
18+
#include <RED4ext/Scripting/Natives/Generated/curve/ESegmentsLinkType.hpp>
1619

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

215+
template<typename T>
216+
struct CurvePoint
217+
{
218+
float point;
219+
T value;
220+
};
221+
222+
template<typename T>
223+
struct CurveBuffer
224+
{
225+
[[nodiscard]] float* GetPoints() noexcept;
226+
[[nodiscard]] T* GetValues() noexcept;
227+
228+
uint32_t size; // 00
229+
uint32_t unk04; // 04
230+
uint32_t offsetPoints; // 08
231+
uint32_t offsetValues; // 12
232+
// float points[size]; // 16
233+
// T values[size]; // 16 + size * sizeof(float)
234+
};
235+
RED4EXT_ASSERT_SIZE(CurveBuffer<float>, 0x10);
236+
RED4EXT_ASSERT_OFFSET(CurveBuffer<float>, size, 0x00);
237+
RED4EXT_ASSERT_OFFSET(CurveBuffer<float>, offsetPoints, 0x08);
238+
RED4EXT_ASSERT_OFFSET(CurveBuffer<float>, offsetValues, 0x0C);
239+
212240
template<typename T>
213241
struct CurveData
214242
{
215-
uint64_t unk00; // 00
216-
uint64_t unk08; // 08
217-
uint64_t unk10; // 10
218-
uint64_t unk18; // 18
219-
uint64_t unk20; // 20
220-
uint64_t unk28; // 28
221-
uint64_t unk30; // 30
243+
[[nodiscard]] CurveBuffer<T>* GetCurve() const noexcept;
244+
[[nodiscard]] uint32_t GetSize() const noexcept;
245+
246+
[[nodiscard]] CurvePoint<T> GetPoint(uint32_t aIndex) const noexcept;
247+
void SetPoint(uint32_t aIndex, const CurvePoint<T>& acPoint) noexcept;
248+
void SetPoint(uint32_t aIndex, float aPoint, const T& acValue) noexcept;
249+
250+
[[nodiscard]] inline CurvePoint<T> operator[](uint32_t aIndex) const noexcept;
251+
252+
CName name; // 00
253+
RawBuffer buffer; // 08
254+
CBaseRTTIType* valueType; // 40
255+
curve::EInterpolationType interpolationType; // 48
256+
curve::ESegmentsLinkType linkType; // 49
222257
};
223258
RED4EXT_ASSERT_SIZE(CurveData<float>, 0x38);
259+
RED4EXT_ASSERT_OFFSET(CurveData<float>, name, 0x00);
260+
RED4EXT_ASSERT_OFFSET(CurveData<float>, buffer, 0x08);
261+
RED4EXT_ASSERT_OFFSET(CurveData<float>, valueType, 0x28);
262+
RED4EXT_ASSERT_OFFSET(CurveData<float>, interpolationType, 0x30);
263+
RED4EXT_ASSERT_OFFSET(CurveData<float>, linkType, 0x31);
224264

225265
template<typename T>
226266
struct ScriptRef

0 commit comments

Comments
 (0)