Monday, April 23, 2012

Movimentum - 3-d or not 3-d

Before I think a little bit about the 3d topic, I confess I have played with the grammar somewhat. I want to introduce vector variables and also use the special variable _ for vectors - but when I added this to vectorexpr5, the grammar got ambiguous. So I simplified (or "simplified"?) the vector constraints in the same way as the scalar ones:

    constraint returns [Constraint result]
      : a=anchor // <----- was v1=vectorexpr up to now!
        '='
        v=vectorexpr
        ';'              { result = ...; }
      | i=IDENT
        '='
        s=scalarexpr
        ';'              { result = ...; }
      ...

This disallows "very implicit constraints" - I'll see when I need them. On the other hand, it introduces a clear key also for each vector constraint, which is necessary for the Idea introduced at the end of this posting.

But now onwards to the 3d question. In the "what I want list" over there, there was also an item
  • 2D only. Maybe we have 3D ideas later - not now (however, I think I'll give them vectors 3 coordinates from the start).
I have dodged this up to now. But among my ideas on what I want to animate, there are at least a few mechanisms that are three-dimensional:
  • The valve gear for the center cylinder of UP's 4-12-2 engines, 
  • or the lever train from the route lever to the locking bar in a German "Einheitsstellwerk".
How would one explain these? My idea would be about as follows: Start with 2d explanations - e.g. the standard Walschaerts gear -, but then "zoom out" to present a view on the 3d mechanism. But .... ahhhh ... that means that not only the mechanism has to be 3d, but also the camera's movement!

And this leads to a solution to a problem that has sat in the back of my mind for all that time: A useful animated explanation at times also needs to zoom into some part of the moving mechanism - and I could not see how I could integrate this zooming with the moving mechanism in the script: How can I "scale part of the mechanism"?? But of course: This scaling is not part of the moving mechanism, but of the camera's moving around - which is a completely separate script, probably even with special operations like "zoom center part (of 'diameter' 15 degrees)" or the like, which do not make sense for the mechanism per se. I'll not delve into this "camera script (language)" for the moment, but it will have to be done ...

Another 3d question: Where do the objects ("things") come from? For 2d things, there are standard formats even I know of (GIF with transparency, for example). But are there standard 3d formats which can readily be loaded and rendered by .Net? I do not know, and for the moment, I'll ignore this topic (I'll ask Dennis when I see him next time :) ). The examples above, at least, can be readily explained with "paper-thick 2d objects," which are projected onto a camera moving in 3d.

And as I do now have a somewhat clear understanding of the very limited 3d capabilities Movimentum should have, I'll upgrade my vectors to 3 coordinates!

Here are the changes to ConstVector - for enhanced usability, I continue to allow two-coordinate vectors:

    constvector returns [ConstVector result]
      :       {{ double x = double.NaN, y = double.NaN, z = 0; }}
        '['
        ('-' c=constscalar  { x = -c; }
        |    c=constscalar  { x = c; }
        )
        ','
        ('-' c=constscalar  { y = -c; }
        |    c=constscalar  { y = c; }
        )
        ( ','
          ('-' c=constscalar  { z = -c; }
          |    c=constscalar  { z = c; }
          )
        )?
 
        ']'                 { result = new ConstVector(x,y,z); }
      ;

    constscalar returns [double result]
      : n=number            { result = n; }
      | c=constvector      
        ( X                 { result = c.X; }
        | Y                 { result = c.Y; }
        | Z                 { result = c.Z; }
        )
      ;

with a simple lexer addition:

    Z :  '.z';

And here is the change to Vector:

    vector returns [Vector result]
      : '['
        s1=scalarexpr
        ','
        s2=scalarexpr
        ( ','
          s3=scalarexpr
        )?

        ']' { result = new Vector(s1, s2, s3 ?? new Constant(0)); }
      ;

Both changes, of course, require corresponding changes in the constructors as well as the Equals() and GetHashcode() methods of the mentioned model classes. After I implemented these changes and upgraded a few test cases (I do not allow default parameters - the model is not an API!), all the tests ran without a hitch!

No comments:

Post a Comment