How to bind a Pawn to an existing Mesh

Hey UE Community,

I’m creating a Dynamixyz Streaming Client for UE.

I receives from an extern server a list of bones and shape name, to animate in realtime a 3D Character face.
Unity example : Demo Unity

Previously, we extended a Pawn and use this piece of code to create a Map of bones or Morph, like a shortcut access to bones transformations.

struct SingleBoneController
{
	var int                     type;
	var SkelControlSingleBone   node;
	var MorphNodePose           morph;
};

var array<SingleBoneController>    sbControllers;


function InitSingleBoneControllers(array<int> types, array<string> names)
{
	local int index;
	local string str;

	sbControllers.Length = names.Length;
	foreach names(str, index)
	{
		sbControllers[index].type = types[index];
		sbControllers[index].morph = none;
		sbControllers[index].node = none;

		//`log("[UPawn] controller type "$types[index]);

		switch (types[index])
		{
		case 1: // blendshape type
			sbControllers[index].morph = MorphNodePose(Mesh.FindMorphNode(name(str)));
			if (sbControllers[index].morph == None)
			{
				`log("[UPawn] morph FAILED");
			}
			break;

		case 2: // joint type
			sbControllers[index].node = SkelControlSingleBone(Mesh.FindSkelControl(name(str)));
			if (sbControllers[index].node == None)
			{
				`log("[UPawn] single bone FAILED");
			}
			break;
		}
	}
}

Now with APawn Class, I can’t find search by name feature like Mesh.FindMorphNode(name(str)) and Mesh.FindSkelControl(name(str)).

In my new C++ version, I try to convert SingleBoneController like this but I’m not sure

USTRUCT()
struct FDxyzFacialController
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY()
	uint32						Type;//0 bone - 1 Morph

	UPROPERTY()
	FBoneReference				Bone;

	UPROPERTY()
	UMorphTarget*				Morph;

};

Any help will be greatly appreciated

Cheers,

Soxyz

Hey,

So my binding looks like that, I’m still searching the final class to move a bone in unreal (don’t laught please)

#pragma once

#include "DxyzFacialController.generated.h"

USTRUCT()
struct FDxyzFacialController
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY()
	int32						Type;//0 bone / 1 Morph / -1 uninitialized

	UPROPERTY()
	USkeletalMeshComponent*		Parent;

	UPROPERTY()
	int32						BoneIndex;
	UPROPERTY()
	FBodyInstance				Body;

	UPROPERTY()
	FName						MorphName;

	//Constructor
	FDxyzFacialController():
		Type(-1), Parent(nullptr), BoneIndex(-1), MorphName(""), Body()
	{

	}
};

my binding method , I would like to create a shortcut access :

	void HandleSocketXMLReceived()
	{
		UE_LOG(DxyzLog, Log, TEXT("HandleSocketXMLReceived: XML Received"));
		if (Client.IsValid())
		{
			for (int i = 0; i < Client->ChannelList.Num(); ++i)
			{
				FDxyzFacialController ctrl;
				bool found = false;
				if (Client->ChannelList[i].ClassName.ToLower() == "component")//mean bone
				{
					ctrl.Type = 0;//Bone
		
		

					UE_LOG(DxyzLog, Log, TEXT("searching : %s"), *(Client->ChannelList[i].Name));
					for (TObjectIterator<USkeletalMeshComponent> Itr; Itr && !found; ++Itr)
					{

						
						UE_LOG(DxyzLog, Log, TEXT("Scan USkeletalMeshComponent: %s %s"), *(Itr->GetName()), *(Itr->GetFullName()));

						int32 BoneIndex = Itr->GetBoneIndex(FName(*(Client->ChannelList[i].Name)));// Will return INDEX_NONE if bone not found.
						FBodyInstance * Body = Itr->GetBodyInstance
							(
							FName(*(Client->ChannelList[i].Name))
							);
						if (INDEX_NONE != BoneIndex)
						{
							UE_LOG(DxyzLog, Log, TEXT("Found USkeletalMeshComponent: Bone Index %d"), BoneIndex);
							ctrl.Parent = (*Itr);
							ctrl.BoneIndex = BoneIndex;
							ctrl.Body = (*Body);
							found = true;
						}

					}
				}
				else if (Client->ChannelList[i].ClassName.ToLower() == "blendshapetarget")//mean morph
				{
					ctrl.Type = 1;//Morph
					
					int LastOpenBracketIndex = 0;
					if (!Client->ChannelList[i].Name.FindLastChar('[', LastOpenBracketIndex))
					{
						UE_LOG(DxyzLog, Log, TEXT("Blendshape name parsing failed, can't find [ char in %s"), *( Client->ChannelList[i].Name));
					}

					int LastCloseBracketIndex;
					if (!Client->ChannelList[i].Name.FindLastChar(']', LastCloseBracketIndex))
					{
						UE_LOG(DxyzLog, Log, TEXT("Blendshape name parsing failed, can't find ] char in %s"), *(Client->ChannelList[i].Name));
					}

					FString ParentMeshName = Client->ChannelList[i].Name.LeftChop(LastOpenBracketIndex);
					FString TargetName = Client->ChannelList[i].Name.RightChop(LastOpenBracketIndex).LeftChop(LastCloseBracketIndex);

					UE_LOG(DxyzLog, Log, TEXT("Scan searching : %s %s"), *(ParentMeshName), *(TargetName));

					for (TObjectIterator<USkeletalMeshComponent> Itr; Itr && !found; ++Itr)
					{
						UE_LOG(DxyzLog, Log, TEXT("Scan USkeletalMeshComponent: %s"), *(Itr->GetName()));
						if (Itr->GetName().ToLower() == ParentMeshName.ToLower())
						{
							UE_LOG(DxyzLog, Log, TEXT("Found USkeletalMeshComponent: %s"), *(Itr->GetName()));

							UMorphTarget* Morph = Itr->FindMorphTarget(FName(*TargetName));
							if (Morph != NULL)
							{
								UE_LOG(DxyzLog, Log, TEXT("Found UMorphTarget: %s"), *(TargetName));

								ctrl.Parent = (*Itr);
								ctrl.MorphName = FName(*TargetName);

								found = true;
							}
						}
						
					}
					
				}
				if (ctrl.Type != -1)
					fControllers.Add(ctrl);
				else
				{
					UE_LOG(DxyzLog, Log, TEXT("Error Channel not found %s"), *(Client->ChannelList[i].Name));
				}
			}
		}
	}

and my frame received delegate :

	void HandleSocketFrameReceived()
	{
		UE_LOG(DxyzLog, Log, TEXT("HandleSocketFrameReceived: Frame Received"));
		if (fControllers.Num() == 0)return;
		if (Client->ChannelList.Num() != fControllers.Num())return;
		if (Client->CoeffCount == 0)return;
		if (Client->CoeffBuffer == NULL)return;

		for (int i = 0; i < fControllers.Num(); i++)
		{

			if (fControllers[i].Type == 0)//bone
			{
				FVector RelativeLocation(Client->CoeffBuffer[Client->ChannelList[i].CoeffBufferIndex],
					Client->CoeffBuffer[Client->ChannelList[i].CoeffBufferIndex + 1],
					Client->CoeffBuffer[Client->ChannelList[i].CoeffBufferIndex + 2]);

				FRotator RelativeRotation(const FQuat(Client->CoeffBuffer[Client->ChannelList[i].CoeffBufferIndex + 3]//InX
					, Client->CoeffBuffer[Client->ChannelList[i].CoeffBufferIndex + 4]//InY
					, Client->CoeffBuffer[Client->ChannelList[i].CoeffBufferIndex + 5]//InZ
					, Client->CoeffBuffer[Client->ChannelList[i].CoeffBufferIndex + 6]//InA
					));

				FVector RelativeScale3D(Client->CoeffBuffer[Client->ChannelList[i].CoeffBufferIndex + 7],
					Client->CoeffBuffer[Client->ChannelList[i].CoeffBufferIndex + 8],
					Client->CoeffBuffer[Client->ChannelList[i].CoeffBufferIndex + 9]);

				FTransform RelativeTransform(RelativeRotation, RelativeLocation, RelativeScale3D);

				const FBoneTransform BoneTransform(fControllers[i].BoneIndex, RelativeTransform);
		
		

			
				fControllers[i].Body.SetBodyTransform(RelativeTransform, true);

			}
			else if (fControllers[i].Type == 1)//morph
			{
				fControllers[i].Parent->SetMorphTarget(fControllers[i].MorphName, Client->CoeffBuffer[Client->ChannelList[i].CoeffBufferIndex]);
			}
		}

	}


No movement at all