mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-02-02 05:41:49 +00:00
IQM Refactor Milestone
- Removed bone manipulation code - Implemented an index in calculateBones to optimize multi-armature actors - Moved the bone storage object's creation to RenderModels so that the armature array can be sized there
This commit is contained in:
parent
7092971331
commit
f7c3615d3b
9 changed files with 26 additions and 145 deletions
|
@ -77,7 +77,7 @@ public:
|
|||
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 const TArray<VSMatrix> CalculateBones(int frame1, int frame2, double inter, const TArray<TRS>& animationData, AActor* actor) { return {}; };
|
||||
virtual const TArray<VSMatrix> CalculateBones(int frame1, int frame2, double inter, const TArray<TRS>& animationData, AActor* actor, int index) { return {}; };
|
||||
|
||||
void SetVertexBuffer(int type, IModelVertexBuffer *buffer) { mVBuf[type] = buffer; }
|
||||
IModelVertexBuffer *GetVertexBuffer(int type) const { return mVBuf[type]; }
|
||||
|
|
|
@ -113,7 +113,7 @@ public:
|
|||
void BuildVertexBuffer(FModelRenderer* renderer) override;
|
||||
void AddSkins(uint8_t* hitlist, const FTextureID* surfaceskinids) override;
|
||||
const TArray<TRS>* AttachAnimationData() override;
|
||||
const TArray<VSMatrix> CalculateBones(int frame1, int frame2, double inter, const TArray<TRS>& animationData, AActor* actor) override;
|
||||
const TArray<VSMatrix> CalculateBones(int frame1, int frame2, double inter, const TArray<TRS>& animationData, AActor* actor, int index) override;
|
||||
|
||||
private:
|
||||
void LoadGeometry();
|
||||
|
|
|
@ -510,20 +510,16 @@ const TArray<TRS>* IQMModel::AttachAnimationData()
|
|||
return &TRSData;
|
||||
}
|
||||
|
||||
const TArray<VSMatrix> IQMModel::CalculateBones(int frame1, int frame2, double inter, const TArray<TRS>& animationData, AActor* actor)
|
||||
const TArray<VSMatrix> IQMModel::CalculateBones(int frame1, int frame2, double inter, const TArray<TRS>& animationData, AActor* actor, int index)
|
||||
{
|
||||
const TArray<TRS>& animationFrames = &animationData ? animationData : TRSData;
|
||||
|
||||
int numbones = Joints.Size();
|
||||
|
||||
if (actor->boneComponentData == nullptr)
|
||||
{
|
||||
auto ptr = Create<DBoneComponents>();
|
||||
ptr->trscomponents.Resize(numbones);
|
||||
ptr->trsmatrix.Resize(numbones);
|
||||
actor->boneComponentData = ptr;
|
||||
GC::WriteBarrier(actor, ptr);
|
||||
}
|
||||
if(actor->boneComponentData->trscomponents[index].Size() != numbones)
|
||||
actor->boneComponentData->trscomponents[index].Resize(numbones);
|
||||
if (actor->boneComponentData->trsmatrix[index].Size() != numbones)
|
||||
actor->boneComponentData->trsmatrix[index].Resize(numbones);
|
||||
|
||||
frame1 = clamp(frame1, 0, ((int)animationFrames.Size() - 1) / numbones);
|
||||
frame2 = clamp(frame2, 0, ((int)animationFrames.Size() - 1) / numbones);
|
||||
|
@ -547,23 +543,6 @@ const TArray<VSMatrix> IQMModel::CalculateBones(int frame1, int frame2, double i
|
|||
TRS from = animationFrames[offset1 + i];
|
||||
TRS to = animationFrames[offset2 + i];
|
||||
|
||||
if (actor->boneManipulationData != nullptr)
|
||||
{
|
||||
if (i < actor->boneManipulationData->boneComponentsOld.Size())
|
||||
{
|
||||
from.translation += actor->boneManipulationData->boneComponentsOld[i].translation;
|
||||
from.rotation *= actor->boneManipulationData->boneComponentsOld[i].rotation;
|
||||
from.scaling += actor->boneManipulationData->boneComponentsOld[i].scaling;
|
||||
}
|
||||
|
||||
if (i < actor->boneManipulationData->boneComponentsNew.Size())
|
||||
{
|
||||
to.translation += actor->boneManipulationData->boneComponentsNew[i].translation;
|
||||
to.rotation *= actor->boneManipulationData->boneComponentsNew[i].rotation;
|
||||
to.scaling += actor->boneManipulationData->boneComponentsNew[i].scaling;
|
||||
}
|
||||
}
|
||||
|
||||
bone.translation = from.translation * invt + to.translation * t;
|
||||
bone.rotation = from.rotation * invt;
|
||||
if ((bone.rotation | to.rotation * t) < 0)
|
||||
|
@ -576,18 +555,18 @@ const TArray<VSMatrix> IQMModel::CalculateBones(int frame1, int frame2, double i
|
|||
|
||||
if (Joints[i].Parent >= 0 && modifiedBone[Joints[i].Parent])
|
||||
{
|
||||
actor->boneComponentData->trscomponents[i] = bone;
|
||||
actor->boneComponentData->trscomponents[index][i] = bone;
|
||||
modifiedBone[i] = true;
|
||||
}
|
||||
else if (actor->boneComponentData->trscomponents[i].Equals(bone))
|
||||
else if (actor->boneComponentData->trscomponents[index][i].Equals(bone))
|
||||
{
|
||||
bones[i] = actor->boneComponentData->trsmatrix[i];
|
||||
bones[i] = actor->boneComponentData->trsmatrix[index][i];
|
||||
modifiedBone[i] = false;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
actor->boneComponentData->trscomponents[i] = bone;
|
||||
actor->boneComponentData->trscomponents[index][i] = bone;
|
||||
modifiedBone[i] = true;
|
||||
}
|
||||
|
||||
|
@ -612,7 +591,7 @@ const TArray<VSMatrix> IQMModel::CalculateBones(int frame1, int frame2, double i
|
|||
}
|
||||
}
|
||||
|
||||
actor->boneComponentData->trsmatrix = bones;
|
||||
actor->boneComponentData->trsmatrix[index] = bones;
|
||||
|
||||
for (uint32_t j = 0; j < numbones; j++)
|
||||
{
|
||||
|
|
|
@ -695,22 +695,12 @@ class DBoneComponents : public DObject
|
|||
{
|
||||
DECLARE_CLASS(DBoneComponents, DObject);
|
||||
public:
|
||||
TArray<TRS> trscomponents;
|
||||
TArray<VSMatrix> trsmatrix;
|
||||
TArray<TArray<TRS>> trscomponents;
|
||||
TArray<TArray<VSMatrix>> trsmatrix;
|
||||
|
||||
DBoneComponents() = default;
|
||||
};
|
||||
|
||||
class DBoneManipulations : public DObject
|
||||
{
|
||||
DECLARE_CLASS(DBoneComponents, DObject);
|
||||
public:
|
||||
TArray<TRS> boneComponentsNew;
|
||||
TArray<TRS> boneComponentsOld;
|
||||
|
||||
DBoneManipulations() = default;
|
||||
};
|
||||
|
||||
class DViewPosition : public DObject
|
||||
{
|
||||
DECLARE_CLASS(DViewPosition, DObject);
|
||||
|
@ -1108,7 +1098,6 @@ public:
|
|||
double FloatSpeed;
|
||||
TObjPtr<DActorModelData*> modelData;
|
||||
TObjPtr<DBoneComponents*> boneComponentData;
|
||||
TObjPtr<DBoneManipulations*> boneManipulationData;
|
||||
|
||||
// interaction info
|
||||
FBlockNode *BlockNode; // links in blocks (if needed)
|
||||
|
|
|
@ -5194,91 +5194,4 @@ DEFINE_ACTION_FUNCTION(AActor, GetRenderStyle)
|
|||
if (self->RenderStyle == LegacyRenderStyles[i]) ACTION_RETURN_INT(i);
|
||||
}
|
||||
ACTION_RETURN_INT(-1); // no symbolic constant exists to handle this style.
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// A_ManipulateBone(a bunch of crap)
|
||||
//
|
||||
// This function allows manipulating a bone
|
||||
//==========================================================================
|
||||
|
||||
enum ManipulateBoneFlags
|
||||
{
|
||||
BM_USEEULER = 1
|
||||
};
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, A_ManipulateBone)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE(AActor);
|
||||
PARAM_INT(modelindex);
|
||||
PARAM_INT(boneindex);
|
||||
PARAM_FLOAT(positionX);
|
||||
PARAM_FLOAT(positionY);
|
||||
PARAM_FLOAT(positionZ);
|
||||
PARAM_FLOAT(rotationX);
|
||||
PARAM_FLOAT(rotationY);
|
||||
PARAM_FLOAT(rotationZ);
|
||||
PARAM_FLOAT(rotationW);
|
||||
PARAM_FLOAT(scaleX);
|
||||
PARAM_FLOAT(scaleY);
|
||||
PARAM_FLOAT(scaleZ);
|
||||
PARAM_INT(flags);
|
||||
|
||||
if (self == nullptr)
|
||||
ACTION_RETURN_BOOL(false);
|
||||
|
||||
AActor* mobj = ACTION_CALL_FROM_INVENTORY() ? self : stateowner;
|
||||
|
||||
if (mobj->boneManipulationData == nullptr)
|
||||
{
|
||||
auto ptr = Create<DBoneManipulations>();
|
||||
ptr->boneComponentsNew = *new TArray<TRS>();
|
||||
ptr->boneComponentsOld = *new TArray<TRS>();
|
||||
mobj->boneManipulationData = ptr;
|
||||
GC::WriteBarrier(mobj, ptr);
|
||||
}
|
||||
|
||||
while(boneindex >= mobj->boneManipulationData->boneComponentsNew.Size())
|
||||
mobj->boneManipulationData->boneComponentsNew.Push(TRS());
|
||||
while (boneindex >= mobj->boneManipulationData->boneComponentsOld.Size())
|
||||
mobj->boneManipulationData->boneComponentsOld.Push(TRS());
|
||||
|
||||
if (flags & BM_USEEULER)
|
||||
{
|
||||
rotationX = rotationX * 3.14159265359f / 180.0f;
|
||||
rotationY = rotationY * 3.14159265359f / 180.0f;
|
||||
rotationZ = rotationZ * 3.14159265359f / 180.0f;
|
||||
|
||||
double cr = cos(rotationX * 0.5);
|
||||
double sr = sin(rotationX * 0.5);
|
||||
double cp = cos(rotationZ * 0.5);
|
||||
double sp = sin(rotationZ * 0.5);
|
||||
double cy = cos(rotationY * 0.5);
|
||||
double sy = sin(rotationY * 0.5);
|
||||
|
||||
rotationW = cr * cp * cy + sr * sp * sy;
|
||||
rotationX = sr * cp * cy - cr * sp * sy;
|
||||
rotationY = cr * sp * cy + sr * cp * sy;
|
||||
rotationZ = cr * cp * sy - sr * sp * cy;
|
||||
|
||||
//Printf("Rotation X is: %f\n", rotationX);
|
||||
//Printf("Rotation Y is: %f\n", rotationY);
|
||||
//Printf("Rotation Z is: %f\n", rotationZ);
|
||||
//Printf("Rotation W is: %f\n", rotationW);
|
||||
}
|
||||
|
||||
mobj->boneManipulationData->boneComponentsOld[boneindex] = mobj->boneManipulationData->boneComponentsNew[boneindex];
|
||||
mobj->boneManipulationData->boneComponentsNew[boneindex].translation.X = positionX;
|
||||
mobj->boneManipulationData->boneComponentsNew[boneindex].translation.Y = positionZ;
|
||||
mobj->boneManipulationData->boneComponentsNew[boneindex].translation.Z = positionY;
|
||||
mobj->boneManipulationData->boneComponentsNew[boneindex].rotation.X = rotationX;
|
||||
mobj->boneManipulationData->boneComponentsNew[boneindex].rotation.Y = rotationY;
|
||||
mobj->boneManipulationData->boneComponentsNew[boneindex].rotation.Z = rotationZ;
|
||||
mobj->boneManipulationData->boneComponentsNew[boneindex].rotation.W = rotationW;
|
||||
mobj->boneManipulationData->boneComponentsNew[boneindex].scaling.X = scaleX;
|
||||
mobj->boneManipulationData->boneComponentsNew[boneindex].scaling.Y = scaleZ;
|
||||
mobj->boneManipulationData->boneComponentsNew[boneindex].scaling.Z = scaleY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -160,7 +160,6 @@ CVAR (Int, cl_bloodtype, 0, CVAR_ARCHIVE);
|
|||
|
||||
IMPLEMENT_CLASS(DActorModelData, false, false);
|
||||
IMPLEMENT_CLASS(DBoneComponents, false, false);
|
||||
IMPLEMENT_CLASS(DBoneManipulations, false, false);
|
||||
IMPLEMENT_CLASS(AActor, false, true)
|
||||
|
||||
IMPLEMENT_POINTERS_START(AActor)
|
||||
|
@ -177,7 +176,6 @@ IMPLEMENT_POINTERS_START(AActor)
|
|||
IMPLEMENT_POINTER(ViewPos)
|
||||
IMPLEMENT_POINTER(modelData)
|
||||
IMPLEMENT_POINTER(boneComponentData)
|
||||
IMPLEMENT_POINTER(boneManipulationData)
|
||||
IMPLEMENT_POINTERS_END
|
||||
|
||||
AActor::~AActor ()
|
||||
|
|
|
@ -356,6 +356,15 @@ 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);
|
||||
}
|
||||
|
||||
if (animationid >= 0)
|
||||
{
|
||||
FModel* animation = Models[animationid];
|
||||
|
@ -363,7 +372,7 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
|
|||
|
||||
if (!(smf->flags & MDL_MODELSAREATTACHMENTS) || evaluatedSingle == false)
|
||||
{
|
||||
boneData = animation->CalculateBones(modelframe, nextFrame ? modelframenext : modelframe, nextFrame ? inter : 0.f, *animationData, actor);
|
||||
boneData = animation->CalculateBones(modelframe, nextFrame ? modelframenext : modelframe, nextFrame ? inter : 0.f, *animationData, actor, i);
|
||||
boneStartingPosition = renderer->SetupFrame(animation, 0, 0, 0, boneData, -1);
|
||||
evaluatedSingle = true;
|
||||
}
|
||||
|
@ -372,7 +381,7 @@ void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpr
|
|||
{
|
||||
if (!(smf->flags & MDL_MODELSAREATTACHMENTS) || evaluatedSingle == false)
|
||||
{
|
||||
boneData = mdl->CalculateBones(modelframe, nextFrame ? modelframenext : modelframe, nextFrame ? inter : 0.f, *animationData, actor);
|
||||
boneData = mdl->CalculateBones(modelframe, nextFrame ? modelframenext : modelframe, nextFrame ? inter : 0.f, *animationData, actor, i);
|
||||
boneStartingPosition = renderer->SetupFrame(mdl, 0, 0, 0, boneData, -1);
|
||||
evaluatedSingle = true;
|
||||
}
|
||||
|
|
|
@ -1134,7 +1134,6 @@ class Actor : Thinker native
|
|||
deprecated("2.3", "Use 'b<FlagName> = [true/false]' instead") native void A_ChangeFlag(string flagname, bool value);
|
||||
native void A_ChangeCountFlags(int kill = FLAG_NO_CHANGE, int item = FLAG_NO_CHANGE, int secret = FLAG_NO_CHANGE);
|
||||
action native void A_ChangeModel(name modeldef, int modelindex = 0, string modelpath = "", name model = "", int skinindex = 0, string skinpath = "", name skin = "", int flags = 0, int generatorindex = -1, int animationindex = 0, string animationpath = "", name animation = "");
|
||||
action native void A_ManipulateBone(int modelindex, int boneindex, float positionX = 0, float positionY = 0, float positionZ = 0, float rotationX = 0, float rotationY = 0, float rotationZ = 0, float rotationW = 0, float scaleX = 0, float scaleY = 0, float scaleZ = 0, int flags = 0);
|
||||
|
||||
void A_SetFriendly (bool set)
|
||||
{
|
||||
|
|
|
@ -373,12 +373,6 @@ enum ChangeModelFlags
|
|||
CMDL_USESURFACESKIN = 1 << 2,
|
||||
};
|
||||
|
||||
// Manipulate Bone Flags
|
||||
enum ManipulateBoneFlags
|
||||
{
|
||||
BM_USEEULER = 1
|
||||
};
|
||||
|
||||
// Activation flags
|
||||
enum EActivationFlags
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue