mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-01-21 09:01:37 +00:00
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:
parent
28444d4cfd
commit
7092971331
4 changed files with 47 additions and 9 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue