diff --git a/src/playsim/actor.h b/src/playsim/actor.h index c4ec8a8b8..2f51398ab 100644 --- a/src/playsim/actor.h +++ b/src/playsim/actor.h @@ -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); diff --git a/src/playsim/p_actionfunctions.cpp b/src/playsim/p_actionfunctions.cpp index 776945da6..d8e13ec26 100644 --- a/src/playsim/p_actionfunctions.cpp +++ b/src/playsim/p_actionfunctions.cpp @@ -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) diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index 08182167b..a29c6928e 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -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); } } diff --git a/wadsrc/static/zscript/actors/actor.zs b/wadsrc/static/zscript/actors/actor.zs index 812c1b245..fbff082cc 100644 --- a/wadsrc/static/zscript/actors/actor.zs +++ b/wadsrc/static/zscript/actors/actor.zs @@ -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; } //================================================