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

View file

@ -41,6 +41,13 @@ public:
FVector4 rotation; FVector4 rotation;
FVector3 scaling; FVector3 scaling;
TRS()
{
translation = FVector3(0,0,0);
rotation = FVector4(0,0,0,1);
scaling = FVector3(0,0,0);
}
bool Equals(TRS& compare) bool Equals(TRS& compare)
{ {
return compare.translation == this->translation && compare.rotation == this->rotation && compare.scaling == this->scaling; 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); 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 // Scalar division
TVector4 &operator/= (vec_t scalar) TVector4 &operator/= (vec_t scalar)
{ {

View file

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