Bone manipulation updates

- Factored in parent bone rotations to check if a bone needs updating
- Implemented multiply Quaternion functions to TVector4
- Converted Euler rotations in A_ManipulateBone to degrees
This commit is contained in:
Shiny Metagross 2022-10-28 12:52:10 -07:00 committed by Christoph Oelckers
parent 28444d4cfd
commit 7092971331
4 changed files with 47 additions and 9 deletions

View file

@ -540,6 +540,7 @@ const TArray<VSMatrix> IQMModel::CalculateBones(int frame1, int frame2, double i
swapYZ[3 + 3 * 4] = 1.0f;
TArray<VSMatrix> bones(numbones, true);
TArray<bool> modifiedBone(numbones, true);
for (int i = 0; i < numbones; i++)
{
TRS bone;
@ -551,14 +552,14 @@ const TArray<VSMatrix> IQMModel::CalculateBones(int frame1, int frame2, double i
if (i < actor->boneManipulationData->boneComponentsOld.Size())
{
from.translation += actor->boneManipulationData->boneComponentsOld[i].translation;
from.rotation += actor->boneManipulationData->boneComponentsOld[i].rotation;
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.rotation *= actor->boneManipulationData->boneComponentsNew[i].rotation;
to.scaling += actor->boneManipulationData->boneComponentsNew[i].scaling;
}
}
@ -573,14 +574,21 @@ const TArray<VSMatrix> IQMModel::CalculateBones(int frame1, int frame2, double i
bone.rotation.MakeUnit();
bone.scaling = from.scaling * invt + to.scaling * t;
if (actor->boneComponentData->trscomponents[i].Equals(bone))
if (Joints[i].Parent >= 0 && modifiedBone[Joints[i].Parent])
{
actor->boneComponentData->trscomponents[i] = bone;
modifiedBone[i] = true;
}
else if (actor->boneComponentData->trscomponents[i].Equals(bone))
{
bones[i] = actor->boneComponentData->trsmatrix[i];
modifiedBone[i] = false;
continue;
}
else
{
actor->boneComponentData->trscomponents[i] = bone;
modifiedBone[i] = true;
}
VSMatrix m;

View file

@ -41,6 +41,13 @@ public:
FVector4 rotation;
FVector3 scaling;
TRS()
{
translation = FVector3(0,0,0);
rotation = FVector4(0,0,0,1);
scaling = FVector3(0,0,0);
}
bool Equals(TRS& compare)
{
return compare.translation == this->translation && compare.rotation == this->rotation && compare.scaling == this->scaling;

View file

@ -833,6 +833,25 @@ struct TVector4
return TVector4(v.X * scalar, v.Y * scalar, v.Z * scalar, v.W * scalar);
}
// Multiply as Quaternion
TVector4& operator*= (const TVector4& v)
{
X = v.W * X + v.X * W + v.Y * Z - v.Z * Y;
Y = v.W * Y + v.Y * W + v.Z * X - v.X * Z;
Z = v.W * Z + v.Z * W + v.X * Y - v.Y * X;
W = v.W * W - v.X * X - v.Y * Y - v.Z * Z;
return *this;
}
friend TVector4 operator* (const TVector4& v1, const TVector4& v2)
{
return TVector4(v2.W * v1.X + v2.X * v1.W + v2.Y * v1.Z - v1.Z * v1.Y,
v2.W * v1.Y + v2.Y * v1.W + v2.Z * v1.X - v2.X * v1.Z,
v2.W * v1.Z + v2.Z * v1.W + v2.X * v1.Y - v2.Y * v1.X,
v2.W * v1.W - v2.X * v1.X - v2.Y * v1.Y - v2.Z * v1.Z
);
}
// Scalar division
TVector4 &operator/= (vec_t scalar)
{

View file

@ -5246,12 +5246,16 @@ DEFINE_ACTION_FUNCTION(AActor, A_ManipulateBone)
if (flags & BM_USEEULER)
{
double cr = cos(rotationZ * 0.5);
double sr = sin(rotationZ * 0.5);
double cp = cos(rotationY * 0.5);
double sp = sin(rotationY * 0.5);
double cy = cos(rotationX * 0.5);
double sy = sin(rotationX * 0.5);
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;