Simplifying Assimp 3.1-imported FBX scenes

Started by
3 comments, last by Husbj 9 years ago

I've recently updated to version 3.1 of the Assimp library for importing 3D models into my game engine.

With this came support for importing FBX files which is nice, however the FBXImporter attempts to retain a lot of separate settings that are present in the file but that do not have any direct correspondence in the aiNode / aiNodeAnimation structs. This is then achieved by creating a lot of extraneous nodes for carrying static transforms for things like pivots and offsets to all the separate scaling, rotation and translation steps. Naturally this creates a pretty overly complicated node hierarchy that both uses a considerable amount more memory and is slower to evaluate for animation purposes. The additional transforms won't be changed by my application at all so I don't need to retain them if they could be transformed into a more concise representation. I thought about just having these offset matrices being part of my Node class but apparently there are potentially up to 10+ of them, so that would be a big waste considering most of them would be set to the identity matrix at most times anyway.

As such I have been thinking about trying to tidy it up a bit by preprocessing these transforms into the animation channels, however I am not entirely sure whether this is feasible. Can you even transform things like quaternions and scale vectors (which are stored as vectors instead of matrices in order to facilitate interpolation) by matrices?

If anybody have some pointers on where to start with this kind of undertaking I would greatly appreciate hearing them.

Advertisement
You can put the scale factors on the matrix Diagonal like this http://en.m.wikipedia.org/wiki/Scaling_(geometry)

To convert a quaternion to a matrix use http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/

Well, to further specify the problem at hand I essentially want to turn this:


transform = translation * rotationOffset * rotationPivot * preRotationOffset * rotation * postRotationOffset * rotationPivotInverse * scalingOffset * scalingPivot * scaling * scalingPivotInverse;

into the more simple, traditional three components scaling, rotation, translation such that the following statement would hold true assuming the above assignment of transform:


transform == _scaling * _rotation * _translation;

Now that I see it in front of me... building the first matrix from the input data and then decomposing it into the SRT components would surely not work would it? That seems way too easy mellow.png

(I have put this problem aside for the last couple of weeks so I don't really remember but I can't believe I wouldn't have examined that possibility).

I'm not sure why you want to do this. With any kind of skeletal animation you'll want to keep track of your pivot points so that your rotations, scaling and translations are applied about the correct locations in 3D space. Working with a simplified _scaling * _rotation * _translation matrix transform really limits you on the kind of transformations you can do.

Ah yes, well there is a single offset / pivot matrix per node. Those outlined up there are in excess to them.

Basically I have built my animation system around this matFinalTransform = (parentNode ? parentNode->matFinalTransform : IdentityMatrix) * matOffset * matScaling * matRotation * matTranslation based on the import structure exposed by the Assimp library. All 3D models imported using Assimp 3.0 adheres to this format so I just have the single conversion of it into my own format. However, the FBX Importer that comes with Assimp 3.1.x+ imports a more complex node hierarchy where all the matrices above are added together by linking them in sub-trees per actual "master node". Because this results in many times more nodes than the actual model has this, while technically working, is inefficient to use. So therefore I want to convert it to the simplified structure mentioned above. I should also point out that these sub-node hierarchies do contain individual offset matrices for not necessarily all but many of the nodes that aren't just set to the identity matrix so it isn't as simple as them just replacing that.

An example hierarchy might be:


Root
  - Spine01
    - Spine01_$Complex$_Translation [offset matrix != identity]
      - Spine01_$Complex$_RotationOffset [offset matrix != identity]
        - Spine01_$Complex$_RotationPivot [offset matrix == identity]
          - Spine01_$Complex$_PreRotationOffet [offset matrix == identity]
            - Spine01_$Complex$_Rotation [offset matrix != identity]
              - Spine01_$Complex$_PostRotationOffset [offset matrix != identity, no animation keys]
                - Spine01_$Complex$_RotationPivotInverse [offset matrix != identity, no keys]
                  - Spine01_$Complex$_ScalingOffset [offset matrix == identity, single key]
                    - Spine01_$Complex$_ScalingPivot [offset matrix != identity, no keys]
                      - Spine01_$Complex$_Scaling [offset matrix != identity]
                        - Spine01_$Complex$_ScalingPivotInverse [offset matrix != identity, no keys]
  - Spine02
    - Spine01_$Complex$_Translation
      ... and so on

As far as I can tell, all of the special offset ones aren't animated but they either store their offset as a single key, or in the assimp-assigned offset matrix of the node, OR both of those carry different, non-identity data.

The fact that you can import an FBX file into most modelling software and then export it to another format that uses the offset + SRT transform order bespeaks that it is indeed possible to do this conversion.

Basically I guess the FBX is imported with that data because it might be interesting to preserve for modelling applications but for use in a realtime game it just isn't reasonable to have meshes with 400+ "joints" like that.

This topic is closed to new replies.

Advertisement