Sharing Animations Between Multiple Characters With the Same Skeleton

I wrote these two functions.

With the help of these two functions, at runtime I can copy the animation from the first TCastleScene to the second TCastleScene and execute it.

procedure CopyAnimationOnly(Source, Target: TCastleScene);
var
I: Integer;
N: TX3DNode;
NewNode: TAbstractChildNode;
begin
for I := 0 to Source.RootNode.FdChildren.Count - 1 do
begin
N := Source.RootNode.FdChildren[I];

if (N is TTimeSensorNode) or
   (N is TAbstractInterpolatorNode) then
begin
  NewNode := N.DeepCopy as TAbstractChildNode;
  //NewNode.RoutesCount:=0;
  Target.RootNode.AddChildren([NewNode], False);
end;

end;
end;

and

procedure CopyRoutes(Source, Target: TCastleScene);
var
I: Integer;
R: TX3DRoute;
NewSourceNode, NewDestNode: TX3DNode;
NewSourceEvent, NewDestEvent: TX3DEvent;
begin
for I := 0 to Source.RootNode.RoutesCount - 1 do
begin
R := Source.RootNode.Routes[I];

NewSourceNode :=
  Target.RootNode.TryFindNodeByName(
    TX3DNode,
    R.SourceNode.X3DName,
    false
  );

NewDestNode :=
  Target.RootNode.TryFindNodeByName(
    TX3DNode,
    R.DestinationNode.X3DName,
    false
  );

if (NewSourceNode = nil) or (NewDestNode = nil) then
  Continue;

NewSourceEvent :=
  NewSourceNode.AnyEvent(R.SourceEvent.X3DName, false);

NewDestEvent :=
  NewDestNode.AnyEvent(R.DestinationEvent.X3DName, false);

if (NewSourceEvent = nil) or (NewDestEvent = nil) then
  Continue;

Target.RootNode.AddRoute(NewSourceEvent, NewDestEvent);

end;
end;

How to use:
procedure TViewMain.onbtnCreateClick(ASender: TObject);
begin
CopyAnimationOnly(Source,Target);
CopyRoutes(Source,Target);
end;

procedure TViewMain.onbtnWalkClick(ASender: TObject);
begin
if TCastleButton(ASender).Tag=1 then
Target.PlayAnimation(‘Walking_A’, true);
if TCastleButton(ASender).Tag=2 then
Target.PlayAnimation(‘Walking_B’, true);
if TCastleButton(ASender).Tag=3 then
Target.PlayAnimation(‘Walking_C’, true);
end;

1 Like