Correct order for applying transforms to Children vertices of an Actor in Simulink 3D Animation

1 回表示 (過去 30 日間)
Lai
Lai 2024 年 11 月 25 日
回答済み: Nishan Nekoo 2024 年 11 月 26 日
An Actor in Simulink 3D Animation is a tree structure because it has Children, which are also Actor and have their own Children.
I want to collect all vertices from an Actor and its Children into a single array. To combine them together, we have to handle the hierarchical coordinate systems. So I recursively apply the cumulative transforms (Scale, Rotation, Translation) to vertices of the Children nodes using a DFS algorithm as attached.
But the results are wrong. It results in disjointed components of the object (as the figure attached).
I tried different combinations of transform order (Scale->Rotation->Translation, Scale->Translation->Rotation, Rotation-Scale->Translation, etc.), I also tried to change the order of Rotation (apply Roll rotation first, as well as Yaw first). They did not work.
I must have a misunderstanding to the process since when we run the sim3d world to view the object, it looks good. How can we apply the transforms correctly?
allVertices = [];
function dfs(node, cumulativeTransform) % node is an Actor, cumulativeTransform is eye(4) for root Actor.
% Apply transforms in order of (Scale->Rotation (X,Y,Z)->Translation)
localTransform = makehgtform( ...
'translate', node.Translation, ...
'zrotate', node.Rotation(3), ... % Yaw
'yrotate', node.Rotation(2), ... % Pitch
'xrotate', node.Rotation(1), ... % Roll
'scale', node.Scale);
nodeTransform = cumulativeTransform * localTransform; % cumulateively apply the transforms
% nodeTransform = localTransform * cumulativeTransform;
% collect vertices into one single array
if ~isempty(node.Vertices)
transformedVertices = (nodeTransform * [node.Vertices, ones(size(node.Vertices, 1), 1)]')';
allVertices = [allVertices; transformedVertices(:, 1:3)];
end
% recursively collect vertices of all Children nodes
if ~isempty(fieldnames(node.Children))
childNames = fieldnames(node.Children);
for i = 1:numel(childNames)
childNode = node.Children.(childNames{i});
dfs(childNode, nodeTransform);
end
end
end

回答 (1 件)

Nishan Nekoo
Nishan Nekoo 2024 年 11 月 26 日
Hi Lai,
While I don't know the answer to your question directly, I do think you can try and narrow this down using only two nodes for example, instead of the whole body. Once you try this with two nodes, and change the order etc, it might be easier to narrow down what the correct order of the Transformation and Rotation should be.
Nishan

カテゴリ

Help Center および File ExchangeAnimation についてさらに検索

製品


リリース

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by