Thursday, November 18, 2010

How to merge animations?

There are two basic problems with copying animations from one figure to another:
  1. The skeletons do not match. First, the body proportions are off, especially if converting between male/female or realistic/stylized characters. And secondly, the non-obvious bones are often arranged completely differently. By obvious bones I mean the ones like armbones, shins and so on, that connect two visible joints. Non-obvious bones are hidden and their joints are not immediately visible - like backbone or shoulders. Thus the exact number and placement of such bones may vary, depending on how realistic and fluid motion is needed and how it is achieved.
  2. The bone orientations do not match. Even for bones that are perfectly aligned, like arms, the local coordinate systems can be very different and thus the transformations from one skeleton cannot be immediately carried over to another.
 How to deal with it?

In Khayyam I am currently doing the following procedure:
  1. Create one-to-one links between the well-defined bones of each skeleton - i.e. legs, shins, arms, forearms and heads. These function as anchors for matching body movements via IK solver.
  2. Pick rootmost joints of matched bones, i.e. hips and shoulders as anchor point pairs.
  3. Find the bone chain leading to last common ancestor of such pairs (starting from the point where previous chain ended). I.e. we get chains like these:
    3.1. Center_of_Mass -> Skeleton_Root -> Pelvis
    3.2. Lower_Backbone -> Upper_Backbone -> Chest
  4. Adjust chains, starting from rootmost, as closely as possible to anchor points using IK solver.
  5. Point all well-defined bones to the same direction as the originals, using IK solver

As you can see, it basically works, although some constraints on joint movement would be nice.

A demo video showing how dancing moves for DAZ skeleton can be imported to Esk Anderson figure

Sunday, November 7, 2010

About C++

I have had love/hate relationship with C++ from the time I started using it extensively about nine years ago. Before that everything was C - for example Sodipodi was 99.9% written in C (the only exception was the interface to KDE file dialogs). Those were good old times...

The learning of C++ was mostly one big frustration. Few beautiful and useful features - buried in clumsy, unintuitive and ugly mess. So after trying out and throwing away one feature after another, I mostly joined the C with classes crowd. This is the style used in Khayyam/Miletos/Elea code. But even for this minor subset of features, the language is just implemented plain wrong. Some completely elementary, clean and logical things are missing - and on the other hand - extremely clumsy, opaque and hard to use features are present.

So following is my list of things I'll one day implement in my own C Successor(TM) language.
  1. Keep classes and struct separate. Structs should be POD, classes should ALWYAS have pointer to RTI. So no virtual methods for struct - and who in his right mind will miss these?
  2. Keep memory layout standardized. Seriously. Probably all C++ variants implement things in one way - but the specification refuses to fix things once and for all.
    • Classes are struct(ure)s. Like in Java. Standardized containers having function pointers for virtual methods, RTI information, link to parent class and so on.
    • All object instances have hidden data field in first position, that is - you guess it - pointer to class struct(ure).
    • All nonstatic methods should have pointer to class instance as hidden first parameter. So you can call class method from C. It is implemented this way anyways - but why force people to jump through loops to use it.
  3. Keep meta-language separate from core. Implement two-pass compiling or something (in addition to preprocessor).
    • Operator overloading should be specified in some meta-language. This would allow really useful things, like implementing separate dot and cross operators for vectors and so on. It should be transparently translated into proper C code during metalanguage parsing pass and then compiled by normal C/C++ compiler.
    • Templates should be specified in proper metalanguage instead of "yet another hack on top of C syntax" and translated into normal C code during compilation.
And for extra sugar - allow overloading the virtual method call operation. So I can actually subclass object systems from other languages without writing countless ugly wrapper classes.

Obligatory screenshot - Ichiro having break in a forest (needs better lighting actually)