FBX animation problem
#11
I again test this file with the latest version and unfortunately, it still doesn't work.

Hope this will be fixed in the next releases
#12
Yes, it seems that the native Assimp importer does not correctly read the animation.
I would recommend you to report that issue on GitHub for the project: https://github.com/assimp/assimp/issues
Andrej Benedik
#13
Some other customer also had problems with importing skeletal animation from fbx files (animation file was created by Mixamo). He found out that if he imports the fbx file into Blender and then exports it into glTF 2 (.glb file) then he can import the gb file and the animation is played correctly.

I hope that the native Assimp importer will be improved in the future to correctly read the animation (the version from 2023-07-04 still does not work correctly for those files).
Andrej Benedik
#14
This is almost fixed in version 5.4
But you need to change something so that it works as it should
1) Change AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS to false
Code:
mSettings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, false);

2) add the following code to FBXConverter.cpp
Code:
    ConvertGlobalSettings();
    FixSceneRotation(out); // insert before  TransferDataToScene
    TransferDataToScene();
/*
*  Imported Model is rotated by 90 degrees
*  https://github.com/assimp/assimp/issues/849#issuecomment-875475292
*/
void FBXConverter::FixSceneRotation(const aiScene *pScene) {
    if (pScene->mMetaData) {
        int32_t UpAxis = 1, UpAxisSign = 1, FrontAxis = 2, FrontAxisSign = 1, CoordAxis = 0, CoordAxisSign = 1;
        double UnitScaleFactor = 1.0;
        for (unsigned MetadataIndex = 0; MetadataIndex < pScene->mMetaData->mNumProperties; ++MetadataIndex) {
            if (strcmp(pScene->mMetaData->mKeys[MetadataIndex].C_Str(), "UpAxis") == 0) {
                pScene->mMetaData->Get<int32_t>(MetadataIndex, UpAxis);
            }
            if (strcmp(pScene->mMetaData->mKeys[MetadataIndex].C_Str(), "UpAxisSign") == 0) {
                pScene->mMetaData->Get<int32_t>(MetadataIndex, UpAxisSign);
            }
            if (strcmp(pScene->mMetaData->mKeys[MetadataIndex].C_Str(), "FrontAxis") == 0) {
                pScene->mMetaData->Get<int32_t>(MetadataIndex, FrontAxis);
            }
            if (strcmp(pScene->mMetaData->mKeys[MetadataIndex].C_Str(), "FrontAxisSign") == 0) {
                pScene->mMetaData->Get<int32_t>(MetadataIndex, FrontAxisSign);
            }
            if (strcmp(pScene->mMetaData->mKeys[MetadataIndex].C_Str(), "CoordAxis") == 0) {
                pScene->mMetaData->Get<int32_t>(MetadataIndex, CoordAxis);
            }
            if (strcmp(pScene->mMetaData->mKeys[MetadataIndex].C_Str(), "CoordAxisSign") == 0) {
                pScene->mMetaData->Get<int32_t>(MetadataIndex, CoordAxisSign);
            }
            if (strcmp(pScene->mMetaData->mKeys[MetadataIndex].C_Str(), "UnitScaleFactor") == 0) {
                pScene->mMetaData->Get<double>(MetadataIndex, UnitScaleFactor);
            }
        }

        aiVector3D upVec, forwardVec, rightVec;

        upVec[UpAxis] = UpAxisSign * (float)UnitScaleFactor;
        forwardVec[FrontAxis] = FrontAxisSign * (float)UnitScaleFactor;
        rightVec[CoordAxis] = CoordAxisSign * (float)UnitScaleFactor;

        aiMatrix4x4 mat(rightVec.x, rightVec.y, rightVec.z, 0.0f,
                upVec.x, upVec.y, upVec.z, 0.0f,
                forwardVec.x, forwardVec.y, forwardVec.z, 0.0f,
                0.0f, 0.0f, 0.0f, 1.0f);
        pScene->mRootNode->mTransformation = mat;
        //pScene->mRootNode->
    }
}
And now all my models, static and animated work as expected!
I hope it will be useful.
#15
Please leave comments if any nuances can improve the code.
I don't know how universal this solution is.
#16
Alex3d, I am really happy to hear that all my models, static and animated work as expected.

But if I understand you correctly, then for everything to work, the 2 additional changes to the code are required on top of Assimp v5.4 changes.

The first change sets the default value of AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS property to false (from true). I do not like such a change. Therefore I have added a simple way to set those properties in the AssimpWpfImporter. There is now a SetConfig method where you can set all the importer properties, for example:

Code:
assimpWpfImporter.SetConfig(new global::Assimp.Configs.FBXPreservePivotsConfig(preservePivots: false));
// this is the same as:
assimpWpfImporter.SetConfig(new global::Assimp.Configs.BooleanPropertyConfig("IMPORT_FBX_PRESERVE_PIVOTS", false));

This will be part of the new Ab3d.PowerToys.Assimp library that will be released this week.


I am also curious about your second code change. There you add FixSceneRotation method that is called before call to TransferDataToScene.

I see that the new Assimp version already defines the correctRootTransform method that is the same as your  FixSceneRotation method (see: #5494 PR). So the main difference between the official source and your recommendation is that in the official source the correctRootTransform method is called after the call to TransferDataToScene but in your change this method is called before the call to TransferDataToScene.

Are you sure that this is correct? In this case it would be good to create a PR on Assimp's GitHub so that others can also check that.

I am going to publish the compiled native Assimp library with the next version of Ab3d.PowerToys, but I am not sure if I should include the official version 5.4 (I will probably do that) or add your recommended change to the source and publish that version.
Andrej Benedik
#17
I did not go into details.
I found a few users with similar problems and used their solutions.
You can see the link above the code I provided to one of the discussions of the model rotation problem
https://github.com/assimp/assimp/issues/...-875475292
Quote:......new Assimp version already defines the correctRootTransform method that is the same as your FixSceneRotation method

In my case, the problem was solved precisely after placing FixSceneRotation before the TransferDataToScene method.
  


Forum Jump:


Users browsing this thread:
1 Guest(s)