From aba5cbf768e676232cd196f5d0161e43be146b9e Mon Sep 17 00:00:00 2001 From: nashmuhandes Date: Thu, 30 Jan 2025 20:44:14 +0800 Subject: [PATCH] Revert "fix for vkdoom" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 5eb9a1095ee8787bfe92bacb4a0132d3ce141dc5. Revert "upload bones 😅" This reverts commit cc766311f784aa2a11f4856cdd276179d99a5ad5. Revert "remove bone component cache to decrease memory consumption" This reverts commit e2908ce0a346756fe1a551caf28d9e3b9518cd2b. --- src/common/models/bonecomponents.h | 11 ++++ src/common/models/model.h | 6 +- src/common/models/model_iqm.h | 12 ++-- src/common/models/model_kvx.h | 2 +- src/common/models/model_md2.h | 2 +- src/common/models/model_md3.h | 2 +- src/common/models/model_obj.h | 2 +- src/common/models/model_ue1.h | 2 +- src/common/models/modelrenderer.h | 3 +- src/common/models/models_iqm.cpp | 81 +++++++++++++++++--------- src/common/models/models_md2.cpp | 4 +- src/common/models/models_md3.cpp | 5 +- src/common/models/models_obj.cpp | 5 +- src/common/models/models_ue1.cpp | 4 +- src/common/models/models_voxel.cpp | 4 +- src/playsim/actor.h | 1 + src/playsim/p_actionfunctions.cpp | 2 +- src/playsim/p_mobj.cpp | 1 + src/r_data/models.cpp | 30 +++++----- src/rendering/hwrenderer/hw_models.cpp | 11 ++-- src/rendering/hwrenderer/hw_models.h | 3 +- 21 files changed, 113 insertions(+), 80 deletions(-) diff --git a/src/common/models/bonecomponents.h b/src/common/models/bonecomponents.h index f4f221f3ba..313b0832ee 100644 --- a/src/common/models/bonecomponents.h +++ b/src/common/models/bonecomponents.h @@ -6,6 +6,17 @@ #include + +class DBoneComponents : public DObject +{ + DECLARE_CLASS(DBoneComponents, DObject); +public: + TArray> trscomponents; + TArray> trsmatrix; + + DBoneComponents() = default; +}; + struct ModelAnimFrameInterp { float inter = -1.0f; diff --git a/src/common/models/model.h b/src/common/models/model.h index c9eacb8dc0..ac1d5c3c05 100644 --- a/src/common/models/model.h +++ b/src/common/models/model.h @@ -91,15 +91,15 @@ class FModel virtual int FindLastFrame(FName name) { return FErr_NotFound; } virtual double FindFramerate(FName name) { return FErr_NotFound; } - virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition, void * act) = 0; + virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, const TArray& boneData, int boneStartPosition, void * act) = 0; virtual void BuildVertexBuffer(FModelRenderer *renderer) = 0; virtual void AddSkins(uint8_t *hitlist, const FTextureID* surfaceskinids) = 0; virtual float getAspectFactor(float vscale) { return 1.f; } virtual const TArray* AttachAnimationData() { return nullptr; }; - virtual ModelAnimFrame PrecalculateFrame(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray* animationData) { return nullptr; }; + virtual ModelAnimFrame PrecalculateFrame(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray* animationData, DBoneComponents* bones, int index) { return nullptr; }; - virtual const TArray* CalculateBones(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray* animationData) { return nullptr; }; + virtual const TArray CalculateBones(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray* animationData, DBoneComponents* bones, int index) { return {}; }; void SetVertexBuffer(int type, IModelVertexBuffer *buffer) { mVBuf[type] = buffer; } IModelVertexBuffer *GetVertexBuffer(int type) const { return mVBuf[type]; } diff --git a/src/common/models/model_iqm.h b/src/common/models/model_iqm.h index 5de5651994..5329a2030b 100644 --- a/src/common/models/model_iqm.h +++ b/src/common/models/model_iqm.h @@ -116,16 +116,16 @@ class IQMModel : public FModel int FindFirstFrame(FName name) override; int FindLastFrame(FName name) override; double FindFramerate(FName name) override; - void RenderFrame(FModelRenderer* renderer, FGameTexture* skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition, void * act) override; + void RenderFrame(FModelRenderer* renderer, FGameTexture* skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, const TArray& boneData, int boneStartPosition, void * act) override; void BuildVertexBuffer(FModelRenderer* renderer) override; void AddSkins(uint8_t* hitlist, const FTextureID* surfaceskinids) override; const TArray* AttachAnimationData() override; - ModelAnimFrame PrecalculateFrame(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray* animationData) override; - const TArray* CalculateBones(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray* animationData) override; + ModelAnimFrame PrecalculateFrame(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray* animationData, DBoneComponents* bones, int index) override; + const TArray CalculateBones(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray* animationData, DBoneComponents* bones, int index) override; - ModelAnimFramePrecalculatedIQM CalculateFrameIQM(int frame1, int frame2, float inter, int frame1_prev, float inter1_prev, int frame2_prev, float inter2_prev, const ModelAnimFramePrecalculatedIQM* precalculated, const TArray* animationData); - const TArray* CalculateBonesIQM(int frame1, int frame2, float inter, int frame1_prev, float inter1_prev, int frame2_prev, float inter2_prev, const ModelAnimFramePrecalculatedIQM* precalculated, const TArray* animationData); + ModelAnimFramePrecalculatedIQM CalculateFrameIQM(int frame1, int frame2, float inter, int frame1_prev, float inter1_prev, int frame2_prev, float inter2_prev, const ModelAnimFramePrecalculatedIQM* precalculated, const TArray* animationData, DBoneComponents* bones, int index); + const TArray CalculateBonesIQM(int frame1, int frame2, float inter, int frame1_prev, float inter1_prev, int frame2_prev, float inter2_prev, const ModelAnimFramePrecalculatedIQM* precalculated, const TArray* animationData, DBoneComponents* bones, int index); private: void LoadGeometry(); @@ -151,8 +151,6 @@ class IQMModel : public FModel TArray VertexArrays; uint32_t NumVertices = 0; - TArray boneData; // temporary array, used to hold animation data during rendering, set during CalculateBones, uploaded during RenderFrame - TArray Vertices; TArray baseframe; diff --git a/src/common/models/model_kvx.h b/src/common/models/model_kvx.h index 8c160e3942..faebca5025 100644 --- a/src/common/models/model_kvx.h +++ b/src/common/models/model_kvx.h @@ -59,7 +59,7 @@ class FVoxelModel : public FModel bool Load(const char * fn, int lumpnum, const char * buffer, int length) override; void Initialize(); virtual int FindFrame(const char* name, bool nodefault) override; - virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition, void * act) override; + virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, const TArray& boneData, int boneStartPosition, void * act) override; virtual void AddSkins(uint8_t *hitlist, const FTextureID* surfaceskinids) override; FTextureID GetPaletteTexture() const { return mPalette; } void BuildVertexBuffer(FModelRenderer *renderer) override; diff --git a/src/common/models/model_md2.h b/src/common/models/model_md2.h index 7b56ca1ea6..4cd20f5bbb 100644 --- a/src/common/models/model_md2.h +++ b/src/common/models/model_md2.h @@ -113,7 +113,7 @@ class FDMDModel : public FModel virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length) override; virtual int FindFrame(const char* name, bool nodefault) override; - virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition, void * act) override; + virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, const TArray& boneData, int boneStartPosition, void * act) override; virtual void LoadGeometry(); virtual void AddSkins(uint8_t *hitlist, const FTextureID* surfaceskinids) override; diff --git a/src/common/models/model_md3.h b/src/common/models/model_md3.h index 68c776616f..a4877ddb45 100644 --- a/src/common/models/model_md3.h +++ b/src/common/models/model_md3.h @@ -67,7 +67,7 @@ class FMD3Model : public FModel virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length) override; virtual int FindFrame(const char* name, bool nodefault) override; - virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition, void * act) override; + virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, const TArray& boneData, int boneStartPosition, void * act) override; void LoadGeometry(); void BuildVertexBuffer(FModelRenderer *renderer); virtual void AddSkins(uint8_t *hitlist, const FTextureID* surfaceskinids) override; diff --git a/src/common/models/model_obj.h b/src/common/models/model_obj.h index 78b2206bdd..400f6897e4 100644 --- a/src/common/models/model_obj.h +++ b/src/common/models/model_obj.h @@ -98,7 +98,7 @@ class FOBJModel : public FModel ~FOBJModel(); bool Load(const char* fn, int lumpnum, const char* buffer, int length) override; int FindFrame(const char* name, bool nodefault) override; - void RenderFrame(FModelRenderer* renderer, FGameTexture* skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition, void * act) override; + void RenderFrame(FModelRenderer* renderer, FGameTexture* skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, const TArray& boneData, int boneStartPosition, void * act) override; void BuildVertexBuffer(FModelRenderer* renderer) override; void AddSkins(uint8_t* hitlist, const FTextureID* surfaceskinids) override; }; diff --git a/src/common/models/model_ue1.h b/src/common/models/model_ue1.h index 2e30435e28..f862463c67 100644 --- a/src/common/models/model_ue1.h +++ b/src/common/models/model_ue1.h @@ -26,7 +26,7 @@ class FUE1Model : public FModel bool Load(const char * fn, int lumpnum, const char * buffer, int length) override; int FindFrame(const char* name, bool nodefault) override; - void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition, void * act) override; + void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, const TArray& boneData, int boneStartPosition, void * act) override; void BuildVertexBuffer(FModelRenderer *renderer) override; void AddSkins(uint8_t *hitlist, const FTextureID* surfaceskinids) override; void LoadGeometry(); diff --git a/src/common/models/modelrenderer.h b/src/common/models/modelrenderer.h index 538712f264..f93c1279b8 100644 --- a/src/common/models/modelrenderer.h +++ b/src/common/models/modelrenderer.h @@ -24,7 +24,6 @@ class FModelRenderer virtual void SetMaterial(FGameTexture *skin, bool clampNoFilter, FTranslationID translation, void * act) = 0; virtual void DrawArrays(int start, int count) = 0; virtual void DrawElements(int numIndices, size_t offset) = 0; - virtual void SetupFrame(FModel* model, unsigned int frame1, unsigned int frame2, unsigned int size, int boneStartIndex) {}; - virtual int UploadBones(const TArray& bones) = 0; + virtual int SetupFrame(FModel* model, unsigned int frame1, unsigned int frame2, unsigned int size, const TArray& bones, int boneStartIndex) { return -1; }; }; diff --git a/src/common/models/models_iqm.cpp b/src/common/models/models_iqm.cpp index 5fac867a9b..9d57d1c183 100644 --- a/src/common/models/models_iqm.cpp +++ b/src/common/models/models_iqm.cpp @@ -7,7 +7,9 @@ #include "engineerrors.h" #include "dobject.h" #include "bonecomponents.h" -#include "v_video.h" + +IMPLEMENT_CLASS(DBoneComponents, false, false); + IQMModel::IQMModel() { @@ -467,10 +469,9 @@ double IQMModel::FindFramerate(FName name) return FErr_NotFound; } -void IQMModel::RenderFrame(FModelRenderer* renderer, FGameTexture* skin, int frame1, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition, void * act) +void IQMModel::RenderFrame(FModelRenderer* renderer, FGameTexture* skin, int frame1, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, const TArray& boneData, int boneStartPosition, void * act) { - - renderer->SetupFrame(this, 0, 0, NumVertices, boneStartPosition >= 0 ? boneStartPosition : renderer->UploadBones(boneData)); + renderer->SetupFrame(this, 0, 0, NumVertices, boneData, boneStartPosition); FGameTexture* lastSkin = nullptr; for (unsigned i = 0; i < Meshes.Size(); i++) @@ -562,51 +563,51 @@ static TRS InterpolateBone(const TRS &from, const TRS &to, float t, float invt) #include "printf.h" -ModelAnimFrame IQMModel::PrecalculateFrame(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray* animationData) +ModelAnimFrame IQMModel::PrecalculateFrame(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray* animationData, DBoneComponents* bones, int index) { if(inter <= 0) { - return CalculateFrameIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, animationData); + return CalculateFrameIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, animationData, bones, index); } else if(std::holds_alternative(from)) { auto &from_interp = std::get(from); - return CalculateFrameIQM(from_interp.frame2, to.frame2, inter, from_interp.frame1, from_interp.inter, to.frame1, to.inter, nullptr, animationData); + return CalculateFrameIQM(from_interp.frame2, to.frame2, inter, from_interp.frame1, from_interp.inter, to.frame1, to.inter, nullptr, animationData, bones, index); } else if(std::holds_alternative(from)) { - return CalculateFrameIQM(0, to.frame2, inter, 0, -1.f, to.frame1, to.inter, &std::get(from), animationData); + return CalculateFrameIQM(0, to.frame2, inter, 0, -1.f, to.frame1, to.inter, &std::get(from), animationData, bones, index); } else { - return CalculateFrameIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, animationData); + return CalculateFrameIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, animationData, bones, index); } } -const TArray* IQMModel::CalculateBones(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray* animationData) +const TArray IQMModel::CalculateBones(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray* animationData, DBoneComponents* bones, int index) { if(inter <= 0) { - return CalculateBonesIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, animationData); + return CalculateBonesIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, animationData, bones, index); } else if(std::holds_alternative(from)) { auto &from_interp = std::get(from); - return CalculateBonesIQM(from_interp.frame2, to.frame2, inter, from_interp.frame1, from_interp.inter, to.frame1, to.inter, nullptr, animationData); + return CalculateBonesIQM(from_interp.frame2, to.frame2, inter, from_interp.frame1, from_interp.inter, to.frame1, to.inter, nullptr, animationData, bones, index); } else if(std::holds_alternative(from)) { - return CalculateBonesIQM(0, to.frame2, inter, 0, -1.f, to.frame1, to.inter, &std::get(from), animationData); + return CalculateBonesIQM(0, to.frame2, inter, 0, -1.f, to.frame1, to.inter, &std::get(from), animationData, bones, index); } else { - return CalculateBonesIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, animationData); + return CalculateBonesIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, animationData, bones, index); } } -ModelAnimFramePrecalculatedIQM IQMModel::CalculateFrameIQM(int frame1, int frame2, float inter, int frame1_prev, float inter1_prev, int frame2_prev, float inter2_prev, const ModelAnimFramePrecalculatedIQM* precalculated, const TArray* animationData) +ModelAnimFramePrecalculatedIQM IQMModel::CalculateFrameIQM(int frame1, int frame2, float inter, int frame1_prev, float inter1_prev, int frame2_prev, float inter2_prev, const ModelAnimFramePrecalculatedIQM* precalculated, const TArray* animationData, DBoneComponents* boneComponentData, int index) { ModelAnimFramePrecalculatedIQM out; const TArray& animationFrames = animationData ? *animationData : TRSData; @@ -660,13 +661,18 @@ ModelAnimFramePrecalculatedIQM IQMModel::CalculateFrameIQM(int frame1, int frame return out; } -const TArray* IQMModel::CalculateBonesIQM(int frame1, int frame2, float inter, int frame1_prev, float inter1_prev, int frame2_prev, float inter2_prev, const ModelAnimFramePrecalculatedIQM* precalculated, const TArray* animationData) +const TArray IQMModel::CalculateBonesIQM(int frame1, int frame2, float inter, int frame1_prev, float inter1_prev, int frame2_prev, float inter2_prev, const ModelAnimFramePrecalculatedIQM* precalculated, const TArray* animationData, DBoneComponents* boneComponentData, int index) { const TArray& animationFrames = animationData ? *animationData : TRSData; if (Joints.Size() > 0) { int numbones = Joints.SSize(); + if (boneComponentData->trscomponents[index].SSize() != numbones) + boneComponentData->trscomponents[index].Resize(numbones); + if (boneComponentData->trsmatrix[index].SSize() != numbones) + boneComponentData->trsmatrix[index].Resize(numbones); + frame1 = clamp(frame1, 0, (animationFrames.SSize() - 1) / numbones); frame2 = clamp(frame2, 0, (animationFrames.SSize() - 1) / numbones); @@ -680,16 +686,14 @@ const TArray* IQMModel::CalculateBonesIQM(int frame1, int frame2, floa float invt1 = 1.0f - inter1_prev; float invt2 = 1.0f - inter2_prev; - constexpr const float swapYZ[16] - { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - }; - - boneData.Resize(numbones); + float swapYZ[16] = { 0.0f }; + swapYZ[0 + 0 * 4] = 1.0f; + swapYZ[1 + 2 * 4] = 1.0f; + swapYZ[2 + 1 * 4] = 1.0f; + swapYZ[3 + 3 * 4] = 1.0f; + TArray bones(numbones, true); + TArray modifiedBone(numbones, true); for (int i = 0; i < numbones; i++) { TRS prev; @@ -720,16 +724,33 @@ const TArray* IQMModel::CalculateBonesIQM(int frame1, int frame2, floa bone = inter < 0 ? animationFrames[offset1 + i] : InterpolateBone(prev, next , inter, invt); } + if (Joints[i].Parent >= 0 && modifiedBone[Joints[i].Parent]) + { + boneComponentData->trscomponents[index][i] = bone; + modifiedBone[i] = true; + } + else if (boneComponentData->trscomponents[index][i].Equals(bone)) + { + bones[i] = boneComponentData->trsmatrix[index][i]; + modifiedBone[i] = false; + continue; + } + else + { + boneComponentData->trscomponents[index][i] = bone; + modifiedBone[i] = true; + } + VSMatrix m; m.loadIdentity(); m.translate(bone.translation.X, bone.translation.Y, bone.translation.Z); m.multQuaternion(bone.rotation); m.scale(bone.scaling.X, bone.scaling.Y, bone.scaling.Z); - VSMatrix& result = boneData[i]; + VSMatrix& result = bones[i]; if (Joints[i].Parent >= 0) { - result = boneData[Joints[i].Parent]; + result = bones[Joints[i].Parent]; result.multMatrix(swapYZ); result.multMatrix(baseframe[Joints[i].Parent]); result.multMatrix(m); @@ -744,7 +765,9 @@ const TArray* IQMModel::CalculateBonesIQM(int frame1, int frame2, floa result.multMatrix(swapYZ); } - return &boneData; + boneComponentData->trsmatrix[index] = bones; + + return bones; } - return nullptr; + return {}; } diff --git a/src/common/models/models_md2.cpp b/src/common/models/models_md2.cpp index fb0b3909a4..c9565afc47 100644 --- a/src/common/models/models_md2.cpp +++ b/src/common/models/models_md2.cpp @@ -364,7 +364,7 @@ int FDMDModel::FindFrame(const char* name, bool nodefault) // //=========================================================================== -void FDMDModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frameno, int frameno2, double inter, FTranslationID translation, const FTextureID*, int boneStartPosition, void * act) +void FDMDModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frameno, int frameno2, double inter, FTranslationID translation, const FTextureID*, const TArray& boneData, int boneStartPosition, void * act) { if (frameno >= info.numFrames || frameno2 >= info.numFrames) return; @@ -377,7 +377,7 @@ void FDMDModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int f renderer->SetInterpolation(inter); renderer->SetMaterial(skin, false, translation, act); - renderer->SetupFrame(this, frames[frameno].vindex, frames[frameno2].vindex, lodInfo[0].numTriangles * 3, -1); + renderer->SetupFrame(this, frames[frameno].vindex, frames[frameno2].vindex, lodInfo[0].numTriangles * 3, {}, -1); renderer->DrawArrays(0, lodInfo[0].numTriangles * 3); renderer->SetInterpolation(0.f); } diff --git a/src/common/models/models_md3.cpp b/src/common/models/models_md3.cpp index b07fe976c2..1c2097f22b 100644 --- a/src/common/models/models_md3.cpp +++ b/src/common/models/models_md3.cpp @@ -345,7 +345,7 @@ int FMD3Model::FindFrame(const char* name, bool nodefault) // //=========================================================================== -void FMD3Model::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frameno, int frameno2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition, void * act) +void FMD3Model::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frameno, int frameno2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, const TArray& boneData, int boneStartPosition, void * act) { if ((unsigned)frameno >= Frames.Size() || (unsigned)frameno2 >= Frames.Size()) return; @@ -373,8 +373,9 @@ void FMD3Model::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int f continue; } } + renderer->SetMaterial(surfaceSkin, false, translation, act); - renderer->SetupFrame(this, surf->vindex + frameno * surf->numVertices, surf->vindex + frameno2 * surf->numVertices, surf->numVertices, -1); + renderer->SetupFrame(this, surf->vindex + frameno * surf->numVertices, surf->vindex + frameno2 * surf->numVertices, surf->numVertices, {}, -1); renderer->DrawElements(surf->numTriangles * 3, surf->iindex * sizeof(unsigned int)); } renderer->SetInterpolation(0.f); diff --git a/src/common/models/models_obj.cpp b/src/common/models/models_obj.cpp index c84357a61d..1afa81cc24 100644 --- a/src/common/models/models_obj.cpp +++ b/src/common/models/models_obj.cpp @@ -630,7 +630,7 @@ int FOBJModel::FindFrame(const char* name, bool nodefault) * @param inter The amount to interpolate the two frames. * @param translation The translation for the skin */ -void FOBJModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frameno, int frameno2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition, void * act) +void FOBJModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frameno, int frameno2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, const TArray& boneData, int boneStartPosition, void * act) { // Prevent the model from rendering if the frame number is < 0 if (frameno < 0 || frameno2 < 0) return; @@ -657,8 +657,9 @@ void FOBJModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int f { continue; } + renderer->SetMaterial(userSkin, false, translation, act); - renderer->SetupFrame(this, surf->vbStart, surf->vbStart, surf->numTris * 3, -1); + renderer->SetupFrame(this, surf->vbStart, surf->vbStart, surf->numTris * 3, {}, -1); renderer->DrawArrays(0, surf->numTris * 3); } } diff --git a/src/common/models/models_ue1.cpp b/src/common/models/models_ue1.cpp index d32105a4d0..a03763d5bf 100644 --- a/src/common/models/models_ue1.cpp +++ b/src/common/models/models_ue1.cpp @@ -232,7 +232,7 @@ int FUE1Model::FindFrame(const char* name, bool nodefault) return index; } -void FUE1Model::RenderFrame( FModelRenderer *renderer, FGameTexture *skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition, void * act) +void FUE1Model::RenderFrame( FModelRenderer *renderer, FGameTexture *skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, const TArray& boneData, int boneStartPosition, void * act) { // the moment of magic if ( (frame < 0) || (frame2 < 0) || (frame >= numFrames) || (frame2 >= numFrames) ) return; @@ -263,7 +263,7 @@ void FUE1Model::RenderFrame( FModelRenderer *renderer, FGameTexture *skin, int f // TODO: Handle per-group render styles and other flags once functions for it are implemented // Future note: poly renderstyles should always be enforced unless the actor itself has a style other than Normal renderer->SetMaterial(sskin, false, translation, act); - renderer->SetupFrame(this, vofs + frame * fsize, vofs + frame2 * fsize, vsize, -1); + renderer->SetupFrame(this, vofs + frame * fsize, vofs + frame2 * fsize, vsize, {}, -1); renderer->DrawArrays(0,vsize); vofs += vsize; } diff --git a/src/common/models/models_voxel.cpp b/src/common/models/models_voxel.cpp index a04a76d5e7..61504e9765 100644 --- a/src/common/models/models_voxel.cpp +++ b/src/common/models/models_voxel.cpp @@ -400,9 +400,9 @@ float FVoxelModel::getAspectFactor(float stretch) // //=========================================================================== -void FVoxelModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID*, int boneStartPosition, void * act) +void FVoxelModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID*, const TArray& boneData, int boneStartPosition, void * act) { renderer->SetMaterial(skin, true, translation, act); - renderer->SetupFrame(this, 0, 0, 0, -1); + renderer->SetupFrame(this, 0, 0, 0, {}, -1); renderer->DrawElements(mNumIndices, 0); } diff --git a/src/playsim/actor.h b/src/playsim/actor.h index 7969aeea69..e9b3b7c7a5 100644 --- a/src/playsim/actor.h +++ b/src/playsim/actor.h @@ -1156,6 +1156,7 @@ class AActor final : public DThinker double Speed; double FloatSpeed; TObjPtr modelData; + TObjPtr boneComponentData; // interaction info FBlockNode *BlockNode; // links in blocks (if needed) diff --git a/src/playsim/p_actionfunctions.cpp b/src/playsim/p_actionfunctions.cpp index 1f18209bbc..8d50993d90 100644 --- a/src/playsim/p_actionfunctions.cpp +++ b/src/playsim/p_actionfunctions.cpp @@ -5209,7 +5209,7 @@ void SetAnimationInternal(AActor * self, FName animName, double framerate, int s animationData = animation->AttachAnimationData(); } - self->modelData->prevAnim = animation->PrecalculateFrame(self->modelData->prevAnim, to, inter, animationData); + self->modelData->prevAnim = animation->PrecalculateFrame(self->modelData->prevAnim, to, inter, animationData, self->boneComponentData, 0); } else { diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index 8b44e59400..67eb477156 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -178,6 +178,7 @@ IMPLEMENT_POINTERS_START(AActor) IMPLEMENT_POINTER(alternative) IMPLEMENT_POINTER(ViewPos) IMPLEMENT_POINTER(modelData) + IMPLEMENT_POINTER(boneComponentData) IMPLEMENT_POINTERS_END //========================================================================== diff --git a/src/r_data/models.cpp b/src/r_data/models.cpp index 73c332a149..c8b0784a79 100644 --- a/src/r_data/models.cpp +++ b/src/r_data/models.cpp @@ -47,7 +47,6 @@ #include "p_tick.h" #include "actor.h" #include "actorinlines.h" -#include "v_video.h" #ifdef _MSC_VER @@ -412,8 +411,8 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr TArray surfaceskinids; - const TArray *boneData; - int boneStartingPosition = -1; + TArray boneData; + int boneStartingPosition = 0; bool evaluatedSingle = false; for (unsigned i = 0; i < modelsamount; i++) @@ -538,6 +537,15 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr bool nextFrame = smfNext && modelframe != modelframenext; + if (actor->boneComponentData == nullptr) + { + auto ptr = Create(); + ptr->trscomponents.Resize(modelsamount); + ptr->trsmatrix.Resize(modelsamount); + actor->boneComponentData = ptr; + GC::WriteBarrier(actor, ptr); + } + // [RL0] while per-model animations aren't done, DECOUPLEDANIMATIONS does the same as MODELSAREATTACHMENTS if(!evaluatedSingle) { @@ -554,24 +562,18 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr { if(decoupled_frame.frame1 != -1) { - boneData = animation->CalculateBones(actor->modelData->prevAnim, decoupled_frame, inter, animationData); + boneData = animation->CalculateBones(actor->modelData->prevAnim, decoupled_frame, inter, animationData, actor->boneComponentData, i); } } else { - boneData = animation->CalculateBones(nullptr, {nextFrame ? inter : -1.0f, modelframe, modelframenext}, -1.0f, animationData); + boneData = animation->CalculateBones(nullptr, {nextFrame ? inter : -1.0f, modelframe, modelframenext}, -1.0f, animationData, actor->boneComponentData, i); } - - if(smf_flags & MDL_MODELSAREATTACHMENTS || is_decoupled) - { - boneStartingPosition = boneData ? renderer->UploadBones(*boneData) : -1; - evaluatedSingle = true; - } - - boneData = nullptr; + boneStartingPosition = renderer->SetupFrame(animation, 0, 0, 0, boneData, -1); + evaluatedSingle = (smf_flags & MDL_MODELSAREATTACHMENTS) || is_decoupled; } - mdl->RenderFrame(renderer, tex, modelframe, nextFrame ? modelframenext : modelframe, nextFrame ? inter : -1.f, translation, ssidp, boneStartingPosition, actor); + mdl->RenderFrame(renderer, tex, modelframe, nextFrame ? modelframenext : modelframe, nextFrame ? inter : -1.f, translation, ssidp, boneData, boneStartingPosition, actor); } } } diff --git a/src/rendering/hwrenderer/hw_models.cpp b/src/rendering/hwrenderer/hw_models.cpp index cd99cc4e22..7214b31c77 100644 --- a/src/rendering/hwrenderer/hw_models.cpp +++ b/src/rendering/hwrenderer/hw_models.cpp @@ -169,19 +169,16 @@ void FHWModelRenderer::DrawElements(int numIndices, size_t offset) // //=========================================================================== -int FHWModelRenderer::UploadBones(const TArray& bones) -{ - return state.UploadBones(bones); -} - -void FHWModelRenderer::SetupFrame(FModel *model, unsigned int frame1, unsigned int frame2, unsigned int size, int boneStartIndex) +int FHWModelRenderer::SetupFrame(FModel *model, unsigned int frame1, unsigned int frame2, unsigned int size, const TArray& bones, int boneStartIndex) { auto mdbuff = static_cast(model->GetVertexBuffer(GetType())); - state.SetBoneIndexBase(boneStartIndex); + boneIndexBase = boneStartIndex >= 0 ? boneStartIndex : state.UploadBones(bones); + state.SetBoneIndexBase(boneIndexBase); if (mdbuff) { state.SetVertexBuffer(mdbuff->vertexBuffer(), frame1, frame2); if (mdbuff->indexBuffer()) state.SetIndexBuffer(mdbuff->indexBuffer()); } + return boneIndexBase; } diff --git a/src/rendering/hwrenderer/hw_models.h b/src/rendering/hwrenderer/hw_models.h index b19ad23a7b..ed3fb2066b 100644 --- a/src/rendering/hwrenderer/hw_models.h +++ b/src/rendering/hwrenderer/hw_models.h @@ -59,8 +59,7 @@ class FHWModelRenderer : public FModelRenderer void SetMaterial(FGameTexture *skin, bool clampNoFilter, FTranslationID translation, void * act) override; void DrawArrays(int start, int count) override; void DrawElements(int numIndices, size_t offset) override; - void SetupFrame(FModel *model, unsigned int frame1, unsigned int frame2, unsigned int size, int boneStartIndex) override; - int UploadBones(const TArray& bones) override; + int SetupFrame(FModel *model, unsigned int frame1, unsigned int frame2, unsigned int size, const TArray& bones, int boneStartIndex) override; };