Howto talk:Animate gear scissors using the tracking animation

From FlightGear wiki
Jump to navigation Jump to search

It is really sad that no one knows how to make an example of the "animation Tracking" animation. The animation is really interesting, but it is not explained in an understandable way in the wiki, someone has used it successfully? --Abassign (talk) 19:06, 11 July 2016 (EDT)


Notes about locked-track animations

I've found this page a little difficult to understand, so here's some alternative notes about locked-track animations.


            o a_center
          /
        a
      /
    o slave_center:lock_axis
     \
      b
       \
        o b_center

We want to animate a and b, which involves first modifying one or both of them with simple animations such as rotate or translate, then applying two locked-track animations that rotate each object about the (modified) a_center and b_center points so that they meet at a new slave_center position (with an unchanged lock_axis direction).

The XML specifications for the required locked-track animations contain duplicate and derived data, which i think contributes to making it difficult to understand.

There are a few examples of locked-track animations in https://sourceforge.net/p/flightgear/fgaddon/HEAD/tree/trunk/Aircraft/Aircraft/Citation/Models/Citation-II.xml. These are without parenting, i.e. they do not require that b is a child object of a. I've similarly kept to this non-parenting style, because it seems to be conceptually simpler.

So here's a Python function that can be used to generate the two locked-track XML specifications. It turns out that one only needs 6 pieces of information.

    def locked_track_animation(
            a_name,
            a_center,
            b_name,
            b_center,
            slave_center,
            lock_axis,
            ):
        '''
        Returns text for a locked track animation.

            a_name:
                Name of component A.
            a_center:
                Position of center of rotation of A.
            b_name:
                Name of component B.
            b_center:
                Position of center of rotation of B.
            slave_center:
                Position of hinge linking A and B.
            lock_axis:
                Axis of hinge.
        '''
        def ac2xml( p):
            '''
            Convert from .ac coordinates to Flightgear .xml
            coordinates.
            '''
            return numpy.array( ( p[0], -p[2], p[1]))

        a_center = ac2xml( a_center)
        b_center = ac2xml( b_center)
        slave_center = ac2xml( slave_center)
        lock_axis = ac2xml( lock_axis)

        track_axis = b_center - a_center

        text = textwrap.dedent( f'''
                <animation>
                    <type>locked-track</type>
                    <object-name>{a_name}</object-name>
                    <center>
                        <x-m>{a_center[0]}</x-m>
                        <y-m>{a_center[1]}</y-m>
                        <z-m>{a_center[2]}</z-m>
                    </center>
                    <lock-axis>
                        <x>{lock_axis[0]}</x>
                        <y>{lock_axis[1]}</y>
                        <z>{lock_axis[2]}</z>
                    </lock-axis>
                    <track-axis>
                        <x>{track_axis[0]}</x>
                        <y>{track_axis[1]}</y>
                        <z>{track_axis[2]}</z>
                    </track-axis>
                    <slave-center>
                        <x-m>{slave_center[0]}</x-m>
                        <y-m>{slave_center[1]}</y-m>
                        <z-m>{slave_center[2]}</z-m>
                    </slave-center>
                    <target-name>{b_name}</target-name>
                    <target-center>
                        <x-m>{b_center[0]}</x-m>
                        <y-m>{b_center[1]}</y-m>
                        <z-m>{b_center[2]}</z-m>
                    </target-center>
                </animation>

                <animation>
                    <type>locked-track</type>
                    <object-name>{b_name}</object-name>
                    <center>
                        <x-m>{b_center[0]}</x-m>
                        <y-m>{b_center[1]}</y-m>
                        <z-m>{b_center[2]}</z-m>
                    </center>
                    <lock-axis>
                        <x>{-lock_axis[0]}</x>
                        <y>{-lock_axis[1]}</y>
                        <z>{-lock_axis[2]}</z>
                    </lock-axis>
                    <track-axis>
                        <x>{-track_axis[0]}</x>
                        <y>{-track_axis[1]}</y>
                        <z>{-track_axis[2]}</z>
                    </track-axis>
                    <slave-center>
                        <x-m>{slave_center[0]}</x-m>
                        <y-m>{slave_center[1]}</y-m>
                        <z-m>{slave_center[2]}</z-m>
                    </slave-center>
                    <target-name>{a_name}</target-name>
                    <target-center>
                        <x-m>{a_center[0]}</x-m>
                        <y-m>{a_center[1]}</y-m>
                        <z-m>{a_center[2]}</z-m>
                    </target-center>
                </animation>

                ''')
        return text
  • The various positions and axes should be as in the .ac file, i.e. before any animations have been applied.
  • Note how we can derive track_axis from a_center and b_center, and use -ve versions of lock_axis and track_axis in the second animation.
  • I'm not sure it's currently possible to use geometry objects for the three positions and one axis that are required.

Here's an example call:

   lta = locked_track_animation(
           a_name='gear_pusher_lo.l',
           a_center=gear_pushed_bottom,
           b_name='gear_pusher_hi.l',
           b_center=gear_pusher_top,
           slave_center=gear_pusher_mid,
           lock_axis=(0, 0, 1),
           )

A simpler syntax?

Given that typical use of a locked-track animation only uses 6 pieces of information, it might be worth adding in support for a different XML specification that takes these 6 items only.

So maybe we could define a new animation called hinge which looks like:

    <animation>
        <type>hinge</type>
        <a>
            <object-name>foo<object-name>
            <center>
                <x-m>...</x-m>
                <y-m>...</y-m>
                <z-m>...</z-m>
            </center>
        </a>
        <b>
            <object-name>bar<object-name>
            <center>
                <x-m>...</x-m>
                <y-m>...</y-m>
                <z-m>...</z-m>
            </center>
        </b>
        <hinge>
            <center>
                <x-m>...</x-m>
                <y-m>...</y-m>
                <z-m>...</z-m>
            </center>
            <axis>
                <x-m>...</x-m>
                <y-m>...</y-m>
                <z-m>...</z-m>
            </axis>
        </b>
    </animation>

Internally this would be converted into two locked-track animations.

If we then add support for specifying a position using a geometry object, like we already do with axes, this could become:

    <animation>
        <type>hinge</type>
        <a>
            <object-name>foo</object-name>
            <center>
                <object-name>foo-center</object-name>
            </center>
        </a>
        <b>
            <object-name>bar</object-name>
            <center>
                <object-name>bar-center</object-name>
            </center>
        </b>
        <hinge>
            <center>
                <object-name>foo.bar.hinge-center</object-name>
            </center>
            <axis>
                <object-name>foo.bar.hinge-axis</object-name>
            </axis>
        </b>
    </animation>

Finally we could use the existing default -axis suffix and create a new default -center suffix to give a very concise syntax:

    <animation>
        <type>hinge</type>
        <a>
            <object-name>foo</object-name>
            <!-- we use first vertex of object 'foo-center' as center. -->
        </a>
        <b>
            <object-name>bar</object-name>
            <!-- we use first vertex of object 'bar-center' as center. -->
        </b>
        <hinge>
            <object-name>foo.bar.hinge</object-name>
            <!-- we use first two vertices of
            foo.bar.hinge-axis as axis (in the usual way) and
            use the mid-point as the hinge center. -->
        </b>
    </animation>

Or maybe avoid the new -center convention and instead use the first vertex of a *-axis object?

Cgdae (talk) 21:47, 12 February 2022 (UTC)