/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------

Copyright (c) 2006-2017, assimp team


All rights reserved.

Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:

* Redistributions of source code must retain the above
  copyright notice, this list of conditions and the
  following disclaimer.

* Redistributions in binary form must reproduce the above
  copyright notice, this list of conditions and the
  following disclaimer in the documentation and/or other
  materials provided with the distribution.

* Neither the name of the assimp team, nor the names of its
  contributors may be used to endorse or promote products
  derived from this software without specific prior
  written permission of the assimp team.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/

/** @file PretransformVertices.cpp
 *  @brief Implementation of the "PretransformVertices" post processing step
*/


#include "PretransformVertices.h"
#include "ProcessHelper.h"
#include <assimp/SceneCombiner.h>
#include "Exceptional.h"

using namespace Assimp;

// some array offsets
#define AI_PTVS_VERTEX 0x0
#define AI_PTVS_FACE 0x1

// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
PretransformVertices::PretransformVertices()
:   configKeepHierarchy (false), configNormalize(false), configTransform(false), configTransformation()
{
}

// ------------------------------------------------------------------------------------------------
// Destructor, private as well
PretransformVertices::~PretransformVertices()
{
    // nothing to do here
}

// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool PretransformVertices::IsActive( unsigned int pFlags) const
{
    return  (pFlags & aiProcess_PreTransformVertices) != 0;
}

// ------------------------------------------------------------------------------------------------
// Setup import configuration
void PretransformVertices::SetupProperties(const Importer* pImp)
{
    // Get the current value of AI_CONFIG_PP_PTV_KEEP_HIERARCHY, AI_CONFIG_PP_PTV_NORMALIZE,
    // AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION and AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION
    configKeepHierarchy = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_KEEP_HIERARCHY,0));
    configNormalize = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_NORMALIZE,0));
    configTransform = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION,0));

    configTransformation = pImp->GetPropertyMatrix(AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION, aiMatrix4x4());
}

// ------------------------------------------------------------------------------------------------
// Count the number of nodes
unsigned int PretransformVertices::CountNodes( aiNode* pcNode )
{
    unsigned int iRet = 1;
    for (unsigned int i = 0;i < pcNode->mNumChildren;++i)
    {
        iRet += CountNodes(pcNode->mChildren[i]);
    }
    return iRet;
}

// ------------------------------------------------------------------------------------------------
// Get a bitwise combination identifying the vertex format of a mesh
unsigned int PretransformVertices::GetMeshVFormat( aiMesh* pcMesh )
{
    // the vertex format is stored in aiMesh::mBones for later retrieval.
    // there isn't a good reason to compute it a few hundred times
    // from scratch. The pointer is unused as animations are lost
    // during PretransformVertices.
    if (pcMesh->mBones)
        return (unsigned int)(uint64_t)pcMesh->mBones;


    const unsigned int iRet = GetMeshVFormatUnique(pcMesh);

    // store the value for later use
    pcMesh->mBones = (aiBone**)(uint64_t)iRet;
    return iRet;
}

// ------------------------------------------------------------------------------------------------
// Count the number of vertices in the whole scene and a given
// material index
void PretransformVertices::CountVerticesAndFaces( aiScene* pcScene, aiNode* pcNode, unsigned int iMat,
    unsigned int iVFormat, unsigned int* piFaces, unsigned int* piVertices)
{
    for (unsigned int i = 0; i < pcNode->mNumMeshes;++i)
    {
        aiMesh* pcMesh = pcScene->mMeshes[ pcNode->mMeshes[i] ];
        if (iMat == pcMesh->mMaterialIndex && iVFormat == GetMeshVFormat(pcMesh))
        {
            *piVertices += pcMesh->mNumVertices;
            *piFaces += pcMesh->mNumFaces;
        }
    }
    for (unsigned int i = 0;i < pcNode->mNumChildren;++i)
    {
        CountVerticesAndFaces(pcScene,pcNode->mChildren[i],iMat,
            iVFormat,piFaces,piVertices);
    }
}

// ------------------------------------------------------------------------------------------------
// Collect vertex/face data
void PretransformVertices::CollectData( aiScene* pcScene, aiNode* pcNode, unsigned int iMat,
    unsigned int iVFormat, aiMesh* pcMeshOut,
    unsigned int aiCurrent[2], unsigned int* num_refs)
{
    // No need to multiply if there's no transformation
    const bool identity = pcNode->mTransformation.IsIdentity();
    for (unsigned int i = 0; i < pcNode->mNumMeshes;++i)
    {
        aiMesh* pcMesh = pcScene->mMeshes[ pcNode->mMeshes[i] ];
        if (iMat == pcMesh->mMaterialIndex && iVFormat == GetMeshVFormat(pcMesh))
        {
            // Decrement mesh reference counter
            unsigned int& num_ref = num_refs[pcNode->mMeshes[i]];
            ai_assert(0 != num_ref);
            --num_ref;
            // Save the name of the last mesh
            if (num_ref==0)
            {
                pcMeshOut->mName = pcMesh->mName;
            }

            if (identity)   {
                // copy positions without modifying them
                ::memcpy(pcMeshOut->mVertices + aiCurrent[AI_PTVS_VERTEX],
                    pcMesh->mVertices,
                    pcMesh->mNumVertices * sizeof(aiVector3D));

                if (iVFormat & 0x2) {
                    // copy normals without modifying them
                    ::memcpy(pcMeshOut->mNormals + aiCurrent[AI_PTVS_VERTEX],
                        pcMesh->mNormals,
                        pcMesh->mNumVertices * sizeof(aiVector3D));
                }
                if (iVFormat & 0x4)
                {
                    // copy tangents without modifying them
                    ::memcpy(pcMeshOut->mTangents + aiCurrent[AI_PTVS_VERTEX],
                        pcMesh->mTangents,
                        pcMesh->mNumVertices * sizeof(aiVector3D));
                    // copy bitangents without modifying them
                    ::memcpy(pcMeshOut->mBitangents + aiCurrent[AI_PTVS_VERTEX],
                        pcMesh->mBitangents,
                        pcMesh->mNumVertices * sizeof(aiVector3D));
                }
            }
            else
            {
                // copy positions, transform them to worldspace
                for (unsigned int n = 0; n < pcMesh->mNumVertices;++n)  {
                    pcMeshOut->mVertices[aiCurrent[AI_PTVS_VERTEX]+n] = pcNode->mTransformation * pcMesh->mVertices[n];
                }
                aiMatrix4x4 mWorldIT = pcNode->mTransformation;
                mWorldIT.Inverse().Transpose();

                // TODO: implement Inverse() for aiMatrix3x3
                aiMatrix3x3 m = aiMatrix3x3(mWorldIT);

                if (iVFormat & 0x2)
                {
                    // copy normals, transform them to worldspace
                    for (unsigned int n = 0; n < pcMesh->mNumVertices;++n)  {
                        pcMeshOut->mNormals[aiCurrent[AI_PTVS_VERTEX]+n] =
                            (m * pcMesh->mNormals[n]).Normalize();
                    }
                }
                if (iVFormat & 0x4)
                {
                    // copy tangents and bitangents, transform them to worldspace
                    for (unsigned int n = 0; n < pcMesh->mNumVertices;++n)  {
                        pcMeshOut->mTangents  [aiCurrent[AI_PTVS_VERTEX]+n] = (m * pcMesh->mTangents[n]).Normalize();
                        pcMeshOut->mBitangents[aiCurrent[AI_PTVS_VERTEX]+n] = (m * pcMesh->mBitangents[n]).Normalize();
                    }
                }
            }
            unsigned int p = 0;
            while (iVFormat & (0x100 << p))
            {
                // copy texture coordinates
                memcpy(pcMeshOut->mTextureCoords[p] + aiCurrent[AI_PTVS_VERTEX],
                    pcMesh->mTextureCoords[p],
                    pcMesh->mNumVertices * sizeof(aiVector3D));
                ++p;
            }
            p = 0;
            while (iVFormat & (0x1000000 << p))
            {
                // copy vertex colors
                memcpy(pcMeshOut->mColors[p] + aiCurrent[AI_PTVS_VERTEX],
                    pcMesh->mColors[p],
                    pcMesh->mNumVertices * sizeof(aiColor4D));
                ++p;
            }
            // now we need to copy all faces. since we will delete the source mesh afterwards,
            // we don't need to reallocate the array of indices except if this mesh is
            // referenced multiple times.
            for (unsigned int planck = 0;planck < pcMesh->mNumFaces;++planck)
            {
                aiFace& f_src = pcMesh->mFaces[planck];
                aiFace& f_dst = pcMeshOut->mFaces[aiCurrent[AI_PTVS_FACE]+planck];

                const unsigned int num_idx = f_src.mNumIndices;

                f_dst.mNumIndices = num_idx;

                unsigned int* pi;
                if (!num_ref) { /* if last time the mesh is referenced -> no reallocation */
                    pi = f_dst.mIndices = f_src.mIndices;

                    // offset all vertex indices
                    for (unsigned int hahn = 0; hahn < num_idx;++hahn){
                        pi[hahn] += aiCurrent[AI_PTVS_VERTEX];
                    }
                }
                else {
                    pi = f_dst.mIndices = new unsigned int[num_idx];

                    // copy and offset all vertex indices
                    for (unsigned int hahn = 0; hahn < num_idx;++hahn){
                        pi[hahn] = f_src.mIndices[hahn] + aiCurrent[AI_PTVS_VERTEX];
                    }
                }

                // Update the mPrimitiveTypes member of the mesh
                switch (pcMesh->mFaces[planck].mNumIndices)
                {
                case 0x1:
                    pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_POINT;
                    break;
                case 0x2:
                    pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_LINE;
                    break;
                case 0x3:
                    pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
                    break;
                default:
                    pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
                    break;
                };
            }
            aiCurrent[AI_PTVS_VERTEX] += pcMesh->mNumVertices;
            aiCurrent[AI_PTVS_FACE]   += pcMesh->mNumFaces;
        }
    }

    // append all children of us
    for (unsigned int i = 0;i < pcNode->mNumChildren;++i) {
        CollectData(pcScene,pcNode->mChildren[i],iMat,
            iVFormat,pcMeshOut,aiCurrent,num_refs);
    }
}

// ------------------------------------------------------------------------------------------------
// Get a list of all vertex formats that occur for a given material index
// The output list contains duplicate elements
void PretransformVertices::GetVFormatList( aiScene* pcScene, unsigned int iMat,
    std::list<unsigned int>& aiOut)
{
    for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
    {
        aiMesh* pcMesh = pcScene->mMeshes[ i ];
        if (iMat == pcMesh->mMaterialIndex) {
            aiOut.push_back(GetMeshVFormat(pcMesh));
        }
    }
}

// ------------------------------------------------------------------------------------------------
// Compute the absolute transformation matrices of each node
void PretransformVertices::ComputeAbsoluteTransform( aiNode* pcNode )
{
    if (pcNode->mParent)    {
        pcNode->mTransformation = pcNode->mParent->mTransformation*pcNode->mTransformation;
    }

    for (unsigned int i = 0;i < pcNode->mNumChildren;++i)   {
        ComputeAbsoluteTransform(pcNode->mChildren[i]);
    }
}

// ------------------------------------------------------------------------------------------------
// Apply the node transformation to a mesh
void PretransformVertices::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)
{
    // Check whether we need to transform the coordinates at all
    if (!mat.IsIdentity()) {

        if (mesh->HasPositions()) {
            for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
                mesh->mVertices[i] = mat * mesh->mVertices[i];
            }
        }
        if (mesh->HasNormals() || mesh->HasTangentsAndBitangents()) {
            aiMatrix4x4 mWorldIT = mat;
            mWorldIT.Inverse().Transpose();

            // TODO: implement Inverse() for aiMatrix3x3
            aiMatrix3x3 m = aiMatrix3x3(mWorldIT);

            if (mesh->HasNormals()) {
                for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
                    mesh->mNormals[i] = (m * mesh->mNormals[i]).Normalize();
                }
            }
            if (mesh->HasTangentsAndBitangents()) {
                for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
                    mesh->mTangents[i]   = (m * mesh->mTangents[i]).Normalize();
                    mesh->mBitangents[i] = (m * mesh->mBitangents[i]).Normalize();
                }
            }
        }
    }
}

// ------------------------------------------------------------------------------------------------
// Simple routine to build meshes in worldspace, no further optimization
void PretransformVertices::BuildWCSMeshes(std::vector<aiMesh*>& out, aiMesh** in,
    unsigned int numIn, aiNode* node)
{
    // NOTE:
    //  aiMesh::mNumBones store original source mesh, or UINT_MAX if not a copy
    //  aiMesh::mBones store reference to abs. transform we multiplied with

    // process meshes
    for (unsigned int i = 0; i < node->mNumMeshes;++i) {
        aiMesh* mesh = in[node->mMeshes[i]];

        // check whether we can operate on this mesh
        if (!mesh->mBones || *reinterpret_cast<aiMatrix4x4*>(mesh->mBones) == node->mTransformation) {
            // yes, we can.
            mesh->mBones = reinterpret_cast<aiBone**> (&node->mTransformation);
            mesh->mNumBones = UINT_MAX;
        }
        else {

            // try to find us in the list of newly created meshes
            for (unsigned int n = 0; n < out.size(); ++n) {
                aiMesh* ctz = out[n];
                if (ctz->mNumBones == node->mMeshes[i] && *reinterpret_cast<aiMatrix4x4*>(ctz->mBones) ==  node->mTransformation) {

                    // ok, use this one. Update node mesh index
                    node->mMeshes[i] = numIn + n;
                }
            }
            if (node->mMeshes[i] < numIn) {
                // Worst case. Need to operate on a full copy of the mesh
                DefaultLogger::get()->info("PretransformVertices: Copying mesh due to mismatching transforms");
                aiMesh* ntz;

                const unsigned int tmp = mesh->mNumBones; //
                mesh->mNumBones = 0;
                SceneCombiner::Copy(&ntz,mesh);
                mesh->mNumBones = tmp;

                ntz->mNumBones = node->mMeshes[i];
                ntz->mBones = reinterpret_cast<aiBone**> (&node->mTransformation);

                out.push_back(ntz);

                node->mMeshes[i] = static_cast<unsigned int>(numIn + out.size() - 1);
            }
        }
    }

    // call children
    for (unsigned int i = 0; i < node->mNumChildren;++i)
        BuildWCSMeshes(out,in,numIn,node->mChildren[i]);
}

// ------------------------------------------------------------------------------------------------
// Reset transformation matrices to identity
void PretransformVertices::MakeIdentityTransform(aiNode* nd)
{
    nd->mTransformation = aiMatrix4x4();

    // call children
    for (unsigned int i = 0; i < nd->mNumChildren;++i)
        MakeIdentityTransform(nd->mChildren[i]);
}

// ------------------------------------------------------------------------------------------------
// Build reference counters for all meshes
void PretransformVertices::BuildMeshRefCountArray(aiNode* nd, unsigned int * refs)
{
    for (unsigned int i = 0; i< nd->mNumMeshes;++i)
        refs[nd->mMeshes[i]]++;

    // call children
    for (unsigned int i = 0; i < nd->mNumChildren;++i)
        BuildMeshRefCountArray(nd->mChildren[i],refs);
}

// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void PretransformVertices::Execute( aiScene* pScene)
{
    DefaultLogger::get()->debug("PretransformVerticesProcess begin");

    // Return immediately if we have no meshes
    if (!pScene->mNumMeshes)
        return;

    const unsigned int iOldMeshes = pScene->mNumMeshes;
    const unsigned int iOldAnimationChannels = pScene->mNumAnimations;
    const unsigned int iOldNodes = CountNodes(pScene->mRootNode);

    if(configTransform) {
        pScene->mRootNode->mTransformation = configTransformation;
    }

    // first compute absolute transformation matrices for all nodes
    ComputeAbsoluteTransform(pScene->mRootNode);

    // Delete aiMesh::mBones for all meshes. The bones are
    // removed during this step and we need the pointer as
    // temporary storage
    for (unsigned int i = 0; i < pScene->mNumMeshes;++i)    {
        aiMesh* mesh = pScene->mMeshes[i];

        for (unsigned int a = 0; a < mesh->mNumBones;++a)
            delete mesh->mBones[a];

        delete[] mesh->mBones;
        mesh->mBones = NULL;
    }

    // now build a list of output meshes
    std::vector<aiMesh*> apcOutMeshes;

    // Keep scene hierarchy? It's an easy job in this case ...
    // we go on and transform all meshes, if one is referenced by nodes
    // with different absolute transformations a depth copy of the mesh
    // is required.
    if( configKeepHierarchy ) {

        // Hack: store the matrix we're transforming a mesh with in aiMesh::mBones
        BuildWCSMeshes(apcOutMeshes,pScene->mMeshes,pScene->mNumMeshes, pScene->mRootNode);

        // ... if new meshes have been generated, append them to the end of the scene
        if (apcOutMeshes.size() > 0) {
            aiMesh** npp = new aiMesh*[pScene->mNumMeshes + apcOutMeshes.size()];

            memcpy(npp,pScene->mMeshes,sizeof(aiMesh*)*pScene->mNumMeshes);
            memcpy(npp+pScene->mNumMeshes,&apcOutMeshes[0],sizeof(aiMesh*)*apcOutMeshes.size());

            pScene->mNumMeshes  += static_cast<unsigned int>(apcOutMeshes.size());
            delete[] pScene->mMeshes; pScene->mMeshes = npp;
        }

        // now iterate through all meshes and transform them to worldspace
        for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
            ApplyTransform(pScene->mMeshes[i],*reinterpret_cast<aiMatrix4x4*>( pScene->mMeshes[i]->mBones ));

            // prevent improper destruction
            pScene->mMeshes[i]->mBones    = NULL;
            pScene->mMeshes[i]->mNumBones = 0;
        }
    }
    else {

        apcOutMeshes.reserve(pScene->mNumMaterials<<1u);
        std::list<unsigned int> aiVFormats;

        std::vector<unsigned int> s(pScene->mNumMeshes,0);
        BuildMeshRefCountArray(pScene->mRootNode,&s[0]);

        for (unsigned int i = 0; i < pScene->mNumMaterials;++i)     {
            // get the list of all vertex formats for this material
            aiVFormats.clear();
            GetVFormatList(pScene,i,aiVFormats);
            aiVFormats.sort();
            aiVFormats.unique();
            for (std::list<unsigned int>::const_iterator j =  aiVFormats.begin();j != aiVFormats.end();++j) {
                unsigned int iVertices = 0;
                unsigned int iFaces = 0;
                CountVerticesAndFaces(pScene,pScene->mRootNode,i,*j,&iFaces,&iVertices);
                if (0 != iFaces && 0 != iVertices)
                {
                    apcOutMeshes.push_back(new aiMesh());
                    aiMesh* pcMesh = apcOutMeshes.back();
                    pcMesh->mNumFaces = iFaces;
                    pcMesh->mNumVertices = iVertices;
                    pcMesh->mFaces = new aiFace[iFaces];
                    pcMesh->mVertices = new aiVector3D[iVertices];
                    pcMesh->mMaterialIndex = i;
                    if ((*j) & 0x2)pcMesh->mNormals = new aiVector3D[iVertices];
                    if ((*j) & 0x4)
                    {
                        pcMesh->mTangents    = new aiVector3D[iVertices];
                        pcMesh->mBitangents  = new aiVector3D[iVertices];
                    }
                    iFaces = 0;
                    while ((*j) & (0x100 << iFaces))
                    {
                        pcMesh->mTextureCoords[iFaces] = new aiVector3D[iVertices];
                        if ((*j) & (0x10000 << iFaces))pcMesh->mNumUVComponents[iFaces] = 3;
                        else pcMesh->mNumUVComponents[iFaces] = 2;
                        iFaces++;
                    }
                    iFaces = 0;
                    while ((*j) & (0x1000000 << iFaces))
                        pcMesh->mColors[iFaces++] = new aiColor4D[iVertices];

                    // fill the mesh ...
                    unsigned int aiTemp[2] = {0,0};
                    CollectData(pScene,pScene->mRootNode,i,*j,pcMesh,aiTemp,&s[0]);
                }
            }
        }

        // If no meshes are referenced in the node graph it is possible that we get no output meshes.
        if (apcOutMeshes.empty())   {
            throw DeadlyImportError("No output meshes: all meshes are orphaned and are not referenced by any nodes");
        }
        else
        {
            // now delete all meshes in the scene and build a new mesh list
            for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
            {
                aiMesh* mesh = pScene->mMeshes[i];
                mesh->mNumBones = 0;
                mesh->mBones    = NULL;

                // we're reusing the face index arrays. avoid destruction
                for (unsigned int a = 0; a < mesh->mNumFaces; ++a) {
                    mesh->mFaces[a].mNumIndices = 0;
                    mesh->mFaces[a].mIndices = NULL;
                }

                delete mesh;

                // Invalidate the contents of the old mesh array. We will most
                // likely have less output meshes now, so the last entries of
                // the mesh array are not overridden. We set them to NULL to
                // make sure the developer gets notified when his application
                // attempts to access these fields ...
                mesh = NULL;
            }

            // It is impossible that we have more output meshes than
            // input meshes, so we can easily reuse the old mesh array
            pScene->mNumMeshes = (unsigned int)apcOutMeshes.size();
            for (unsigned int i = 0; i < pScene->mNumMeshes;++i) {
                pScene->mMeshes[i] = apcOutMeshes[i];
            }
        }
    }

    // remove all animations from the scene
    for (unsigned int i = 0; i < pScene->mNumAnimations;++i)
        delete pScene->mAnimations[i];
    delete[] pScene->mAnimations;

    pScene->mAnimations    = NULL;
    pScene->mNumAnimations = 0;

    // --- we need to keep all cameras and lights
    for (unsigned int i = 0; i < pScene->mNumCameras;++i)
    {
        aiCamera* cam = pScene->mCameras[i];
        const aiNode* nd = pScene->mRootNode->FindNode(cam->mName);
        ai_assert(NULL != nd);

        // multiply all properties of the camera with the absolute
        // transformation of the corresponding node
        cam->mPosition = nd->mTransformation * cam->mPosition;
        cam->mLookAt   = aiMatrix3x3( nd->mTransformation ) * cam->mLookAt;
        cam->mUp       = aiMatrix3x3( nd->mTransformation ) * cam->mUp;
    }

    for (unsigned int i = 0; i < pScene->mNumLights;++i)
    {
        aiLight* l = pScene->mLights[i];
        const aiNode* nd = pScene->mRootNode->FindNode(l->mName);
        ai_assert(NULL != nd);

        // multiply all properties of the camera with the absolute
        // transformation of the corresponding node
        l->mPosition   = nd->mTransformation * l->mPosition;
        l->mDirection  = aiMatrix3x3( nd->mTransformation ) * l->mDirection;
        l->mUp         = aiMatrix3x3( nd->mTransformation ) * l->mUp;
    }

    if( !configKeepHierarchy ) {

        // now delete all nodes in the scene and build a new
        // flat node graph with a root node and some level 1 children
        aiNode* newRoot = new aiNode();
        newRoot->mName = pScene->mRootNode->mName;
        delete pScene->mRootNode;
        pScene->mRootNode = newRoot;

        if (1 == pScene->mNumMeshes && !pScene->mNumLights && !pScene->mNumCameras)
        {
            pScene->mRootNode->mNumMeshes = 1;
            pScene->mRootNode->mMeshes = new unsigned int[1];
            pScene->mRootNode->mMeshes[0] = 0;
        }
        else
        {
            pScene->mRootNode->mNumChildren = pScene->mNumMeshes+pScene->mNumLights+pScene->mNumCameras;
            aiNode** nodes = pScene->mRootNode->mChildren = new aiNode*[pScene->mRootNode->mNumChildren];

            // generate mesh nodes
            for (unsigned int i = 0; i < pScene->mNumMeshes;++i,++nodes)
            {
                aiNode* pcNode = *nodes = new aiNode();
                pcNode->mParent = pScene->mRootNode;
                pcNode->mName = pScene->mMeshes[i]->mName;

                // setup mesh indices
                pcNode->mNumMeshes = 1;
                pcNode->mMeshes = new unsigned int[1];
                pcNode->mMeshes[0] = i;
            }
            // generate light nodes
            for (unsigned int i = 0; i < pScene->mNumLights;++i,++nodes)
            {
                aiNode* pcNode = *nodes = new aiNode();
                pcNode->mParent = pScene->mRootNode;
                pcNode->mName.length = ai_snprintf(pcNode->mName.data, MAXLEN, "light_%u",i);
                pScene->mLights[i]->mName = pcNode->mName;
            }
            // generate camera nodes
            for (unsigned int i = 0; i < pScene->mNumCameras;++i,++nodes)
            {
                aiNode* pcNode = *nodes = new aiNode();
                pcNode->mParent = pScene->mRootNode;
                pcNode->mName.length = ::ai_snprintf(pcNode->mName.data,MAXLEN,"cam_%u",i);
                pScene->mCameras[i]->mName = pcNode->mName;
            }
        }
    }
    else {
        // ... and finally set the transformation matrix of all nodes to identity
        MakeIdentityTransform(pScene->mRootNode);
    }

    if (configNormalize) {
        // compute the boundary of all meshes
        aiVector3D min,max;
        MinMaxChooser<aiVector3D> ()(min,max);

        for (unsigned int a = 0; a <  pScene->mNumMeshes; ++a) {
            aiMesh* m = pScene->mMeshes[a];
            for (unsigned int i = 0; i < m->mNumVertices;++i) {
                min = std::min(m->mVertices[i],min);
                max = std::max(m->mVertices[i],max);
            }
        }

        // find the dominant axis
        aiVector3D d = max-min;
        const ai_real div = std::max(d.x,std::max(d.y,d.z))*ai_real( 0.5);

        d = min + d * (ai_real)0.5;
        for (unsigned int a = 0; a <  pScene->mNumMeshes; ++a) {
            aiMesh* m = pScene->mMeshes[a];
            for (unsigned int i = 0; i < m->mNumVertices;++i) {
                m->mVertices[i] = (m->mVertices[i]-d)/div;
            }
        }
    }

    // print statistics
    if (!DefaultLogger::isNullLogger())
    {
        char buffer[4096];

        DefaultLogger::get()->debug("PretransformVerticesProcess finished");

        ::ai_snprintf(buffer,4096,"Removed %u nodes and %u animation channels (%u output nodes)",
            iOldNodes,iOldAnimationChannels,CountNodes(pScene->mRootNode));
        DefaultLogger::get()->info(buffer);

        ai_snprintf(buffer, 4096,"Kept %u lights and %u cameras",
            pScene->mNumLights,pScene->mNumCameras);
        DefaultLogger::get()->info(buffer);

        ai_snprintf(buffer, 4096,"Moved %u meshes to WCS (number of output meshes: %u)",
            iOldMeshes,pScene->mNumMeshes);
        DefaultLogger::get()->info(buffer);
    }
}
