| 911 | } |
| 912 | |
| 913 | inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animation>& animRef, Ref<Buffer>& buffer, const aiNodeAnim* nodeChannel, float ticksPerSecond) |
| 914 | { |
| 915 | // Loop over the data and check to see if it exactly matches an existing buffer. |
| 916 | // If yes, then reference the existing corresponding accessor. |
| 917 | // Otherwise, add to the buffer and create a new accessor. |
| 918 | |
| 919 | size_t counts[3] = { |
| 920 | nodeChannel->mNumPositionKeys, |
| 921 | nodeChannel->mNumScalingKeys, |
| 922 | nodeChannel->mNumRotationKeys, |
| 923 | }; |
| 924 | size_t numKeyframes = 1; |
| 925 | for (int i = 0; i < 3; ++i) { |
| 926 | if (counts[i] > numKeyframes) { |
| 927 | numKeyframes = counts[i]; |
| 928 | } |
| 929 | } |
| 930 | |
| 931 | //------------------------------------------------------- |
| 932 | // Extract TIME parameter data. |
| 933 | // Check if the timeStamps are the same for mPositionKeys, mRotationKeys, and mScalingKeys. |
| 934 | if(nodeChannel->mNumPositionKeys > 0) { |
| 935 | typedef float TimeType; |
| 936 | std::vector<TimeType> timeData; |
| 937 | timeData.resize(numKeyframes); |
| 938 | for (size_t i = 0; i < numKeyframes; ++i) { |
| 939 | size_t frameIndex = i * nodeChannel->mNumPositionKeys / numKeyframes; |
| 940 | // mTime is measured in ticks, but GLTF time is measured in seconds, so convert. |
| 941 | // Check if we have to cast type here. e.g. uint16_t() |
| 942 | timeData[i] = static_cast<float>(nodeChannel->mPositionKeys[frameIndex].mTime / ticksPerSecond); |
| 943 | } |
| 944 | |
| 945 | Ref<Accessor> timeAccessor = ExportData(mAsset, animId, buffer, static_cast<unsigned int>(numKeyframes), &timeData[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_FLOAT); |
| 946 | if (timeAccessor) animRef->Parameters.TIME = timeAccessor; |
| 947 | } |
| 948 | |
| 949 | //------------------------------------------------------- |
| 950 | // Extract translation parameter data |
| 951 | if(nodeChannel->mNumPositionKeys > 0) { |
| 952 | C_STRUCT aiVector3D* translationData = new aiVector3D[numKeyframes]; |
| 953 | for (size_t i = 0; i < numKeyframes; ++i) { |
| 954 | size_t frameIndex = i * nodeChannel->mNumPositionKeys / numKeyframes; |
| 955 | translationData[i] = nodeChannel->mPositionKeys[frameIndex].mValue; |
| 956 | } |
| 957 | |
| 958 | Ref<Accessor> tranAccessor = ExportData(mAsset, animId, buffer, static_cast<unsigned int>(numKeyframes), translationData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT); |
| 959 | if ( tranAccessor ) { |
| 960 | animRef->Parameters.translation = tranAccessor; |
| 961 | } |
| 962 | delete[] translationData; |
| 963 | } |
| 964 | |
| 965 | //------------------------------------------------------- |
| 966 | // Extract scale parameter data |
| 967 | if(nodeChannel->mNumScalingKeys > 0) { |
| 968 | C_STRUCT aiVector3D* scaleData = new aiVector3D[numKeyframes]; |
| 969 | for (size_t i = 0; i < numKeyframes; ++i) { |
| 970 | size_t frameIndex = i * nodeChannel->mNumScalingKeys / numKeyframes; |
no test coverage detected