remove bone component cache to decrease memory consumption

caching this is entirely unnecessary, as it changes every frame
This commit is contained in:
Ricardo Luís Vaz Silva 2025-01-26 17:25:27 -03:00
parent 6ea1b68a1c
commit 3d2f9e06ed
22 changed files with 79 additions and 113 deletions

View file

@ -6,17 +6,6 @@
#include <variant>
class DBoneComponents : public DObject
{
DECLARE_CLASS(DBoneComponents, DObject);
public:
TArray<TArray<TRS>> trscomponents;
TArray<TArray<VSMatrix>> trsmatrix;
DBoneComponents() = default;
};
struct ModelAnimFrameInterp
{
float inter = -1.0f;

View file

@ -91,15 +91,15 @@ public:
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, const TArray<VSMatrix>& boneData, int boneStartPosition) = 0;
virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition) = 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<TRS>* AttachAnimationData() { return nullptr; };
virtual ModelAnimFrame PrecalculateFrame(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray<TRS>* animationData, DBoneComponents* bones, int index) { return nullptr; };
virtual ModelAnimFrame PrecalculateFrame(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray<TRS>* animationData) { return nullptr; };
virtual const TArray<VSMatrix> CalculateBones(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray<TRS>* animationData, DBoneComponents* bones, int index) { return {}; };
virtual const TArray<VSMatrix>* CalculateBones(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray<TRS>* animationData) { return nullptr; };
void SetVertexBuffer(int type, IModelVertexBuffer *buffer) { mVBuf[type] = buffer; }
IModelVertexBuffer *GetVertexBuffer(int type) const { return mVBuf[type]; }

View file

@ -116,16 +116,16 @@ public:
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, const TArray<VSMatrix>& boneData, int boneStartPosition) override;
void RenderFrame(FModelRenderer* renderer, FGameTexture* skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition) override;
void BuildVertexBuffer(FModelRenderer* renderer) override;
void AddSkins(uint8_t* hitlist, const FTextureID* surfaceskinids) override;
const TArray<TRS>* AttachAnimationData() override;
ModelAnimFrame PrecalculateFrame(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray<TRS>* animationData, DBoneComponents* bones, int index) override;
const TArray<VSMatrix> CalculateBones(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray<TRS>* animationData, DBoneComponents* bones, int index) override;
ModelAnimFrame PrecalculateFrame(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray<TRS>* animationData) override;
const TArray<VSMatrix>* CalculateBones(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray<TRS>* animationData) 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<TRS>* animationData, DBoneComponents* bones, int index);
const TArray<VSMatrix> CalculateBonesIQM(int frame1, int frame2, float inter, int frame1_prev, float inter1_prev, int frame2_prev, float inter2_prev, const ModelAnimFramePrecalculatedIQM* precalculated, const TArray<TRS>* animationData, DBoneComponents* bones, int index);
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<TRS>* animationData);
const TArray<VSMatrix>* CalculateBonesIQM(int frame1, int frame2, float inter, int frame1_prev, float inter1_prev, int frame2_prev, float inter2_prev, const ModelAnimFramePrecalculatedIQM* precalculated, const TArray<TRS>* animationData);
private:
void LoadGeometry();
@ -151,6 +151,8 @@ private:
TArray<IQMVertexArray> VertexArrays;
uint32_t NumVertices = 0;
TArray<VSMatrix> boneData; // temporary array, used to hold animation data during rendering, set during CalculateBones, uploaded during RenderFrame
TArray<FModelVertex> Vertices;
TArray<VSMatrix> baseframe;

View file

@ -59,7 +59,7 @@ public:
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, const TArray<VSMatrix>& boneData, int boneStartPosition) override;
virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition) override;
virtual void AddSkins(uint8_t *hitlist, const FTextureID* surfaceskinids) override;
FTextureID GetPaletteTexture() const { return mPalette; }
void BuildVertexBuffer(FModelRenderer *renderer) override;

View file

@ -113,7 +113,7 @@ public:
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, const TArray<VSMatrix>& boneData, int boneStartPosition) override;
virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition) override;
virtual void LoadGeometry();
virtual void AddSkins(uint8_t *hitlist, const FTextureID* surfaceskinids) override;

View file

@ -67,7 +67,7 @@ public:
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, const TArray<VSMatrix>& boneData, int boneStartPosition) override;
virtual void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition) override;
void LoadGeometry();
void BuildVertexBuffer(FModelRenderer *renderer);
virtual void AddSkins(uint8_t *hitlist, const FTextureID* surfaceskinids) override;

View file

@ -98,7 +98,7 @@ public:
~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, const TArray<VSMatrix>& boneData, int boneStartPosition) override;
void RenderFrame(FModelRenderer* renderer, FGameTexture* skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition) override;
void BuildVertexBuffer(FModelRenderer* renderer) override;
void AddSkins(uint8_t* hitlist, const FTextureID* surfaceskinids) override;
};

View file

@ -26,7 +26,7 @@ public:
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, const TArray<VSMatrix>& boneData, int boneStartPosition) override;
void RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition) override;
void BuildVertexBuffer(FModelRenderer *renderer) override;
void AddSkins(uint8_t *hitlist, const FTextureID* surfaceskinids) override;
void LoadGeometry();

View file

@ -24,6 +24,6 @@ public:
virtual void SetMaterial(FGameTexture *skin, bool clampNoFilter, FTranslationID translation) = 0;
virtual void DrawArrays(int start, int count) = 0;
virtual void DrawElements(int numIndices, size_t offset) = 0;
virtual int SetupFrame(FModel* model, unsigned int frame1, unsigned int frame2, unsigned int size, const TArray<VSMatrix>& bones, int boneStartIndex) { return -1; };
virtual void SetupFrame(FModel* model, unsigned int frame1, unsigned int frame2, unsigned int size, int boneStartIndex) {};
};

View file

@ -7,9 +7,8 @@
#include "engineerrors.h"
#include "dobject.h"
#include "bonecomponents.h"
IMPLEMENT_CLASS(DBoneComponents, false, false);
#include "v_video.h"
#include "hw_bonebuffer.h"
IQMModel::IQMModel()
{
@ -469,9 +468,10 @@ 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, const TArray<VSMatrix>& boneData, int boneStartPosition)
void IQMModel::RenderFrame(FModelRenderer* renderer, FGameTexture* skin, int frame1, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition)
{
renderer->SetupFrame(this, 0, 0, NumVertices, boneData, boneStartPosition);
renderer->SetupFrame(this, 0, 0, NumVertices, boneStartPosition >= 0 ? boneStartPosition : screen->mBones->UploadBones(boneData));
FGameTexture* lastSkin = nullptr;
for (unsigned i = 0; i < Meshes.Size(); i++)
@ -563,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<TRS>* animationData, DBoneComponents* bones, int index)
ModelAnimFrame IQMModel::PrecalculateFrame(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray<TRS>* animationData)
{
if(inter <= 0)
{
return CalculateFrameIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, animationData, bones, index);
return CalculateFrameIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, animationData);
}
else if(std::holds_alternative<ModelAnimFrameInterp>(from))
{
auto &from_interp = std::get<ModelAnimFrameInterp>(from);
return CalculateFrameIQM(from_interp.frame2, to.frame2, inter, from_interp.frame1, from_interp.inter, to.frame1, to.inter, nullptr, animationData, bones, index);
return CalculateFrameIQM(from_interp.frame2, to.frame2, inter, from_interp.frame1, from_interp.inter, to.frame1, to.inter, nullptr, animationData);
}
else if(std::holds_alternative<ModelAnimFramePrecalculatedIQM>(from))
{
return CalculateFrameIQM(0, to.frame2, inter, 0, -1.f, to.frame1, to.inter, &std::get<ModelAnimFramePrecalculatedIQM>(from), animationData, bones, index);
return CalculateFrameIQM(0, to.frame2, inter, 0, -1.f, to.frame1, to.inter, &std::get<ModelAnimFramePrecalculatedIQM>(from), animationData);
}
else
{
return CalculateFrameIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, animationData, bones, index);
return CalculateFrameIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, animationData);
}
}
const TArray<VSMatrix> IQMModel::CalculateBones(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray<TRS>* animationData, DBoneComponents* bones, int index)
const TArray<VSMatrix>* IQMModel::CalculateBones(const ModelAnimFrame &from, const ModelAnimFrameInterp &to, float inter, const TArray<TRS>* animationData)
{
if(inter <= 0)
{
return CalculateBonesIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, animationData, bones, index);
return CalculateBonesIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, animationData);
}
else if(std::holds_alternative<ModelAnimFrameInterp>(from))
{
auto &from_interp = std::get<ModelAnimFrameInterp>(from);
return CalculateBonesIQM(from_interp.frame2, to.frame2, inter, from_interp.frame1, from_interp.inter, to.frame1, to.inter, nullptr, animationData, bones, index);
return CalculateBonesIQM(from_interp.frame2, to.frame2, inter, from_interp.frame1, from_interp.inter, to.frame1, to.inter, nullptr, animationData);
}
else if(std::holds_alternative<ModelAnimFramePrecalculatedIQM>(from))
{
return CalculateBonesIQM(0, to.frame2, inter, 0, -1.f, to.frame1, to.inter, &std::get<ModelAnimFramePrecalculatedIQM>(from), animationData, bones, index);
return CalculateBonesIQM(0, to.frame2, inter, 0, -1.f, to.frame1, to.inter, &std::get<ModelAnimFramePrecalculatedIQM>(from), animationData);
}
else
{
return CalculateBonesIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, animationData, bones, index);
return CalculateBonesIQM(to.frame1, to.frame2, to.inter, 0, -1.f, 0, -1.f, nullptr, 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<TRS>* animationData, DBoneComponents* boneComponentData, int 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<TRS>* animationData)
{
ModelAnimFramePrecalculatedIQM out;
const TArray<TRS>& animationFrames = animationData ? *animationData : TRSData;
@ -661,18 +661,13 @@ ModelAnimFramePrecalculatedIQM IQMModel::CalculateFrameIQM(int frame1, int frame
return out;
}
const TArray<VSMatrix> 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<TRS>* animationData, DBoneComponents* boneComponentData, int index)
const TArray<VSMatrix>* 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<TRS>* animationData)
{
const TArray<TRS>& 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);
@ -686,14 +681,16 @@ const TArray<VSMatrix> IQMModel::CalculateBonesIQM(int frame1, int frame2, float
float invt1 = 1.0f - inter1_prev;
float invt2 = 1.0f - inter2_prev;
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;
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);
TArray<VSMatrix> bones(numbones, true);
TArray<bool> modifiedBone(numbones, true);
for (int i = 0; i < numbones; i++)
{
TRS prev;
@ -724,33 +721,16 @@ const TArray<VSMatrix> IQMModel::CalculateBonesIQM(int frame1, int frame2, float
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 = bones[i];
VSMatrix& result = boneData[i];
if (Joints[i].Parent >= 0)
{
result = bones[Joints[i].Parent];
result = boneData[Joints[i].Parent];
result.multMatrix(swapYZ);
result.multMatrix(baseframe[Joints[i].Parent]);
result.multMatrix(m);
@ -765,9 +745,7 @@ const TArray<VSMatrix> IQMModel::CalculateBonesIQM(int frame1, int frame2, float
result.multMatrix(swapYZ);
}
boneComponentData->trsmatrix[index] = bones;
return bones;
return &boneData;
}
return {};
return nullptr;
}

View file

@ -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*, const TArray<VSMatrix>& boneData, int boneStartPosition)
void FDMDModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frameno, int frameno2, double inter, FTranslationID translation, const FTextureID*, int boneStartPosition)
{
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);
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);
}

View file

@ -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, const TArray<VSMatrix>& boneData, int boneStartPosition)
void FMD3Model::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frameno, int frameno2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition)
{
if ((unsigned)frameno >= Frames.Size() || (unsigned)frameno2 >= Frames.Size()) return;
@ -375,7 +375,7 @@ void FMD3Model::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int f
}
renderer->SetMaterial(surfaceSkin, false, translation);
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);

View file

@ -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, const TArray<VSMatrix>& boneData, int boneStartPosition)
void FOBJModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frameno, int frameno2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition)
{
// Prevent the model from rendering if the frame number is < 0
if (frameno < 0 || frameno2 < 0) return;
@ -659,7 +659,7 @@ void FOBJModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int f
}
renderer->SetMaterial(userSkin, false, translation);
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);
}
}

View file

@ -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, const TArray<VSMatrix>& boneData, int boneStartPosition)
void FUE1Model::RenderFrame( FModelRenderer *renderer, FGameTexture *skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID* surfaceskinids, int boneStartPosition)
{
// 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);
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;
}

View file

@ -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*, const TArray<VSMatrix>& boneData, int boneStartPosition)
void FVoxelModel::RenderFrame(FModelRenderer *renderer, FGameTexture * skin, int frame, int frame2, double inter, FTranslationID translation, const FTextureID*, int boneStartPosition)
{
renderer->SetMaterial(skin, true, translation);
renderer->SetupFrame(this, 0, 0, 0, {}, -1);
renderer->SetupFrame(this, 0, 0, 0, -1);
renderer->DrawElements(mNumIndices, 0);
}

View file

@ -74,6 +74,7 @@ void BoneBuffer::Clear()
int BoneBuffer::UploadBones(const TArray<VSMatrix>& bones)
{
Map();
int totalsize = bones.Size();
if (totalsize > (int)mMaxUploadSize)
{
@ -90,10 +91,12 @@ int BoneBuffer::UploadBones(const TArray<VSMatrix>& bones)
if (thisindex + totalsize <= mBufferSize)
{
memcpy(mBufferPointer + thisindex * BONE_SIZE, bones.Data(), totalsize * BONE_SIZE);
Unmap();
return thisindex;
}
else
{
Unmap();
return -1; // Buffer is full. Since it is being used live at the point of the upload we cannot do much here but to abort.
}
}

View file

@ -1155,7 +1155,6 @@ public:
double Speed;
double FloatSpeed;
TObjPtr<DActorModelData*> modelData;
TObjPtr<DBoneComponents*> boneComponentData;
// interaction info
FBlockNode *BlockNode; // links in blocks (if needed)

View file

@ -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->boneComponentData, 0);
self->modelData->prevAnim = animation->PrecalculateFrame(self->modelData->prevAnim, to, inter, animationData);
}
else
{

View file

@ -178,7 +178,6 @@ IMPLEMENT_POINTERS_START(AActor)
IMPLEMENT_POINTER(alternative)
IMPLEMENT_POINTER(ViewPos)
IMPLEMENT_POINTER(modelData)
IMPLEMENT_POINTER(boneComponentData)
IMPLEMENT_POINTERS_END
//==========================================================================

View file

@ -45,6 +45,8 @@
#include "modelrenderer.h"
#include "actor.h"
#include "actorinlines.h"
#include "v_video.h"
#include "hw_bonebuffer.h"
#ifdef _MSC_VER
@ -394,8 +396,8 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
TArray<FTextureID> surfaceskinids;
TArray<VSMatrix> boneData;
int boneStartingPosition = 0;
const TArray<VSMatrix> *boneData;
int boneStartingPosition = -1;
bool evaluatedSingle = false;
for (unsigned i = 0; i < modelsamount; i++)
@ -520,15 +522,6 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
bool nextFrame = smfNext && modelframe != modelframenext;
if (actor->boneComponentData == nullptr)
{
auto ptr = Create<DBoneComponents>();
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)
{
@ -545,18 +538,24 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
{
if(decoupled_frame.frame1 != -1)
{
boneData = animation->CalculateBones(actor->modelData->prevAnim, decoupled_frame, inter, animationData, actor->boneComponentData, i);
boneData = animation->CalculateBones(actor->modelData->prevAnim, decoupled_frame, inter, animationData);
}
}
else
{
boneData = animation->CalculateBones(nullptr, {nextFrame ? inter : -1.0f, modelframe, modelframenext}, -1.0f, animationData, actor->boneComponentData, i);
boneData = animation->CalculateBones(nullptr, {nextFrame ? inter : -1.0f, modelframe, modelframenext}, -1.0f, animationData);
}
boneStartingPosition = renderer->SetupFrame(animation, 0, 0, 0, boneData, -1);
evaluatedSingle = (smf_flags & MDL_MODELSAREATTACHMENTS) || is_decoupled;
if(smf_flags & MDL_MODELSAREATTACHMENTS || is_decoupled)
{
boneStartingPosition = boneData ? screen->mBones->UploadBones(*boneData) : -1;
evaluatedSingle = true;
}
boneData = nullptr;
}
mdl->RenderFrame(renderer, tex, modelframe, nextFrame ? modelframenext : modelframe, nextFrame ? inter : -1.f, translation, ssidp, boneData, boneStartingPosition);
mdl->RenderFrame(renderer, tex, modelframe, nextFrame ? modelframenext : modelframe, nextFrame ? inter : -1.f, translation, ssidp, boneStartingPosition);
}
}
}

View file

@ -138,18 +138,15 @@ void FHWModelRenderer::DrawElements(int numIndices, size_t offset)
//
//===========================================================================
int FHWModelRenderer::SetupFrame(FModel *model, unsigned int frame1, unsigned int frame2, unsigned int size, const TArray<VSMatrix>& bones, int boneStartIndex)
void FHWModelRenderer::SetupFrame(FModel *model, unsigned int frame1, unsigned int frame2, unsigned int size, int boneStartIndex)
{
auto mdbuff = static_cast<FModelVertexBuffer*>(model->GetVertexBuffer(GetType()));
screen->mBones->Map();
boneIndexBase = boneStartIndex >= 0 ? boneStartIndex : screen->mBones->UploadBones(bones);
screen->mBones->Unmap();
state.SetBoneIndexBase(boneIndexBase);
//boneIndexBase = boneStartIndex;//boneStartIndex >= 0 ? boneStartIndex : screen->mBones->UploadBones(bones);
state.SetBoneIndexBase(boneStartIndex);
if (mdbuff)
{
state.SetVertexBuffer(mdbuff->vertexBuffer(), frame1, frame2);
if (mdbuff->indexBuffer()) state.SetIndexBuffer(mdbuff->indexBuffer());
}
return boneIndexBase;
}

View file

@ -56,7 +56,7 @@ public:
void SetMaterial(FGameTexture *skin, bool clampNoFilter, FTranslationID translation) override;
void DrawArrays(int start, int count) override;
void DrawElements(int numIndices, size_t offset) override;
int SetupFrame(FModel *model, unsigned int frame1, unsigned int frame2, unsigned int size, const TArray<VSMatrix>& bones, int boneStartIndex) override;
void SetupFrame(FModel *model, unsigned int frame1, unsigned int frame2, unsigned int size, int boneStartIndex) override;
};