up vector for TransformByBone/GetBonePosition

This commit is contained in:
Ricardo Luís Vaz Silva 2025-05-23 03:20:44 -03:00
commit cffdfa802e
4 changed files with 52 additions and 27 deletions

View file

@ -831,7 +831,7 @@ public:
//outmat must be double[16]
void GetBoneMatrix(int model_index, int bone_index, bool with_override, double *outMat);
void GetBonePosition(int model_index, int bone_index, bool with_override, DVector3 &pos, DVector3 &normal);
void GetBonePosition(int model_index, int bone_index, bool with_override, DVector3 &pos, DVector3 &fwd, DVector3 &up);
void GetObjectToWorldMatrix(double *outMat);
static AActor *StaticSpawn (FLevelLocals *Level, PClassActor *type, const DVector3 &pos, replace_t allowreplacement, bool SpawningMapThing = false);

View file

@ -6037,24 +6037,33 @@ DEFINE_ACTION_FUNCTION(AActor, TransformByBone)
PARAM_FLOAT(pos_x);
PARAM_FLOAT(pos_y);
PARAM_FLOAT(pos_z);
PARAM_FLOAT(dir_x);
PARAM_FLOAT(dir_y);
PARAM_FLOAT(dir_z);
PARAM_FLOAT(fwd_x);
PARAM_FLOAT(fwd_y);
PARAM_FLOAT(fwd_z);
PARAM_FLOAT(up_x);
PARAM_FLOAT(up_y);
PARAM_FLOAT(up_z);
PARAM_BOOL(with_override);
FModel * mdl = GetBoneShared(self, 0, bone_index, nullptr);
DVector3 position(pos_x, pos_y, pos_z);
DVector3 direction(dir_x, dir_y, dir_z);
DVector3 fwd(fwd_x, fwd_y, fwd_z);
DVector3 up(up_x, up_y, up_z);
if(mdl)
{
self->GetBonePosition(0, bone_index, with_override, position, direction);
self->GetBonePosition(0, bone_index, with_override, position, fwd, up);
}
if(numret > 2)
{
ret[2].SetVector(up);
}
if(numret > 1)
{
ret[1].SetVector(direction);
ret[1].SetVector(fwd);
}
if(numret > 0)
@ -6072,9 +6081,12 @@ DEFINE_ACTION_FUNCTION(AActor, TransformByNamedBone)
PARAM_FLOAT(pos_x);
PARAM_FLOAT(pos_y);
PARAM_FLOAT(pos_z);
PARAM_FLOAT(dir_x);
PARAM_FLOAT(dir_y);
PARAM_FLOAT(dir_z);
PARAM_FLOAT(fwd_x);
PARAM_FLOAT(fwd_y);
PARAM_FLOAT(fwd_z);
PARAM_FLOAT(up_x);
PARAM_FLOAT(up_y);
PARAM_FLOAT(up_z);
PARAM_BOOL(with_override);
int bone_index;
@ -6082,16 +6094,22 @@ DEFINE_ACTION_FUNCTION(AActor, TransformByNamedBone)
FModel * mdl = GetBoneShared(self, 0, bone_index, &bone_name);
DVector3 position(pos_x, pos_y, pos_z);
DVector3 direction(dir_x, dir_y, dir_z);
DVector3 fwd(fwd_x, fwd_y, fwd_z);
DVector3 up(up_x, up_y, up_z);
if(mdl)
{
self->GetBonePosition(0, bone_index, with_override, position, direction);
self->GetBonePosition(0, bone_index, with_override, position, fwd, up);
}
if(numret > 2)
{
ret[2].SetVector(up);
}
if(numret > 1)
{
ret[1].SetVector(direction);
ret[1].SetVector(fwd);
}
if(numret > 0)

View file

@ -4309,7 +4309,7 @@ void AActor::GetBoneMatrix(int model_index, int bone_index, bool with_override,
}
}
void AActor::GetBonePosition(int model_index, int bone_index, bool with_override, DVector3 &pos, DVector3 &normal)
void AActor::GetBonePosition(int model_index, int bone_index, bool with_override, DVector3 &pos, DVector3 &fwd, DVector3 &up)
{
if(modelData && modelData->flags & MODELDATA_GET_BONE_INFO)
{
@ -4324,20 +4324,26 @@ void AActor::GetBonePosition(int model_index, int bone_index, bool with_override
FVector4 oldPos(pos.X, pos.Z, pos.Y, 1.0);
FVector4 newPos;
FVector4 oldNormal(normal.X, normal.Z, normal.Y, 0.0);
FVector4 newNormal;
FVector4 oldFwd(fwd.X, fwd.Z, fwd.Y, 0.0);
FVector4 newFwd;
FVector4 oldUp(up.X, up.Z, up.Y, 0.0);
FVector4 newUp;
boneMatrix.multMatrixPoint(&oldPos.X, &newPos.X);
boneMatrix.multMatrixPoint(&oldNormal.X, &newNormal.X);
boneMatrix.multMatrixPoint(&oldFwd.X, &newFwd.X);
boneMatrix.multMatrixPoint(&oldUp.X, &newUp.X);
oldPos = FVector4(FVector3(newPos.X, newPos.Y, newPos.Z) / newPos.W, 1.0);
oldNormal = FVector4(FVector3(newNormal.X, newNormal.Y, newNormal.Z) / newNormal.W, 0.0);
oldFwd = FVector4(FVector3(newFwd.X, newFwd.Y, newFwd.Z) / newFwd.W, 0.0);
oldUp = FVector4(FVector3(newUp.X, newUp.Y, newUp.Z) / newUp.W, 0.0);
worldMatrix.multMatrixPoint(&oldPos.X, &newPos.X);
worldMatrix.multMatrixPoint(&oldNormal.X, &newNormal.X);
worldMatrix.multMatrixPoint(&oldFwd.X, &newFwd.X);
worldMatrix.multMatrixPoint(&oldUp.X, &newUp.X);
pos = DVector3(newPos.X, newPos.Z, newPos.Y);
normal = DVector3(newNormal.X, newNormal.Z, newNormal.Y);
fwd = DVector3(newFwd.X, newFwd.Z, newFwd.Y);
up = DVector3(newUp.X, newUp.Z, newUp.Y);
}
}

View file

@ -1479,19 +1479,20 @@ class Actor : Thinker native
native version("4.15.1") Quat, Vector3, Vector3 GetBoneTRS(int boneIndex, bool include_offsets = true);
native version("4.15.1") Quat, Vector3, Vector3 GetNamedBoneTRS(Name boneName, bool include_offsets = true);
native version("4.15.1") Vector3, Vector3 TransformByBone(int boneIndex, Vector3 position, Vector3 direction = (0,0,0), bool include_offsets = true);
native version("4.15.1") Vector3, Vector3 TransformByNamedBone(Name boneName, Vector3 position, Vector3 direction = (0,0,0), bool include_offsets = true);
//input position/direction vectors are in xzy, model space
native version("4.15.1") Vector3, Vector3, Vector3 TransformByBone(int boneIndex, Vector3 position, Vector3 forward = (1,0,0), Vector3 up = (0,1,0), bool include_offsets = true);
native version("4.15.1") Vector3, Vector3, Vector3 TransformByNamedBone(Name boneName, Vector3 position, Vector3 forward = (1,0,0) Vector3 up = (0,1,0), bool include_offsets = true);
version("4.15.1") Vector3, Vector3 GetBonePosition(int boneIndex, bool include_offsets = true)
version("4.15.1") Vector3, Vector3, Vector3 GetBonePosition(int boneIndex, bool include_offsets = true)
{
let [a, b] = TransformByBone(boneIndex, GetBoneBasePosition(boneIndex), include_offsets:include_offsets);
return a, b;
let [a, b, c] = TransformByBone(boneIndex, GetBoneBasePosition(boneIndex), include_offsets:include_offsets);
return a, b, c;
}
version("4.15.1") Vector3, Vector3 GetNamedBonePosition(name boneName, bool include_offsets = true)
{
let [a, b] = GetBonePosition(GetBoneIndex(boneName), include_offsets);
return a, b;
let [a, b, c] = GetBonePosition(GetBoneIndex(boneName), include_offsets);
return a, b, c;
}
//================================================