mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
Bone manipulation start
- Bone manipulation is largely finished, but I need to figure out how to multiply quaternions
This commit is contained in:
parent
317e163fcf
commit
28444d4cfd
6 changed files with 128 additions and 5 deletions
|
@ -543,15 +543,35 @@ const TArray<VSMatrix> IQMModel::CalculateBones(int frame1, int frame2, double i
|
||||||
for (int i = 0; i < numbones; i++)
|
for (int i = 0; i < numbones; i++)
|
||||||
{
|
{
|
||||||
TRS bone;
|
TRS bone;
|
||||||
bone.translation = animationFrames[offset1 + i].translation * invt + animationFrames[offset2 + i].translation * t;
|
TRS from = animationFrames[offset1 + i];
|
||||||
bone.rotation = animationFrames[offset1 + i].rotation * invt;
|
TRS to = animationFrames[offset2 + i];
|
||||||
if ((bone.rotation | animationFrames[offset2 + i].rotation * t) < 0)
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
bone.rotation.X *= -1; bone.rotation.Y *= -1; bone.rotation.Z *= -1; bone.rotation.W *= -1;
|
bone.rotation.X *= -1; bone.rotation.Y *= -1; bone.rotation.Z *= -1; bone.rotation.W *= -1;
|
||||||
}
|
}
|
||||||
bone.rotation += animationFrames[offset2 + i].rotation * t;
|
bone.rotation += to.rotation * t;
|
||||||
bone.rotation.MakeUnit();
|
bone.rotation.MakeUnit();
|
||||||
bone.scaling = animationFrames[offset1 + i].scaling * invt + animationFrames[offset2 + i].scaling * t;
|
bone.scaling = from.scaling * invt + to.scaling * t;
|
||||||
|
|
||||||
if (actor->boneComponentData->trscomponents[i].Equals(bone))
|
if (actor->boneComponentData->trscomponents[i].Equals(bone))
|
||||||
{
|
{
|
||||||
|
|
|
@ -701,6 +701,16 @@ public:
|
||||||
DBoneComponents() = default;
|
DBoneComponents() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DBoneManipulations : public DObject
|
||||||
|
{
|
||||||
|
DECLARE_CLASS(DBoneComponents, DObject);
|
||||||
|
public:
|
||||||
|
TArray<TRS> boneComponentsNew;
|
||||||
|
TArray<TRS> boneComponentsOld;
|
||||||
|
|
||||||
|
DBoneManipulations() = default;
|
||||||
|
};
|
||||||
|
|
||||||
class DViewPosition : public DObject
|
class DViewPosition : public DObject
|
||||||
{
|
{
|
||||||
DECLARE_CLASS(DViewPosition, DObject);
|
DECLARE_CLASS(DViewPosition, DObject);
|
||||||
|
@ -1098,6 +1108,7 @@ public:
|
||||||
double FloatSpeed;
|
double FloatSpeed;
|
||||||
TObjPtr<DActorModelData*> modelData;
|
TObjPtr<DActorModelData*> modelData;
|
||||||
TObjPtr<DBoneComponents*> boneComponentData;
|
TObjPtr<DBoneComponents*> boneComponentData;
|
||||||
|
TObjPtr<DBoneManipulations*> boneManipulationData;
|
||||||
|
|
||||||
// interaction info
|
// interaction info
|
||||||
FBlockNode *BlockNode; // links in blocks (if needed)
|
FBlockNode *BlockNode; // links in blocks (if needed)
|
||||||
|
|
|
@ -5195,3 +5195,86 @@ DEFINE_ACTION_FUNCTION(AActor, GetRenderStyle)
|
||||||
}
|
}
|
||||||
ACTION_RETURN_INT(-1); // no symbolic constant exists to handle this style.
|
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)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
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,6 +160,7 @@ CVAR (Int, cl_bloodtype, 0, CVAR_ARCHIVE);
|
||||||
|
|
||||||
IMPLEMENT_CLASS(DActorModelData, false, false);
|
IMPLEMENT_CLASS(DActorModelData, false, false);
|
||||||
IMPLEMENT_CLASS(DBoneComponents, false, false);
|
IMPLEMENT_CLASS(DBoneComponents, false, false);
|
||||||
|
IMPLEMENT_CLASS(DBoneManipulations, false, false);
|
||||||
IMPLEMENT_CLASS(AActor, false, true)
|
IMPLEMENT_CLASS(AActor, false, true)
|
||||||
|
|
||||||
IMPLEMENT_POINTERS_START(AActor)
|
IMPLEMENT_POINTERS_START(AActor)
|
||||||
|
@ -176,6 +177,7 @@ IMPLEMENT_POINTERS_START(AActor)
|
||||||
IMPLEMENT_POINTER(ViewPos)
|
IMPLEMENT_POINTER(ViewPos)
|
||||||
IMPLEMENT_POINTER(modelData)
|
IMPLEMENT_POINTER(modelData)
|
||||||
IMPLEMENT_POINTER(boneComponentData)
|
IMPLEMENT_POINTER(boneComponentData)
|
||||||
|
IMPLEMENT_POINTER(boneManipulationData)
|
||||||
IMPLEMENT_POINTERS_END
|
IMPLEMENT_POINTERS_END
|
||||||
|
|
||||||
AActor::~AActor ()
|
AActor::~AActor ()
|
||||||
|
|
|
@ -1134,6 +1134,7 @@ class Actor : Thinker native
|
||||||
deprecated("2.3", "Use 'b<FlagName> = [true/false]' instead") native void A_ChangeFlag(string flagname, bool value);
|
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);
|
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_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)
|
void A_SetFriendly (bool set)
|
||||||
{
|
{
|
||||||
|
|
|
@ -373,6 +373,12 @@ enum ChangeModelFlags
|
||||||
CMDL_USESURFACESKIN = 1 << 2,
|
CMDL_USESURFACESKIN = 1 << 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Manipulate Bone Flags
|
||||||
|
enum ManipulateBoneFlags
|
||||||
|
{
|
||||||
|
BM_USEEULER = 1
|
||||||
|
};
|
||||||
|
|
||||||
// Activation flags
|
// Activation flags
|
||||||
enum EActivationFlags
|
enum EActivationFlags
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue