Ejemplo n.º 1
0
void glTF2Importer::ImportMeshes(glTF2::Asset& r)
{
    std::vector<aiMesh*> meshes;

    unsigned int k = 0;

    for (unsigned int m = 0; m < r.meshes.Size(); ++m) {
        Mesh& mesh = r.meshes[m];

        meshOffsets.push_back(k);
        k += unsigned(mesh.primitives.size());

        for (unsigned int p = 0; p < mesh.primitives.size(); ++p) {
            Mesh::Primitive& prim = mesh.primitives[p];

            aiMesh* aim = new aiMesh();
            meshes.push_back(aim);

            aim->mName = mesh.name.empty() ? mesh.id : mesh.name;

            if (mesh.primitives.size() > 1) {
                size_t& len = aim->mName.length;
                aim->mName.data[len] = '-';
                len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(MAXLEN - len - 1), p);
            }

            switch (prim.mode) {
                case PrimitiveMode_POINTS:
                    aim->mPrimitiveTypes |= aiPrimitiveType_POINT;
                    break;

                case PrimitiveMode_LINES:
                case PrimitiveMode_LINE_LOOP:
                case PrimitiveMode_LINE_STRIP:
                    aim->mPrimitiveTypes |= aiPrimitiveType_LINE;
                    break;

                case PrimitiveMode_TRIANGLES:
                case PrimitiveMode_TRIANGLE_STRIP:
                case PrimitiveMode_TRIANGLE_FAN:
                    aim->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
                    break;

            }

            Mesh::Primitive::Attributes& attr = prim.attributes;

            if (attr.position.size() > 0 && attr.position[0]) {
                aim->mNumVertices = static_cast<unsigned int>(attr.position[0]->count);
                attr.position[0]->ExtractData(aim->mVertices);
            }

            if (attr.normal.size() > 0 && attr.normal[0]) {
                attr.normal[0]->ExtractData(aim->mNormals);

                // only extract tangents if normals are present
                if (attr.tangent.size() > 0 && attr.tangent[0]) {
                    // generate bitangents from normals and tangents according to spec
                    Tangent *tangents = nullptr;

                    attr.tangent[0]->ExtractData(tangents);

                    aim->mTangents = new aiVector3D[aim->mNumVertices];
                    aim->mBitangents = new aiVector3D[aim->mNumVertices];

                    for (unsigned int i = 0; i < aim->mNumVertices; ++i) {
                        aim->mTangents[i] = tangents[i].xyz;
                        aim->mBitangents[i] = (aim->mNormals[i] ^ tangents[i].xyz) * tangents[i].w;
                    }

                    delete [] tangents;
                }
            }

            for (size_t c = 0; c < attr.color.size() && c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c) {
                if (attr.color[c]->count != aim->mNumVertices) {
                    DefaultLogger::get()->warn("Color stream size in mesh \"" + mesh.name +
                        "\" does not match the vertex count");
                    continue;
                }
                aim->mColors[c] = new aiColor4D[attr.color[c]->count];
                attr.color[c]->ExtractData(aim->mColors[c]);
            }
            for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
                if (attr.texcoord[tc]->count != aim->mNumVertices) {
                    DefaultLogger::get()->warn("Texcoord stream size in mesh \"" + mesh.name +
                                               "\" does not match the vertex count");
                    continue;
                }

                attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);
                aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();

                aiVector3D* values = aim->mTextureCoords[tc];
                for (unsigned int i = 0; i < aim->mNumVertices; ++i) {
                    values[i].y = 1 - values[i].y; // Flip Y coords
                }
            }

            std::vector<Mesh::Primitive::Target>& targets = prim.targets;
            if (targets.size() > 0) {
                aim->mNumAnimMeshes = (unsigned int)targets.size();
                aim->mAnimMeshes = new aiAnimMesh*[aim->mNumAnimMeshes];
                for (size_t i = 0; i < targets.size(); i++) {
                    aim->mAnimMeshes[i] = aiCreateAnimMesh(aim);
                    aiAnimMesh& aiAnimMesh = *(aim->mAnimMeshes[i]);
                    Mesh::Primitive::Target& target = targets[i];

                    if (target.position.size() > 0) {
                        aiVector3D *positionDiff = nullptr;
                        target.position[0]->ExtractData(positionDiff);
                        for(unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
                            aiAnimMesh.mVertices[vertexId] += positionDiff[vertexId];
                        }
                        delete [] positionDiff;
                    }
                    if (target.normal.size() > 0) {
                        aiVector3D *normalDiff = nullptr;
                        target.normal[0]->ExtractData(normalDiff);
                        for(unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
                            aiAnimMesh.mNormals[vertexId] += normalDiff[vertexId];
                        }
                        delete [] normalDiff;
                    }
                    if (target.tangent.size() > 0) {
                        Tangent *tangent = nullptr;
                        attr.tangent[0]->ExtractData(tangent);

                        aiVector3D *tangentDiff = nullptr;
                        target.tangent[0]->ExtractData(tangentDiff);

                        for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; ++vertexId) {
                            tangent[vertexId].xyz += tangentDiff[vertexId];
                            aiAnimMesh.mTangents[vertexId] = tangent[vertexId].xyz;
                            aiAnimMesh.mBitangents[vertexId] = (aiAnimMesh.mNormals[vertexId] ^ tangent[vertexId].xyz) * tangent[vertexId].w;
                        }
                        delete [] tangent;
                        delete [] tangentDiff;
                    }
                    if (mesh.weights.size() > i) {
                        aiAnimMesh.mWeight = mesh.weights[i];
                    }
                }
            }


            aiFace* faces = 0;
            size_t nFaces = 0;

            if (prim.indices) {
                size_t count = prim.indices->count;

                Accessor::Indexer data = prim.indices->GetIndexer();
                ai_assert(data.IsValid());

                switch (prim.mode) {
                    case PrimitiveMode_POINTS: {
                        nFaces = count;
                        faces = new aiFace[nFaces];
                        for (unsigned int i = 0; i < count; ++i) {
                            SetFace(faces[i], data.GetUInt(i));
                        }
                        break;
                    }

                    case PrimitiveMode_LINES: {
                        nFaces = count / 2;
                        faces = new aiFace[nFaces];
                        for (unsigned int i = 0; i < count; i += 2) {
                            SetFace(faces[i / 2], data.GetUInt(i), data.GetUInt(i + 1));
                        }
                        break;
                    }

                    case PrimitiveMode_LINE_LOOP:
                    case PrimitiveMode_LINE_STRIP: {
                        nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
                        faces = new aiFace[nFaces];
                        SetFace(faces[0], data.GetUInt(0), data.GetUInt(1));
                        for (unsigned int i = 2; i < count; ++i) {
                            SetFace(faces[i - 1], faces[i - 2].mIndices[1], data.GetUInt(i));
                        }
                        if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
                            SetFace(faces[count - 1], faces[count - 2].mIndices[1], faces[0].mIndices[0]);
                        }
                        break;
                    }

                    case PrimitiveMode_TRIANGLES: {
                        nFaces = count / 3;
                        faces = new aiFace[nFaces];
                        for (unsigned int i = 0; i < count; i += 3) {
                            SetFace(faces[i / 3], data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
                        }
                        break;
                    }
                    case PrimitiveMode_TRIANGLE_STRIP: {
                        nFaces = count - 2;
                        faces = new aiFace[nFaces];
                        for (unsigned int i = 0; i < nFaces; ++i) {
                            //The ordering is to ensure that the triangles are all drawn with the same orientation
                            if ((i + 1) % 2 == 0)
                            {
                                //For even n, vertices n + 1, n, and n + 2 define triangle n
                                SetFace(faces[i], data.GetUInt(i + 1), data.GetUInt(i), data.GetUInt(i + 2));
                            }
                            else
                            {
                                //For odd n, vertices n, n+1, and n+2 define triangle n
                                SetFace(faces[i], data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
                            }
                        }
                        break;
                    }
                    case PrimitiveMode_TRIANGLE_FAN:
                        nFaces = count - 2;
                        faces = new aiFace[nFaces];
                        SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
                        for (unsigned int i = 1; i < nFaces; ++i) {
                            SetFace(faces[i], faces[0].mIndices[0], faces[i - 1].mIndices[2], data.GetUInt(i + 2));
                        }
                        break;
                }
            }
            else { // no indices provided so directly generate from counts

                // use the already determined count as it includes checks
                unsigned int count = aim->mNumVertices;

                switch (prim.mode) {
                case PrimitiveMode_POINTS: {
                    nFaces = count;
                    faces = new aiFace[nFaces];
                    for (unsigned int i = 0; i < count; ++i) {
                        SetFace(faces[i], i);
                    }
                    break;
                }

                case PrimitiveMode_LINES: {
                    nFaces = count / 2;
                    faces = new aiFace[nFaces];
                    for (unsigned int i = 0; i < count; i += 2) {
                        SetFace(faces[i / 2], i, i + 1);
                    }
                    break;
                }

                case PrimitiveMode_LINE_LOOP:
                case PrimitiveMode_LINE_STRIP: {
                    nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
                    faces = new aiFace[nFaces];
                    SetFace(faces[0], 0, 1);
                    for (unsigned int i = 2; i < count; ++i) {
                        SetFace(faces[i - 1], faces[i - 2].mIndices[1], i);
                    }
                    if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
                        SetFace(faces[count - 1], faces[count - 2].mIndices[1], faces[0].mIndices[0]);
                    }
                    break;
                }

                case PrimitiveMode_TRIANGLES: {
                    nFaces = count / 3;
                    faces = new aiFace[nFaces];
                    for (unsigned int i = 0; i < count; i += 3) {
                        SetFace(faces[i / 3], i, i + 1, i + 2);
                    }
                    break;
                }
                case PrimitiveMode_TRIANGLE_STRIP: {
                    nFaces = count - 2;
                    faces = new aiFace[nFaces];
                    for (unsigned int i = 0; i < nFaces; ++i) {
                        //The ordering is to ensure that the triangles are all drawn with the same orientation
                        if ((i+1) % 2 == 0)
                        {
                            //For even n, vertices n + 1, n, and n + 2 define triangle n
                            SetFace(faces[i], i+1, i, i+2);
                        }
                        else
                        {
                            //For odd n, vertices n, n+1, and n+2 define triangle n
                            SetFace(faces[i], i, i+1, i+2);
                        }
                    }
                    break;
                }
                case PrimitiveMode_TRIANGLE_FAN:
                    nFaces = count - 2;
                    faces = new aiFace[nFaces];
                    SetFace(faces[0], 0, 1, 2);
                    for (unsigned int i = 1; i < nFaces; ++i) {
                        SetFace(faces[i], faces[0].mIndices[0], faces[i - 1].mIndices[2], i + 2);
                    }
                    break;
                }
            }

            if (faces) {
                aim->mFaces = faces;
                aim->mNumFaces = static_cast<unsigned int>(nFaces);
                ai_assert(CheckValidFacesIndices(faces, static_cast<unsigned>(nFaces), aim->mNumVertices));
            }

            if (prim.material) {
                aim->mMaterialIndex = prim.material.GetIndex();
            }
            else {
                aim->mMaterialIndex = mScene->mNumMaterials - 1;
            }

        }
    }

    meshOffsets.push_back(k);

    CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes);
}
Ejemplo n.º 2
0
void glTFImporter::ImportMeshes(glTF::Asset& r)
{
    std::vector<aiMesh*> meshes;

    unsigned int k = 0;

    for (unsigned int m = 0; m < r.meshes.Size(); ++m) {
        Mesh& mesh = r.meshes[m];

        meshOffsets.push_back(k);
        k += mesh.primitives.size();

        for (unsigned int p = 0; p < mesh.primitives.size(); ++p) {
            Mesh::Primitive& prim = mesh.primitives[p];

            aiMesh* aim = new aiMesh();
            meshes.push_back(aim);

            aim->mName = mesh.id;
            if (mesh.primitives.size() > 1) {
                size_t& len = aim->mName.length;
                aim->mName.data[len] = '-';
                len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, MAXLEN - len - 1, p);
            }

            switch (prim.mode) {
                case PrimitiveMode_POINTS:
                    aim->mPrimitiveTypes |= aiPrimitiveType_POINT;
                    break;

                case PrimitiveMode_LINES:
                case PrimitiveMode_LINE_LOOP:
                case PrimitiveMode_LINE_STRIP:
                    aim->mPrimitiveTypes |= aiPrimitiveType_LINE;
                    break;

                case PrimitiveMode_TRIANGLES:
                case PrimitiveMode_TRIANGLE_STRIP:
                case PrimitiveMode_TRIANGLE_FAN:
                    aim->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
                    break;
            }

            Mesh::Primitive::Attributes& attr = prim.attributes;
            if (attr.position.size() > 0 && attr.position[0]) {
                aim->mNumVertices = attr.position[0]->count;
                attr.position[0]->ExtractData(aim->mVertices);
            }

            if (attr.normal.size() > 0 && attr.normal[0]) {
                attr.normal[0]->ExtractData(aim->mNormals);
            }

            for (size_t tc = 0; tc < attr.texcoord.size() && tc <= AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
                attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);
                aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();
            }


            if (prim.indices) {
                aiFace* faces = 0;
                size_t nFaces = 0;

                unsigned int count = prim.indices->count;

                Accessor::Indexer data = prim.indices->GetIndexer();

                switch (prim.mode) {
                    case PrimitiveMode_POINTS: {
                        nFaces = count;
                        faces = new aiFace[nFaces];
                        for (unsigned int i = 0; i < count; ++i) {
                            SetFace(faces[i], data.GetUInt(i));
                        }
                        break;
                    }

                    case PrimitiveMode_LINES: {
                        nFaces = count / 2;
                        faces = new aiFace[nFaces];
                        for (unsigned int i = 0; i < count; i += 2) {
                            SetFace(faces[i / 2], data.GetUInt(i), data.GetUInt(i + 1));
                        }
                        break;
                    }

                    case PrimitiveMode_LINE_LOOP:
                    case PrimitiveMode_LINE_STRIP: {
                        nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
                        faces = new aiFace[nFaces];
                        SetFace(faces[0], data.GetUInt(0), data.GetUInt(1));
                        for (unsigned int i = 2; i < count; ++i) {
                            SetFace(faces[i - 1], faces[i - 2].mIndices[1], data.GetUInt(i));
                        }
                        if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
                            SetFace(faces[count - 1], faces[count - 2].mIndices[1], faces[0].mIndices[0]);
                        }
                        break;
                    }

                    case PrimitiveMode_TRIANGLES: {
                        nFaces = count / 3;
                        faces = new aiFace[nFaces];
                        for (unsigned int i = 0; i < count; i += 3) {
                            SetFace(faces[i / 3], data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
                        }
                        break;
                    }
                    case PrimitiveMode_TRIANGLE_STRIP: {
                        nFaces = count - 2;
                        faces = new aiFace[nFaces];
                        SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
                        for (unsigned int i = 3; i < count; ++i) {
                            SetFace(faces[i - 2], faces[i - 1].mIndices[1], faces[i - 1].mIndices[2], data.GetUInt(i));
                        }
                        break;
                    }
                    case PrimitiveMode_TRIANGLE_FAN:
                        nFaces = count - 2;
                        faces = new aiFace[nFaces];
                        SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
                        for (unsigned int i = 3; i < count; ++i) {
                            SetFace(faces[i - 2], faces[0].mIndices[0], faces[i - 1].mIndices[2], data.GetUInt(i));
                        }
                        break;
                }

                if (faces) {
                    aim->mFaces = faces;
                    aim->mNumFaces = nFaces;
                }
            }


            if (prim.material) {
                aim->mMaterialIndex = prim.material.GetIndex();
            }
        }
    }

    meshOffsets.push_back(k);
    
    CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes);
}
Ejemplo n.º 3
0
void glTF2Importer::ImportMeshes(glTF2::Asset& r)
{
    std::vector<aiMesh*> meshes;

    unsigned int k = 0;

    for (unsigned int m = 0; m < r.meshes.Size(); ++m) {
        Mesh& mesh = r.meshes[m];

        meshOffsets.push_back(k);
        k += unsigned(mesh.primitives.size());

        for (unsigned int p = 0; p < mesh.primitives.size(); ++p) {
            Mesh::Primitive& prim = mesh.primitives[p];

            aiMesh* aim = new aiMesh();
            meshes.push_back(aim);

            aim->mName = mesh.name.empty() ? mesh.id : mesh.name;

            if (mesh.primitives.size() > 1) {
                size_t& len = aim->mName.length;
                aim->mName.data[len] = '-';
                len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(MAXLEN - len - 1), p);
            }

            switch (prim.mode) {
                case PrimitiveMode_POINTS:
                    aim->mPrimitiveTypes |= aiPrimitiveType_POINT;
                    break;

                case PrimitiveMode_LINES:
                case PrimitiveMode_LINE_LOOP:
                case PrimitiveMode_LINE_STRIP:
                    aim->mPrimitiveTypes |= aiPrimitiveType_LINE;
                    break;

                case PrimitiveMode_TRIANGLES:
                case PrimitiveMode_TRIANGLE_STRIP:
                case PrimitiveMode_TRIANGLE_FAN:
                    aim->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
                    break;

            }

            Mesh::Primitive::Attributes& attr = prim.attributes;

            if (attr.position.size() > 0 && attr.position[0]) {
                aim->mNumVertices = attr.position[0]->count;
                attr.position[0]->ExtractData(aim->mVertices);
            }

            if (attr.normal.size() > 0 && attr.normal[0]) {
                attr.normal[0]->ExtractData(aim->mNormals);

                // only extract tangents if normals are present
                if (attr.tangent.size() > 0 && attr.tangent[0]) {
                    // generate bitangents from normals and tangents according to spec
                    struct Tangent
                    {
                        aiVector3D xyz;
                        ai_real w;
                    } *tangents = nullptr;

                    attr.tangent[0]->ExtractData(tangents);

                    aim->mTangents = new aiVector3D[aim->mNumVertices];
                    aim->mBitangents = new aiVector3D[aim->mNumVertices];

                    for (unsigned int i = 0; i < aim->mNumVertices; ++i) {
                        aim->mTangents[i] = tangents[i].xyz;
                        aim->mBitangents[i] = (aim->mNormals[i] ^ tangents[i].xyz) * tangents[i].w;
                    }

                    delete tangents;
                }
            }

            for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
                attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);
                aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();

                aiVector3D* values = aim->mTextureCoords[tc];
                for (unsigned int i = 0; i < aim->mNumVertices; ++i) {
                    values[i].y = 1 - values[i].y; // Flip Y coords
                }
            }


            if (prim.indices) {
                aiFace* faces = 0;
                unsigned int nFaces = 0;

                unsigned int count = prim.indices->count;

                Accessor::Indexer data = prim.indices->GetIndexer();
                ai_assert(data.IsValid());

                switch (prim.mode) {
                    case PrimitiveMode_POINTS: {
                        nFaces = count;
                        faces = new aiFace[nFaces];
                        for (unsigned int i = 0; i < count; ++i) {
                            SetFace(faces[i], data.GetUInt(i));
                        }
                        break;
                    }

                    case PrimitiveMode_LINES: {
                        nFaces = count / 2;
                        faces = new aiFace[nFaces];
                        for (unsigned int i = 0; i < count; i += 2) {
                            SetFace(faces[i / 2], data.GetUInt(i), data.GetUInt(i + 1));
                        }
                        break;
                    }

                    case PrimitiveMode_LINE_LOOP:
                    case PrimitiveMode_LINE_STRIP: {
                        nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
                        faces = new aiFace[nFaces];
                        SetFace(faces[0], data.GetUInt(0), data.GetUInt(1));
                        for (unsigned int i = 2; i < count; ++i) {
                            SetFace(faces[i - 1], faces[i - 2].mIndices[1], data.GetUInt(i));
                        }
                        if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
                            SetFace(faces[count - 1], faces[count - 2].mIndices[1], faces[0].mIndices[0]);
                        }
                        break;
                    }

                    case PrimitiveMode_TRIANGLES: {
                        nFaces = count / 3;
                        faces = new aiFace[nFaces];
                        for (unsigned int i = 0; i < count; i += 3) {
                            SetFace(faces[i / 3], data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
                        }
                        break;
                    }
                    case PrimitiveMode_TRIANGLE_STRIP: {
                        nFaces = count - 2;
                        faces = new aiFace[nFaces];
                        SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
                        for (unsigned int i = 3; i < count; ++i) {
                            SetFace(faces[i - 2], faces[i - 1].mIndices[1], faces[i - 1].mIndices[2], data.GetUInt(i));
                        }
                        break;
                    }
                    case PrimitiveMode_TRIANGLE_FAN:
                        nFaces = count - 2;
                        faces = new aiFace[nFaces];
                        SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
                        for (unsigned int i = 3; i < count; ++i) {
                            SetFace(faces[i - 2], faces[0].mIndices[0], faces[i - 1].mIndices[2], data.GetUInt(i));
                        }
                        break;
                }

                if (faces) {
                    aim->mFaces = faces;
                    aim->mNumFaces = nFaces;
                    ai_assert(CheckValidFacesIndices(faces, nFaces, aim->mNumVertices));
                }
            }


            if (prim.material) {
                aim->mMaterialIndex = prim.material.GetIndex();
            }
        }
    }

    meshOffsets.push_back(k);

    CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes);
}