Set bone rotations for Poseable mesh in local space

Greetings to everyone. : )

I’m implementing a VR experience on UE4 that detects the movement of the VR experience user, updating the user or representation of the user inside the virtual world.

For doing so, I’ve implemented this behavior with C++ based on what ‘Michael Noland’ says in this topic: Pose a skeletal mesh in runtime - C++ - Epic Developer Community Forums

That is, I have an USkeletalMeshComponent (whose Skeletal mesh is the one seen on screen), and an UPoseableMeshComponent (being set as the “master pose component” for the USkeletalMeshComponent), that receives the rotation data as quaternions from each tracking sensor.

One hand, the mesh for the UPoseableMeshComponent will be set to the mesh of the USkeletalMeshComponet. The other hand, the bones of the poseable mesh are updated with the corresponding rotation data coming from the tracking sensors for each bone, which makes automatically the skeletal mesh to be updated accordingly due to the UPoseableMeshComponent was set as “master pose component” for the USkeletalMeshComponent.

This works pefectly when working with all the body parts that are not finger phalanxes, because rotations are set on those body parts in world space, in this way:

m_pPoseableMeshComp->SetBoneRotationByName(strBoneName, qBoneRotation.Rotator(), EBoneSpaces::WorldSpace);

However, for technical reasons, it is mandatory to set the bone rotations for each finger phalanx in LOCAL space, but poseable meshes seems to work only on world space and component space; checking out ‘SkinnedMeshComponent.h’ there is a ‘LocalSpace’ enum value on EBoneSpaces::Type… but it’s commented!.

/** Values for specifying bone space. */
UENUM()
namespace EBoneSpaces
{
	enum Type
	{
		/** Set absolute position of bone in world space. */
		WorldSpace		UMETA(DisplayName = "World Space"),
		/** Set position of bone in components reference frame. */
		ComponentSpace	UMETA(DisplayName = "Component Space"),
		/** Set position of bone relative to parent bone. */
		//LocalSpace		UMETA( DisplayName = "Parent Bone Space" ),
	};
}

I cannot understand the phrase ‘Set position of bone in components reference frame’. It doesn’t seem to work as the “replacement” for local space (with this option it behaves as if the bone were rotating around the avatar’s pivot point). Is there any other way to set rotations in local space for a poseable mesh?.

Thanks in advance. : )

Hi, have you solved it? This problem comes to me too.
I used get bone rotation from component space, but it seems also work as the same as from world space.

I create a class inherit poseablemesh, create a function to do this.
#############
BoneSpaceTransforms[GetBoneIndex(BoneName)] = inLocalTransform;
#############

@DarKMoonone
Thanks a lot for the hint!!!
I really wonder why this feature is not implemented in the stock component of Unreal Engine … it took me 1-2h to figure out what is going wrong when I tried to read bone transforms directly from a UAnimSequence.

This is how we solved the issue in our framework:

#pragma once

#include "CoreMinimal.h"
#include "Components/PoseableMeshComponent.h"
#include "TMPoseableMeshComponent.generated.h"

UCLASS(meta = (BlueprintSpawnableComponent))
class TTMOTION_API UTMPoseableMeshComponent : public UPoseableMeshComponent
{
	GENERATED_BODY()
public:
	UFUNCTION(BlueprintCallable, Category = "Components|PoseableMesh")
	void SetBoneLocalTransformByName(FName BoneName, const FTransform& InTransform);	
};
#include "TMotion/Components/TMPoseableMeshComponent.h"

void UTMPoseableMeshComponent::SetBoneLocalTransformByName(FName BoneName, const FTransform& InTransform)
{
  if (!SkeletalMesh || !RequiredBones.IsValid())
  {
    return;
  }

  int32 boneIndex = GetBoneIndex(BoneName);
  if (boneIndex >= 0 && boneIndex < BoneSpaceTransforms.Num())
  {
    BoneSpaceTransforms[boneIndex] = InTransform;
    MarkRefreshTransformDirty();
  }
}