使用指针清理导入程序

Assimp importer cleanup with pointers

本文关键字:导入 程序 指针      更新时间:2023-10-16

我正在尝试使用 Assimp 导入一些动画文件并将它们添加到现有动画列表中。但是,我在使用 aiAnimation->mChannels(类型 aiNodeAnim**(时遇到了问题,因为当我的函数返回时,我的新 aiAnimation 对象的 mChannels 指针无效。这是因为 Assimp 的进口商在被销毁时会自行清理。我需要的是复制通道,以便在导入程序超出范围时不会删除它们。

这是我的动画追加函数,它按我的预期更新,但在从函数返回时产生运行时异常"引擎.exe触发了断点"。

void Animation::AddAnimation(const char* p_filePath)
{
    Assimp::Importer m_importer;
    const aiScene* m_scene = m_importer.ReadFile(p_filePath,
        aiProcess_CalcTangentSpace |
        aiProcess_Triangulate |
        aiProcess_JoinIdenticalVertices |
        aiProcess_SortByPType | aiProcess_GenSmoothNormals);

    for (int i = 0; i < m_scene->mNumAnimations; ++i)
    {
        aiAnimation* m_newAnimation = new aiAnimation(*m_scene->mAnimations[i]);
        m_newAnimation->mName = m_scene->mAnimations[i]->mName;
        m_newAnimation->mDuration = m_scene->mAnimations[i]->mDuration;
        m_newAnimation->mTicksPerSecond = m_scene->mAnimations[i]->mTicksPerSecond;
        m_newAnimation->mNumChannels = m_scene->mAnimations[i]->mNumChannels;
        if (m_scene->mAnimations[i]->mChannels != NULL)
        {
            aiNodeAnim* m_channels = *m_scene->mAnimations[i]->mChannels;
            *m_newAnimation->mChannels = new aiNodeAnim[m_scene->mAnimations[i]->mNumChannels];
            for (int j = 0; j < m_scene->mAnimations[i]->mNumChannels; ++j)
            {
                m_newAnimation->mChannels[j] = new aiNodeAnim();
                m_newAnimation->mChannels[j] = &m_channels[j];
            }
        }
        g_channels = m_newAnimation->mChannels;
        g_animations.push_back(m_newAnimation);
    }
}

我没有足够的声誉来评论,但你是问是否需要单独复制动画频道吗?答案是肯定的,因为如果您尝试对数组m_channels ,甚至数组中的每个条目进行memcpy,则无法确定它们在内存中是否是连续的。您必须手动复制旋转、转换和缩放密钥的每个数组。

顺便说一下,这些代码行

m_newAnimation->mChannels[j] = new aiNodeAnim();
m_newAnimation->mChannels[j] = &m_channels[j];

可能不做你想做的事。在第一行中,您分配空间并初始化新动画,在第二行中,您可以使用导入器通道的地址将其吹走。删除第二行并将 aiNodeAnim 的内容复制到数组中可以解决此问题。