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;