<div dir="ltr"><div dir="auto"><div>Thanks, yes, I agree and it had occurred to me to that the necessary Mixer combos will become hard to manage.</div><div><br></div><div>So if we want easy animation blending, we would need to identify sets of interpolators to manipulate as a set.</div><div dir="auto"><br></div><div dir="auto">But there is no way to group interpolators into sets AFAIK.</div><div dir="auto"><br></div><div>I think this is related to how it necessary to have long lists of ROUTE statements in the HAnim examples. If there would be a way to define interpolator sets or node sets it should be possible to ROUTE to many nodes in case they share an input field:</div><div><br></div><div><ROUTE from... toNodeSet='DEF name of node set' toField='field in all nodes' /></div><div><br></div><div>A literal fan out of an event, here TimeSensor fraction_changed to set_fraction of many inteprolators. Let's call it MROUTE.</div><div><br></div><div>Perhaps this concept an be applied to mixing as well. Hm, let's see.</div><div><br></div><div>The idea is to mix all the outputs from interpolators of animation A (node set A) with all the outputs from interplators of animation B.</div><div><br></div><div>This will require that it is possible to have a one to one mapping of nodes in both sets. I think MFNode arrays are ordered by occurrence in the file, so this may be possible.</div><div><br></div><div>If so, a MMixer node could accept these node sets as inputs, mix them simultaneously. What would the output be ? Conceptually, It would be all the output events from the mixed inputs.</div><div><br></div><div><MMixer DEF='MixerAB' outputSet='ABmixed' inputA='node set A' inputB='node set B'/></div><div><br></div><div>The output could also be a new, generated node set (ABmixed) which contains the same type of nodes as the input node sets. Nodes contained in the generated output node set could be accessed via a DEF name convention: 'ABmixed_1' would be the first node in the generated node set. Or 'ABmixed_DEFname1_DEFname2' where DEFname is the DEF name of contained nodes in both sets.</div><div><br></div><div>So ROUTES from interpolators to transforms. joints or other targets would just need to replace the fromNode with the generated DEF name from MMixer.</div><div><br></div><div>I think a potential SET, MROUTE and MMixer could be implemented as a Macro preprocessing step converting to (many) ROUTEs and Mixer, perhaps initially using Metadata.</div><div><br></div><div>--</div><div><br></div><div>Another idea is to have somehow an Accumulator as an intermediate node which can accept and sum up contributions of inputs per cycle. But that requires more clear thinking.</div><div><br></div><div>-Andreas</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto"><div data-smartmail="gmail_signature" dir="auto">---on the phone---</div><br><div class="gmail_quote" dir="auto"><div dir="ltr">On Sun, Feb 3, 2019, 3:05 PM Michalis Kamburelis <<a href="mailto:michalis.kambi@gmail.com" target="_blank">michalis.kambi@gmail.com</a> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Brutzman, Donald (Don) (CIV) <<a href="mailto:brutzman@nps.edu" rel="noreferrer" target="_blank">brutzman@nps.edu</a>> wrote:<br>
> b. Michalis your animation cross-fading is really interesting. Perhaps it can be conceptualized declaratively as type-aware Mixer nodes in the X3D Event Utilities component? We can currently animate any data type, such functionality would be a super addition for authors if it can fit into event chains. Perhaps designing a new node prototype is a good way to proceed?<br>
<br>
The Mixer node as proposed by Andreas looks good, i.e. it's something<br>
simple to describe in the specification and easy to implement.<br>
<br>
That said, my approach for cross-fading (without any new nodes,<br>
instead with new internal mechanism in X3D player to propagate "events<br>
that are applied only partially") has some advantages over adding<br>
"Mixer" nodes. Basically, if you want to achieve cross-fading between<br>
any 2 animations in an X3D file, you will need to add a *lot* of Mixer<br>
nodes, and you will need a code to determine proper locations where to<br>
insert these Mixer nodes automatically.<br>
<br>
To explain this better:<br>
<br>
The correspondence between animations and TimeSensors is trivial: in<br>
X3D, one animation *is* one TimeSensor. The correspondence between<br>
animations and interpolators is more complicated: a TimeSensor may be<br>
routed to multiple interpolators.<br>
<br>
To complicate matters further, in theory the same interpolator node<br>
may even be reused in X3D between different animations (may receive<br>
input from multiple TimeSensors). Although my Spine JSON -> X3D<br>
conversion doesn't use this sharing, and glTF -> X3D conversion also<br>
probably will not.<br>
<br>
To add the Mixer nodes to cross-fade from animation A to B, one needs<br>
to trace all the outgoing routes of TimeSensors A and B, and place<br>
appropriate Mixer node to cross-fade 2 interpolators (when both<br>
animations affect the same bone) or fade-in (when some bone is<br>
affected only by new animation) or fade-out (when some bone is<br>
affected only by the old animation).<br>
<br>
Example:<br>
<br>
- Animation A is 1 TimeSensor that sends values to 10<br>
Position/OrientationInterpolator nodes, that in turn send values to 10<br>
Transform nodes.<br>
<br>
- Animation B is a different TimeSensor, with different 10<br>
Position/OrientationInterpolator nodes. They control a set of 10<br>
Transform nodes, some of them are also controlled by A, some are not<br>
(and some Transform nodes controlled by A are not controlled by B).<br>
<br>
So you need to add between 10 and 20 Mixer nodes to cross-fade from A to B.<br>
<br>
Now if you have 10 animations in a model (a modest number for an<br>
average game character in our game "The Unholy Society" :) ), then you<br>
need quite a lot of Mixer nodes, for every possible animation A -><br>
animation B combination. Namely, 10 * 9 * random(10, 20) ~= 1350 .<br>
That's a lot of new nodes! :)<br>
<br>
This is assuming that all nodes and routes are added at the loading<br>
stage, without changing X3D graph later. You could alternatively add<br>
the necessary nodes+routes "on demand", so starting a cross-fade<br>
animation would add 10-20 new nodes, as necessary. Or you could create<br>
a pool of Mixer nodes without connecting routes, and attach their<br>
routes dynamically. Adding or removing routes at runtime has almost<br>
zero cost in CGE, possibly in other X3D players too, so this may be<br>
OK.<br>
<br>
None of this is saying "we cannot do that". I agree that Mixer node<br>
would be worthy addition to the X3D specification. But I'm thinking<br>
out load, pointing out practical *possible* problems with using<br>
"Mixer" node for cross-fading on a large scale, and explaining why my<br>
approach (without new nodes, but with internal possibibility to<br>
"propagate event with partial effect") may still make sense for my<br>
use-case :)<br>
<br>
Regards,<br>
Michalis<br>
</blockquote></div></div></div>
</div>