From 1e757de6f632a6f5c96c8440e73600bef71a6e43 Mon Sep 17 00:00:00 2001 From: Mozz3d <163353426+Mozz3d@users.noreply.github.com> Date: Wed, 22 Jan 2025 01:57:47 -0500 Subject: [PATCH] Decoded Several Rendering Structs & Small Adjustments (#170) --- CONTRIBUTING.md | 13 +- include/RED4ext/Detail/AddressHashes.hpp | 15 ++ include/RED4ext/GpuApi/Buffer.hpp | 2 + .../RED4ext/GpuApi/CommandListContext-inl.hpp | 26 +-- include/RED4ext/GpuApi/D3D12MemAlloc-inl.hpp | 2 +- include/RED4ext/GpuApi/DeviceData-inl.hpp | 51 +----- include/RED4ext/GpuApi/DeviceData.hpp | 50 +++++- include/RED4ext/RenderProxy-inl.hpp | 167 ++++++++++++++++++ include/RED4ext/RenderProxy.hpp | 83 +++++++++ include/RED4ext/RenderResource.hpp | 37 ++++ include/RED4ext/Scripting/Natives/CMesh.hpp | 68 +++++++ .../Scripting/Natives/Generated/CMesh.hpp | 9 + .../Natives/Generated/MorphTargetMesh.hpp | 9 + .../ent/MorphTargetSkinnedMeshComponent.hpp | 10 ++ .../Generated/ent/SkinnedMeshComponent.hpp | 10 ++ .../Scripting/Natives/MorphTargetMesh.hpp | 37 ++++ include/RED4ext/Scripting/Natives/Vector2.hpp | 1 + include/RED4ext/Scripting/Natives/Vector3.hpp | 1 + include/RED4ext/Scripting/Natives/Vector4.hpp | 4 +- .../entMorphTargetSkinnedMeshComponent.hpp | 47 +++++ .../Natives/entSkinnedMeshComponent.hpp | 51 ++++++ src/RenderProxy.cpp | 5 + 22 files changed, 624 insertions(+), 74 deletions(-) create mode 100644 include/RED4ext/RenderProxy-inl.hpp create mode 100644 include/RED4ext/RenderProxy.hpp create mode 100644 include/RED4ext/RenderResource.hpp create mode 100644 include/RED4ext/Scripting/Natives/CMesh.hpp create mode 100644 include/RED4ext/Scripting/Natives/MorphTargetMesh.hpp create mode 100644 include/RED4ext/Scripting/Natives/entMorphTargetSkinnedMeshComponent.hpp create mode 100644 include/RED4ext/Scripting/Natives/entSkinnedMeshComponent.hpp create mode 100644 src/RenderProxy.cpp diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9dbe7f06c..35335a51c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -110,14 +110,7 @@ one: static constexpr const char* NAME = "vehicleBaseObject"; ``` -3. Remove `__declspec()` declaration: - -```diff -- struct __declspec(align(0x10)) BaseObject : game::Object -+ struct BaseObject : game::Object -``` - -4. Declare the new member based on its offset and type: +3. Declare the new member based on its offset and type: ```diff { @@ -135,7 +128,7 @@ one: }; ``` -5. Assert the offset of known members: +4. Assert the offset of known members: ```diff }; @@ -149,7 +142,7 @@ using VehicleObject = vehicle::BaseObject; } // namespace RED4ext ``` -6. Remove these comments: +5. Remove these comments: ```diff -// clang-format off diff --git a/include/RED4ext/Detail/AddressHashes.hpp b/include/RED4ext/Detail/AddressHashes.hpp index ada30ed88..b4dc9de3e 100644 --- a/include/RED4ext/Detail/AddressHashes.hpp +++ b/include/RED4ext/Detail/AddressHashes.hpp @@ -125,6 +125,21 @@ constexpr std::uint32_t Handle_ctor = 0xBA0C115D; constexpr std::uint32_t Handle_DecWeakRef = 0x333B1404; #pragma endregion +#pragma region IRenderProxy +constexpr std::uint32_t IRenderProxy_sub_00 = 302583262UL; +constexpr std::uint32_t IRenderProxy_sub_08 = 3505328647UL; +constexpr std::uint32_t IRenderProxy_sub_18 = 2756580845UL; +constexpr std::uint32_t IRenderProxy_sub_58 = 2462126272UL; +constexpr std::uint32_t IRenderProxy_sub_60 = 3491501770UL; +constexpr std::uint32_t IRenderProxy_sub_78 = 2542474580UL; +constexpr std::uint32_t IRenderProxy_sub_80 = 510274732UL; +constexpr std::uint32_t IRenderProxy_sub_88 = 3724941976UL; +constexpr std::uint32_t IRenderProxy_sub_90 = 1894391003UL; +constexpr std::uint32_t IRenderProxy_sub_98 = 3516862860UL; +constexpr std::uint32_t IRenderProxy_sub_A8 = 4096926792UL; +constexpr std::uint32_t IRenderProxy_sub_B0 = 1468405902UL; +#pragma endregion + #pragma region IScriptable constexpr std::uint32_t IScriptable_sub_D8 = 0xF8E41DDF; constexpr std::uint32_t IScriptable_DestructValueHolder = 0x3521331; diff --git a/include/RED4ext/GpuApi/Buffer.hpp b/include/RED4ext/GpuApi/Buffer.hpp index 8904c2479..ce23274fa 100644 --- a/include/RED4ext/GpuApi/Buffer.hpp +++ b/include/RED4ext/GpuApi/Buffer.hpp @@ -5,6 +5,8 @@ #include #include +#include + namespace RED4ext { namespace GpuApi diff --git a/include/RED4ext/GpuApi/CommandListContext-inl.hpp b/include/RED4ext/GpuApi/CommandListContext-inl.hpp index e985e0bc1..86789c185 100644 --- a/include/RED4ext/GpuApi/CommandListContext-inl.hpp +++ b/include/RED4ext/GpuApi/CommandListContext-inl.hpp @@ -6,39 +6,39 @@ #include -RED4EXT_INLINE void RED4ext::GpuApi::CommandListContext::AddPendingBarrier(const D3D12_RESOURCE_BARRIER& aBarrier) +namespace RED4ext::GpuApi +{ +RED4EXT_INLINE void CommandListContext::AddPendingBarrier(const D3D12_RESOURCE_BARRIER& aBarrier) { using func_t = void (*)(CommandListContext*, const D3D12_RESOURCE_BARRIER&); - static UniversalRelocFunc func(Detail::AddressHashes::CommandListContext_AddPendingBarrier); + static const UniversalRelocFunc func(Detail::AddressHashes::CommandListContext_AddPendingBarrier); func(this, aBarrier); } -RED4EXT_INLINE void RED4ext::GpuApi::CommandListContext::Close() +RED4EXT_INLINE void CommandListContext::Close() { using func_t = void (*)(CommandListContext*); - static UniversalRelocFunc func(Detail::AddressHashes::CommandListContext_Close); + static const UniversalRelocFunc func(Detail::AddressHashes::CommandListContext_Close); func(this); } -RED4EXT_INLINE void RED4ext::GpuApi::CommandListContext::FlushPendingBarriers() +RED4EXT_INLINE void CommandListContext::FlushPendingBarriers() { using func_t = void (*)(CommandListContext*); static UniversalRelocFunc func(Detail::AddressHashes::CommandListContext_FlushPendingBarriers); func(this); } -RED4EXT_INLINE RED4ext::GpuApi::CommandListContext* AcquireFreeCommandList(RED4ext::GpuApi::CommandListType aType, - RED4ext::StringView& aDebugName, - uint64_t aHash) +RED4EXT_INLINE CommandListContext* AcquireFreeCommandList(CommandListType aType, const StringView& aDebugName, + uint64_t aHash) { // NOTE: This function has parameters for debug name and hash which seem to be optional. // Expects unique ptr as an out param and returns it by reference. - using func_t = RED4ext::GpuApi::CommandListContext*& (*)(RED4ext::GpuApi::CommandListContext*&, - RED4ext::GpuApi::CommandListType, - const RED4ext::StringView&, uint64_t); - static RED4ext::UniversalRelocFunc func(RED4ext::Detail::AddressHashes::GetFreeCommandList); + using func_t = CommandListContext*& (*)(CommandListContext*&, CommandListType, const StringView&, uint64_t); + static const UniversalRelocFunc func(Detail::AddressHashes::GetFreeCommandList); // TODO: This should be unique_ptr which function fills in and returns. - RED4ext::GpuApi::CommandListContext* outContext = nullptr; + CommandListContext* outContext = nullptr; return func(outContext, aType, aDebugName, aHash); } +} // namespace RED4ext::GpuApi diff --git a/include/RED4ext/GpuApi/D3D12MemAlloc-inl.hpp b/include/RED4ext/GpuApi/D3D12MemAlloc-inl.hpp index fd799990a..7f1dd7c67 100644 --- a/include/RED4ext/GpuApi/D3D12MemAlloc-inl.hpp +++ b/include/RED4ext/GpuApi/D3D12MemAlloc-inl.hpp @@ -16,7 +16,7 @@ RED4EXT_INLINE HRESULT D3D12MA::Allocator::CreateResource(const ALLOCATION_DESC* { using func_t = HRESULT (*)(Allocator*, const ALLOCATION_DESC*, const D3D12_RESOURCE_DESC*, D3D12_RESOURCE_STATES, const D3D12_CLEAR_VALUE*, Allocation**, REFIID, void**); - static RED4ext::UniversalRelocFunc func(RED4ext::Detail::AddressHashes::Allocator_CreateResource); + static const RED4ext::UniversalRelocFunc func(RED4ext::Detail::AddressHashes::Allocator_CreateResource); return func(this, pAllocDesc, pResourceDesc, InitialResourceState, pOptimizedClearValue, ppAllocation, riidResource, ppvResource); } diff --git a/include/RED4ext/GpuApi/DeviceData-inl.hpp b/include/RED4ext/GpuApi/DeviceData-inl.hpp index f7af5df0c..577d7314e 100644 --- a/include/RED4ext/GpuApi/DeviceData-inl.hpp +++ b/include/RED4ext/GpuApi/DeviceData-inl.hpp @@ -4,54 +4,11 @@ #include #endif -template -bool RED4ext::GpuApi::ResourceContainer::Resource::IsUsed() const +namespace RED4ext::GpuApi { - return refCount >= 0; -} - -template -bool RED4ext::GpuApi::ResourceContainer::IsUsedID(const uint32_t id) const -{ - return IsValidID(id) && resources[IDToIndex(id)].IsUsed(); -} - -template -bool RED4ext::GpuApi::ResourceContainer::IsUnusedID(const uint32_t id) const -{ - return IsValidID(id) && !resources[IDToIndex(id)].IsUsed(); -} - -template -bool RED4ext::GpuApi::ResourceContainer::IsEmpty() const -{ - assert(numUnused <= MAX_SIZE); - return numUnused == MAX_SIZE; -} - -template -bool RED4ext::GpuApi::ResourceContainer::IsFull() const -{ - assert(numUnused <= MAX_SIZE); - return numUnused == 0; -} - -template -T& RED4ext::GpuApi::ResourceContainer::GetData(uint32_t id) -{ - assert(IsUsedID(id)); - return resources[IDToIndex(id)].instance; -} - -template -const T& RED4ext::GpuApi::ResourceContainer::GetData(uint32_t id) const -{ - assert(IsUsedID(id)); - return resources[IDToIndex(id)].instance; -} - -RED4EXT_INLINE RED4ext::GpuApi::SDeviceData* RED4ext::GpuApi::GetDeviceData() +RED4EXT_INLINE SDeviceData* GetDeviceData() { - static UniversalRelocPtr dd(Detail::AddressHashes::g_DeviceData); + static const UniversalRelocPtr dd(Detail::AddressHashes::g_DeviceData); return dd; } +} // namespace RED4ext::GpuApi diff --git a/include/RED4ext/GpuApi/DeviceData.hpp b/include/RED4ext/GpuApi/DeviceData.hpp index f4260b3f5..5259eb07d 100644 --- a/include/RED4ext/GpuApi/DeviceData.hpp +++ b/include/RED4ext/GpuApi/DeviceData.hpp @@ -14,7 +14,7 @@ namespace GpuApi template struct ResourceContainer { - struct Resource + struct ResourceHandle { bool IsUsed() const; @@ -56,7 +56,7 @@ struct ResourceContainer SpinLock& spinLockRef; // 00 - Always points to SDeviceDataBase::resourcesSpinLock. std::atomic_int32_t numUnused; // 08 - Defaults to MaxSize. - Resource resources[MAX_SIZE]; + ResourceHandle resources[MAX_SIZE]; uint16_t unusedIndices[MAX_SIZE]; // These are indices, not IDs! }; @@ -94,6 +94,52 @@ RED4EXT_ASSERT_OFFSET(SDeviceData, directCommandQueue, 0x13bc4d0); RED4EXT_ASSERT_OFFSET(SDeviceData, memoryAllocator, 0x13bc540); SDeviceData* GetDeviceData(); + +template +bool ResourceContainer::ResourceHandle::IsUsed() const +{ + return refCount >= 0; +} + +template +bool ResourceContainer::IsUsedID(const uint32_t id) const +{ + return IsValidID(id) && resources[IDToIndex(id)].IsUsed(); +} + +template +bool ResourceContainer::IsUnusedID(const uint32_t id) const +{ + return IsValidID(id) && !resources[IDToIndex(id)].IsUsed(); +} + +template +bool ResourceContainer::IsEmpty() const +{ + assert(numUnused <= MAX_SIZE); + return numUnused == MAX_SIZE; +} + +template +bool ResourceContainer::IsFull() const +{ + assert(numUnused <= MAX_SIZE); + return numUnused == 0; +} + +template +T& ResourceContainer::GetData(uint32_t id) +{ + assert(IsUsedID(id)); + return resources[IDToIndex(id)].instance; +} + +template +const T& ResourceContainer::GetData(uint32_t id) const +{ + assert(IsUsedID(id)); + return resources[IDToIndex(id)].instance; +} } // namespace GpuApi } // namespace RED4ext diff --git a/include/RED4ext/RenderProxy-inl.hpp b/include/RED4ext/RenderProxy-inl.hpp new file mode 100644 index 000000000..cb765bdb0 --- /dev/null +++ b/include/RED4ext/RenderProxy-inl.hpp @@ -0,0 +1,167 @@ +#pragma once + +#ifdef RED4EXT_STATIC_LIB +#include +#endif + +#include +#include + +namespace RED4ext +{ +RED4EXT_INLINE void IRenderProxy::sub_00() +{ + static const UniversalRelocFunc func(Detail::AddressHashes::IRenderProxy_sub_00); + func(); +} + +RED4EXT_INLINE void IRenderProxy::sub_08() +{ + static const UniversalRelocFunc func(Detail::AddressHashes::IRenderProxy_sub_08); + func(this); +} + +RED4EXT_INLINE uint8_t IRenderProxy::sub_18() +{ + static const UniversalRelocFunc func(Detail::AddressHashes::IRenderProxy_sub_18); + return func(this); +} + +RED4EXT_INLINE void IRenderProxy::sub_20() +{ +} + +RED4EXT_INLINE void IRenderProxy::sub_28() +{ +} + +RED4EXT_INLINE void IRenderProxy::sub_30() +{ +} + +RED4EXT_INLINE bool IRenderProxy::sub_38() +{ + return false; +} + +RED4EXT_INLINE bool IRenderProxy::sub_40() +{ + return true; +} + +RED4EXT_INLINE void IRenderProxy::sub_48() +{ +} + +RED4EXT_INLINE void IRenderProxy::sub_50() +{ +} + +RED4EXT_INLINE uint32_t IRenderProxy::sub_58() +{ + static const UniversalRelocFunc func(Detail::AddressHashes::IRenderProxy_sub_58); + return func(this); +} + +RED4EXT_INLINE float IRenderProxy::sub_60() +{ + static const UniversalRelocFunc func(Detail::AddressHashes::IRenderProxy_sub_60); + return func(this); +} + +RED4EXT_INLINE uint8_t IRenderProxy::sub_68() +{ + return 0; +} + +RED4EXT_INLINE uint8_t IRenderProxy::sub_70() +{ + return 0; +} + +RED4EXT_INLINE void IRenderProxy::sub_78(void* a1) +{ + static const UniversalRelocFunc func(Detail::AddressHashes::IRenderProxy_sub_78); + func(this, a1); +} + +RED4EXT_INLINE void IRenderProxy::sub_80(void* a1, void* a2) +{ + using func_t = void (*)(IRenderProxy*, void*, void*); + static const UniversalRelocFunc func(Detail::AddressHashes::IRenderProxy_sub_80); + func(this, a1, a2); +} + +RED4EXT_INLINE bool IRenderProxy::sub_88(void* a1, void* a2) +{ + using func_t = bool (*)(IRenderProxy*, void*, void*); + static UniversalRelocFunc func(Detail::AddressHashes::IRenderProxy_sub_88); + return func(this, a1, a2); +} + +RED4EXT_INLINE void IRenderProxy::sub_90(void* a1) +{ + static const UniversalRelocFunc func(Detail::AddressHashes::IRenderProxy_sub_90); + func(this, a1); +} + +RED4EXT_INLINE void IRenderProxy::sub_98(void* a1) +{ + static const UniversalRelocFunc func(Detail::AddressHashes::IRenderProxy_sub_98); + func(this, a1); +} + +RED4EXT_INLINE void IRenderProxy::sub_A0() +{ +} + +RED4EXT_INLINE uint8_t IRenderProxy::sub_A8(void* a1) +{ + static const UniversalRelocFunc func(Detail::AddressHashes::IRenderProxy_sub_A8); + return func(this, a1); +} + +RED4EXT_INLINE void IRenderProxy::sub_B0(void* a1) +{ + static const UniversalRelocFunc func(Detail::AddressHashes::IRenderProxy_sub_B0); + func(this, a1); +} + +RED4EXT_INLINE bool IRenderProxy::sub_B8() +{ + return false; +} + +RED4EXT_INLINE bool IRenderProxy::sub_C0() +{ + return false; +} + +RED4EXT_INLINE uint8_t IRenderProxy::sub_C8() +{ + return 0; +} + +RED4EXT_INLINE uint8_t IRenderProxy::sub_D0() +{ + return 0; +} + +RED4EXT_INLINE uint8_t IRenderProxy::sub_D8() +{ + return 0; +} + +RED4EXT_INLINE uint8_t IRenderProxy::sub_E0() +{ + return 0; +} + +RED4EXT_INLINE void IRenderProxy::sub_E8() +{ +} + +RED4EXT_INLINE void IRenderProxy::sub_F0() +{ +} +} // namespace RED4ext diff --git a/include/RED4ext/RenderProxy.hpp b/include/RED4ext/RenderProxy.hpp new file mode 100644 index 000000000..16fe0f72a --- /dev/null +++ b/include/RED4ext/RenderProxy.hpp @@ -0,0 +1,83 @@ +#pragma once + +#include +#include +#include + +#include + +namespace RED4ext +{ +struct IRenderProxy +{ + virtual void sub_00(); // 00 + virtual void sub_08(); // 08 + virtual ~IRenderProxy() = default; // 10 + virtual uint8_t sub_18(); // 18 + virtual void sub_20(); // 20 + virtual void sub_28(); // 28 + virtual void sub_30(); // 30 + virtual bool sub_38(); // 38 + virtual bool sub_40(); // 40 + virtual void sub_48(); // 48 + virtual void sub_50(); // 50 + virtual uint32_t sub_58(); // 58 + virtual float sub_60(); // 60 + virtual uint8_t sub_68(); // 68 + virtual uint8_t sub_70(); // 70 + virtual void sub_78(void* a1); // 78 + virtual void sub_80(void* a1, void* a2); // 80 + virtual bool sub_88(void* a1, void* a2); // 88 + virtual void sub_90(void* a1); // 90 + virtual void sub_98(void* a1); // 98 + virtual void sub_A0(); // A0 + virtual uint8_t sub_A8(void* a1); // A8 + virtual void sub_B0(void* a1); // B0 + virtual bool sub_B8(); // B8 + virtual bool sub_C0(); // C0 + virtual uint8_t sub_C8(); // C8 + virtual uint8_t sub_D0(); // D0 + virtual uint8_t sub_D8(); // D8 + virtual uint8_t sub_E0(); // E0 + virtual void sub_E8(); // E8 + virtual void sub_F0(); // F0 + + uint8_t unk08[0x48 - 0x08]; // 08 + IRenderProxyCustomData* customData; // 48 + uint8_t unk50[0x98 - 0x50]; // 50 +}; +RED4EXT_ASSERT_SIZE(IRenderProxy, 0x98); +RED4EXT_ASSERT_OFFSET(IRenderProxy, customData, 0x48); + +struct RenderProxyBase : IRenderProxy +{ + virtual void sub_F8() = 0; // F8 +}; +RED4EXT_ASSERT_SIZE(RenderProxyBase, 0x98); + +struct CRenderProxy : RenderProxyBase +{ + uint8_t unk98[0xb8 - 0x98]; // 98 +}; +RED4EXT_ASSERT_SIZE(CRenderProxy, 0xb8); + +struct CRenderProxy_Mesh : CRenderProxy +{ + uint8_t unkB8[0xd8 - 0xb8]; // B8 + CRenderMesh* renderMesh; // D8 + uint8_t unkE0[0x1c0 - 0xe0]; // E0 +}; +RED4EXT_ASSERT_SIZE(CRenderProxy_Mesh, 0x1c0); +RED4EXT_ASSERT_OFFSET(CRenderProxy_Mesh, renderMesh, 0xD8); + +struct CRenderProxyHandle +{ + virtual ~CRenderProxyHandle() = default; // 00 + + uint8_t unk08[0x10 - 0x08]; // 08 + IRenderProxy* renderProxy; // 10 + uint8_t unk18[0x28 - 0x18]; // 18 +}; +RED4EXT_ASSERT_SIZE(CRenderProxyHandle, 0x28); +RED4EXT_ASSERT_OFFSET(CRenderProxyHandle, renderProxy, 0x10); +} // namespace RED4ext diff --git a/include/RED4ext/RenderResource.hpp b/include/RED4ext/RenderResource.hpp new file mode 100644 index 000000000..f37ba8f00 --- /dev/null +++ b/include/RED4ext/RenderResource.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include + +#include + +namespace RED4ext +{ +struct CRenderMesh +{ + uint8_t unk00[0x10 - 0x00]; // 00 + Vector4 quantizationScale; // 10 + Vector4 quantizationBias; // 20 + uint32_t vertexBufferID; // 30 - GpuApi buffer ID + uint32_t indexBufferID; // 34 + uint8_t unk38[0xa0 - 0x38]; // 38 + DynArray chunks; // A0 + uint8_t unkB0[0x158 - 0xb0]; // B0 +}; +RED4EXT_ASSERT_SIZE(CRenderMesh, 0x158); +RED4EXT_ASSERT_OFFSET(CRenderMesh, quantizationScale, 0x10); +RED4EXT_ASSERT_OFFSET(CRenderMesh, quantizationBias, 0x20); +RED4EXT_ASSERT_OFFSET(CRenderMesh, vertexBufferID, 0x30); +RED4EXT_ASSERT_OFFSET(CRenderMesh, indexBufferID, 0x34); +RED4EXT_ASSERT_OFFSET(CRenderMesh, chunks, 0xA0); + +struct CRenderMorphTargetMesh : CRenderMesh +{ + uint8_t unk158[0x160 - 0x158]; // 158 + uint32_t baseVertexBufferID; // 160 + uint8_t unk164[0x168 - 0x164]; // 164 +}; +RED4EXT_ASSERT_SIZE(CRenderMorphTargetMesh, 0x168); +RED4EXT_ASSERT_OFFSET(CRenderMorphTargetMesh, baseVertexBufferID, 0x160); +} // namespace RED4ext diff --git a/include/RED4ext/Scripting/Natives/CMesh.hpp b/include/RED4ext/Scripting/Natives/CMesh.hpp new file mode 100644 index 000000000..d8fec7ba0 --- /dev/null +++ b/include/RED4ext/Scripting/Natives/CMesh.hpp @@ -0,0 +1,68 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace RED4ext +{ +struct CMaterialInstance; +struct CResource; +struct IMaterial; +struct IRenderResourceBlob; +namespace mesh +{ +struct MeshAppearance; +struct MeshParameter; +} // namespace mesh + +struct __declspec(align(0x10)) CMesh : res::StreamedResource +{ + static constexpr const char* NAME = "CMesh"; + static constexpr const char* ALIAS = NAME; + + Box boundingBox; // 40 + Vector3 surfaceAreaPerAxis; // 60 + bool constrainAutoHideDistanceToTerrainHeightMap; // 6C + bool forceLoadAllAppearances; // 6D + bool castGlobalShadowsCachedInCook; // 6E + bool castLocalShadowsCachedInCook; // 6F + DynArray> parameters; // 70 + DynArray boneNames; // 80 + DynArray boneRigMatrices; // 90 + DynArray boneVertexEpsilons; // A0 + DynArray lodBoneMask; // B0 + DynArray floatTrackNames; // C0 + DynArray lodLevelInfo; // D0 + DynArray materialEntries; // E0 + DynArray> externalMaterials; // F0 + DynArray> localMaterialInstances; // 100 + mesh::MeshMaterialBuffer localMaterialBuffer; // 110 + DynArray> preloadExternalMaterials; // 1B0 + DynArray> preloadLocalMaterialInstances; // 1C0 + DynArray> inplaceResources; // 1D0 + DynArray> appearances; // 1E0 + CRenderMesh* renderResource; // 1F0 + Handle renderResourceBlob; // 1F8 + bool useRayTracingShadowLODBias; // 208 + bool castsRayTracedShadowsFromOriginalGeometry; // 209 + bool isShadowMesh; // 20A + bool isPlayerShadowMesh; // 20B + uint8_t unk20C[0x219 - 0x20C]; // 20C + ERenderObjectType objectType; // 219 + uint8_t unk21A[0x230 - 0x21A]; // 21A +}; +RED4EXT_ASSERT_SIZE(CMesh, 0x230); +} // namespace RED4ext diff --git a/include/RED4ext/Scripting/Natives/Generated/CMesh.hpp b/include/RED4ext/Scripting/Natives/Generated/CMesh.hpp index 897212140..165086c63 100644 --- a/include/RED4ext/Scripting/Natives/Generated/CMesh.hpp +++ b/include/RED4ext/Scripting/Natives/Generated/CMesh.hpp @@ -4,6 +4,14 @@ // This file is generated from the Game's Reflection data +#include + +namespace RED4ext +{ +RED4EXT_ASSERT_SIZE(CMesh, 0x230); +} // namespace RED4ext + +/* #include #include #include @@ -65,5 +73,6 @@ struct __declspec(align(0x10)) CMesh : res::StreamedResource }; RED4EXT_ASSERT_SIZE(CMesh, 0x230); } // namespace RED4ext +*/ // clang-format on diff --git a/include/RED4ext/Scripting/Natives/Generated/MorphTargetMesh.hpp b/include/RED4ext/Scripting/Natives/Generated/MorphTargetMesh.hpp index d6ed7f0f5..8ddf23ac9 100644 --- a/include/RED4ext/Scripting/Natives/Generated/MorphTargetMesh.hpp +++ b/include/RED4ext/Scripting/Natives/Generated/MorphTargetMesh.hpp @@ -4,6 +4,14 @@ // This file is generated from the Game's Reflection data +#include + +namespace RED4ext +{ +RED4EXT_ASSERT_SIZE(MorphTargetMesh, 0xD0); +} // namespace RED4ext + +/* #include #include #include @@ -36,5 +44,6 @@ struct __declspec(align(0x10)) MorphTargetMesh : res::StreamedResource }; RED4EXT_ASSERT_SIZE(MorphTargetMesh, 0xD0); } // namespace RED4ext +*/ // clang-format on diff --git a/include/RED4ext/Scripting/Natives/Generated/ent/MorphTargetSkinnedMeshComponent.hpp b/include/RED4ext/Scripting/Natives/Generated/ent/MorphTargetSkinnedMeshComponent.hpp index 995ee27a0..fd8ed4971 100644 --- a/include/RED4ext/Scripting/Natives/Generated/ent/MorphTargetSkinnedMeshComponent.hpp +++ b/include/RED4ext/Scripting/Natives/Generated/ent/MorphTargetSkinnedMeshComponent.hpp @@ -4,6 +4,15 @@ // This file is generated from the Game's Reflection data +#include + +namespace RED4ext +{ +RED4EXT_ASSERT_SIZE(ent::MorphTargetSkinnedMeshComponent, 0x370); +using entMorphTargetSkinnedMeshComponent = ent::MorphTargetSkinnedMeshComponent; +} // namespace RED4ext + +/* #include #include #include @@ -45,5 +54,6 @@ RED4EXT_ASSERT_SIZE(MorphTargetSkinnedMeshComponent, 0x370); } // namespace ent using entMorphTargetSkinnedMeshComponent = ent::MorphTargetSkinnedMeshComponent; } // namespace RED4ext +*/ // clang-format on diff --git a/include/RED4ext/Scripting/Natives/Generated/ent/SkinnedMeshComponent.hpp b/include/RED4ext/Scripting/Natives/Generated/ent/SkinnedMeshComponent.hpp index edec111c6..5b740f4c6 100644 --- a/include/RED4ext/Scripting/Natives/Generated/ent/SkinnedMeshComponent.hpp +++ b/include/RED4ext/Scripting/Natives/Generated/ent/SkinnedMeshComponent.hpp @@ -4,6 +4,15 @@ // This file is generated from the Game's Reflection data +#include + +namespace RED4ext +{ +RED4EXT_ASSERT_SIZE(ent::SkinnedMeshComponent, 0x270); +using entSkinnedMeshComponent = ent::SkinnedMeshComponent; +} // namespace RED4ext + +/* #include #include #include @@ -50,5 +59,6 @@ RED4EXT_ASSERT_SIZE(SkinnedMeshComponent, 0x270); } // namespace ent using entSkinnedMeshComponent = ent::SkinnedMeshComponent; } // namespace RED4ext +*/ // clang-format on diff --git a/include/RED4ext/Scripting/Natives/MorphTargetMesh.hpp b/include/RED4ext/Scripting/Natives/MorphTargetMesh.hpp new file mode 100644 index 000000000..89153a8b6 --- /dev/null +++ b/include/RED4ext/Scripting/Natives/MorphTargetMesh.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace RED4ext +{ +struct CMesh; +struct IRenderResourceBlob; +struct ITexture; + +struct __declspec(align(0x10)) MorphTargetMesh : res::StreamedResource +{ + static constexpr const char* NAME = "MorphTargetMesh"; + static constexpr const char* ALIAS = NAME; + + Box boundingBox; // 40 + Ref baseMesh; // 60 + CName baseTextureParamName; // 78 + Ref baseTexture; // 80 + CName baseMeshAppearance; // 98 + Handle blob; // A0 + DynArray targets; // B0 + CRenderMorphTargetMesh* renderResource; // C0 + uint8_t unkC8[0xD0 - 0xC8]; // C8 +}; +RED4EXT_ASSERT_SIZE(MorphTargetMesh, 0xD0); +} // namespace RED4ext diff --git a/include/RED4ext/Scripting/Natives/Vector2.hpp b/include/RED4ext/Scripting/Natives/Vector2.hpp index 0b9f414d5..18fa95fbc 100644 --- a/include/RED4ext/Scripting/Natives/Vector2.hpp +++ b/include/RED4ext/Scripting/Natives/Vector2.hpp @@ -1,6 +1,7 @@ #pragma once #include + #include namespace RED4ext diff --git a/include/RED4ext/Scripting/Natives/Vector3.hpp b/include/RED4ext/Scripting/Natives/Vector3.hpp index 891cc0be0..a3c9580c5 100644 --- a/include/RED4ext/Scripting/Natives/Vector3.hpp +++ b/include/RED4ext/Scripting/Natives/Vector3.hpp @@ -1,6 +1,7 @@ #pragma once #include + #include namespace RED4ext diff --git a/include/RED4ext/Scripting/Natives/Vector4.hpp b/include/RED4ext/Scripting/Natives/Vector4.hpp index 2672a1bbe..53af6ab45 100644 --- a/include/RED4ext/Scripting/Natives/Vector4.hpp +++ b/include/RED4ext/Scripting/Natives/Vector4.hpp @@ -1,6 +1,8 @@ #pragma once #include + +#include #include namespace RED4ext @@ -28,7 +30,7 @@ struct Vector4 inline Vector4& operator=(const Vector4& aOther) { - if (this != std::addressof(aOther)) + if (this != &aOther) { X = aOther.X; Y = aOther.Y; diff --git a/include/RED4ext/Scripting/Natives/entMorphTargetSkinnedMeshComponent.hpp b/include/RED4ext/Scripting/Natives/entMorphTargetSkinnedMeshComponent.hpp new file mode 100644 index 000000000..7a5adeb5d --- /dev/null +++ b/include/RED4ext/Scripting/Natives/entMorphTargetSkinnedMeshComponent.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace RED4ext +{ +struct MorphTargetMesh; + +namespace ent +{ +struct __declspec(align(0x10)) MorphTargetSkinnedMeshComponent : ent::ISkinTargetComponent +{ + static constexpr const char* NAME = "entMorphTargetSkinnedMeshComponent"; + static constexpr const char* ALIAS = NAME; + + uint8_t unk1E0[0x1E8 - 0x1E0]; // 1E0 + SharedPtr renderProxy; // 1E8 + uint8_t unk1F0[0x200 - 0x1F8]; // 1F8 + RaRef morphResource; // 200 + Handle meshHandle; // 208 + uint8_t unk208[0x238 - 0x218]; // 218 + CName meshAppearance; // 238 + uint64_t chunkMask; // 240 + uint8_t unk248[0x2E8 - 0x248]; // 248 + CName renderingPlaneAnimationParam; // 2E8 + CName visibilityAnimationParam; // 2F0 + uint8_t unk2F8[0x308 - 0x2F8]; // 2F8 + red::TagList tags; // 308 + uint8_t unk318[0x35C - 0x318]; // 318 + shadows::ShadowCastingMode castShadows; // 35C + shadows::ShadowCastingMode castLocalShadows; // 35D + bool acceptDismemberment; // 35E + uint8_t unk35F[0x361 - 0x35F]; // 35F + uint8_t version; // 361 + uint8_t unk362[0x370 - 0x362]; // 362 +}; +RED4EXT_ASSERT_SIZE(MorphTargetSkinnedMeshComponent, 0x370); +} // namespace ent +} // namespace RED4ext diff --git a/include/RED4ext/Scripting/Natives/entSkinnedMeshComponent.hpp b/include/RED4ext/Scripting/Natives/entSkinnedMeshComponent.hpp new file mode 100644 index 000000000..50030530f --- /dev/null +++ b/include/RED4ext/Scripting/Natives/entSkinnedMeshComponent.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace RED4ext +{ +namespace ent +{ +struct __declspec(align(0x10)) SkinnedMeshComponent : ent::ISkinTargetComponent +{ + static constexpr const char* NAME = "entSkinnedMeshComponent"; + static constexpr const char* ALIAS = NAME; + + SharedPtr renderProxy; // 1E0 + Handle appearanceHandle; // 1F0 + Handle meshHandle; // 200 + uint8_t unk1F0[0x228 - 0x210]; // 210 + RaRef mesh; // 228 + CName meshAppearance; // 230 + CName renderingPlaneAnimationParam; // 238 + CName visibilityAnimationParam; // 240 + uint64_t chunkMask; // 248 + NavGenNavigationSetting navigationImpact; // 250 + ent::MeshComponentLODMode LODMode; // 252 + uint8_t unk253[0x255 - 0x253]; // 253 + uint8_t order; // 255 + shadows::ShadowCastingMode castShadows; // 256 + shadows::ShadowCastingMode castLocalShadows; // 257 + bool useProxyMeshAsShadowMesh; // 258 + bool acceptDismemberment; // 259 + bool overrideMeshNavigationImpact; // 25A + uint8_t unk25B[0x25D - 0x25B]; // 25B + ent::ForcedLodDistance forcedLodDistance; // 25D + uint8_t unk25E[0x268 - 0x25E]; // 25E + uint8_t version; // 268 + uint8_t unk269[0x270 - 0x269]; // 269 +}; +RED4EXT_ASSERT_SIZE(SkinnedMeshComponent, 0x270); +} // namespace ent +} // namespace RED4ext diff --git a/src/RenderProxy.cpp b/src/RenderProxy.cpp new file mode 100644 index 000000000..39ed20746 --- /dev/null +++ b/src/RenderProxy.cpp @@ -0,0 +1,5 @@ +#ifndef RED4EXT_STATIC_LIB +#error Please define 'RED4EXT_STATIC_LIB' to compile this file. +#endif + +#include