Пример #1
0
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadMat1_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
{
    if(nfo.version > 8) {
        return UnsupportedChunk_Ascii(splitter,nfo,"Mat1");
    }

    ++splitter;
    if (!splitter.match_start("mat# ")) {
        ASSIMP_LOG_WARN_F( "Expected `mat#` line in `Mat1` chunk ", nfo.id );
        return;
    }

    out.materials.push_back(Material());
    Material& mat = out.materials.back();
    mat = nfo;

    mat.matnum = strtoul10(splitter[1]);
    ++splitter;

    if (!splitter.match_start("shader: ")) {
        ASSIMP_LOG_WARN_F( "Expected `mat#` line in `Mat1` chunk ", nfo.id);
        return;
    }
    std::string shader = std::string(splitter[1]);
    shader = shader.substr(0,shader.find_first_of(" \t"));

    if (shader == "metal") {
        mat.shader = Material::METAL;
    }
    else if (shader == "phong") {
        mat.shader = Material::PHONG;
    }
    else if (shader != "flat") {
        ASSIMP_LOG_WARN_F( "Unknown value for `shader` in `Mat1` chunk ", nfo.id );
    }

    ++splitter;
    if (!splitter.match_start("rgb ")) {
        ASSIMP_LOG_WARN_F( "Expected `rgb` line in `Mat1` chunk ", nfo.id);
    }

    const char* rgb = splitter[1];
    ReadFloat3Tuple_Ascii(mat.rgb,&rgb);

    ++splitter;
    if (!splitter.match_start("alpha ")) {
        ASSIMP_LOG_WARN_F( "Expected `alpha` line in `Mat1` chunk ", nfo.id);
    }

    const char* tokens[10];
    splitter.get_tokens(tokens);

    mat.alpha   = fast_atof( tokens[1] );
    mat.ka      = fast_atof( tokens[3] );
    mat.ks      = fast_atof( tokens[5] );
    mat.exp     = fast_atof( tokens[7] );
    mat.ior     = fast_atof( tokens[9] );
}
Пример #2
0
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadLght_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
{
    if(nfo.version > 8) {
        return UnsupportedChunk_Ascii(splitter,nfo,"Lght");
    }

    out.nodes.push_back(std::shared_ptr<Light>(new Light()));
    Light& msh = (Light&)(*out.nodes.back().get());
    msh = nfo;

    ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);

    if (splitter.match_start("Infinite ")) {
        msh.ltype = Light::INFINITE;
    }
    else if (splitter.match_start("Local ")) {
        msh.ltype = Light::LOCAL;
    }
    else if (splitter.match_start("Spot ")) {
        msh.ltype = Light::SPOT;
    }
    else {
        LogWarn_Ascii(splitter,format()<<
            "Unknown kind of light source in `Lght` chunk "<<nfo.id<<" : "<<*splitter);
        msh.ltype = Light::SPOT;
    }

    ++splitter;
    if (!splitter.match_start("color ")) {
        LogWarn_Ascii(splitter,format()<<
            "Expected `color` line in `Lght` chunk "<<nfo.id);
    }

    const char* rgb = splitter[1];
    ReadFloat3Tuple_Ascii(msh.color ,&rgb);

    SkipSpaces(&rgb);
    if (strncmp(rgb,"cone angle",10)) {
        LogWarn_Ascii(splitter,format()<<
            "Expected `cone angle` entity in `color` line in `Lght` chunk "<<nfo.id);
    }
    SkipSpaces(rgb+10,&rgb);
    msh.angle = fast_atof(&rgb);

    SkipSpaces(&rgb);
    if (strncmp(rgb,"inner angle",11)) {
        LogWarn_Ascii(splitter,format()<<
            "Expected `inner angle` entity in `color` line in `Lght` chunk "<<nfo.id);
    }
    SkipSpaces(rgb+11,&rgb);
    msh.inner_angle = fast_atof(&rgb);

    // skip the rest for we can't handle this kind of physically-based lighting information.
}
Пример #3
0
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadUnit_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
{
    if(nfo.version > 1) {
        return UnsupportedChunk_Ascii(splitter,nfo,"Unit");
    }
    ++splitter;
    if (!splitter.match_start("Units ")) {
        LogWarn_Ascii(splitter,format()<<
            "Expected `Units` line in `Unit` chunk "<<nfo.id);
        return;
    }

    // parent chunks preceede their childs, so we should have the
    // corresponding chunk already.
    for(std::shared_ptr< Node >& nd : out.nodes) {
        if (nd->id == nfo.parent_id) {
            const unsigned int t=strtoul10(splitter[1]);

            nd->unit_scale = t>=sizeof(units)/sizeof(units[0])?(
                LogWarn_Ascii(splitter,format()<<t<<" is not a valid value for `Units` attribute in `Unit chunk` "<<nfo.id)
                ,1.f):units[t];
            return;
        }
    }
    LogWarn_Ascii(splitter,format()<<"`Unit` chunk "<<nfo.id<<" is a child of "
        <<nfo.parent_id<<" which does not exist");
}
Пример #4
0
// ------------------------------------------------------------------------------------------------
void COBImporter::UnsupportedChunk_Ascii(LineSplitter& splitter, const ChunkInfo& nfo, const char* name)
{
    const std::string error = format("Encountered unsupported chunk: ") <<  name <<
        " [version: "<<nfo.version<<", size: "<<nfo.size<<"]";

    // we can recover if the chunk size was specified.
    if(nfo.size != static_cast<unsigned int>(-1)) {
        DefaultLogger::get()->error(error);

        // (HACK) - our current position in the stream is the beginning of the
        // head line of the next chunk. That's fine, but the caller is going
        // to call ++ on `splitter`, which we need to swallow to avoid
        // missing the next line.
        splitter.get_stream().IncPtr(nfo.size);
        splitter.swallow_next_increment();
    }
    else ThrowException(error);
}
Пример #5
0
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadChunkInfo_Ascii(ChunkInfo& out, const LineSplitter& splitter)
{
    const char* all_tokens[8];
    splitter.get_tokens(all_tokens);

    out.version = (all_tokens[1][1]-'0')*100+(all_tokens[1][3]-'0')*10+(all_tokens[1][4]-'0');
    out.id  = strtoul10(all_tokens[3]);
    out.parent_id = strtoul10(all_tokens[5]);
    out.size = strtol10(all_tokens[7]);
}
Пример #6
0
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadBasicNodeInfo_Ascii(Node& msh, LineSplitter& splitter, const ChunkInfo& /*nfo*/)
{
    for(;splitter;++splitter) {
        if (splitter.match_start("Name")) {
            msh.name = std::string(splitter[1]);

            // make nice names by merging the dupe count
            std::replace(msh.name.begin(),msh.name.end(),
                ',','_');
        }
        else if (splitter.match_start("Transform")) {
            for(unsigned int y = 0; y < 4 && ++splitter; ++y) {
                const char* s = splitter->c_str();
                for(unsigned int x = 0; x < 4; ++x) {
                    SkipSpaces(&s);
                    msh.transform[y][x] = fast_atof(&s);
                }
            }
            // we need the transform chunk, so we won't return until we have it.
            return;
        }
    }
}
Пример #7
0
// ------------------------------------------------------------------------------------------------
void COBImporter::ReadPolH_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
{
    if(nfo.version > 8) {
        return UnsupportedChunk_Ascii(splitter,nfo,"PolH");
    }

    out.nodes.push_back(std::shared_ptr<Mesh>(new Mesh()));
    Mesh& msh = (Mesh&)(*out.nodes.back().get());
    msh = nfo;

    ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);

    // the chunk has a fixed order of components, but some are not interesting of us so
    // we're just looking for keywords in arbitrary order. The end of the chunk is
    // either the last `Face` or the `DrawFlags` attribute, depending on the format ver.
    for(;splitter;++splitter) {
        if (splitter.match_start("World Vertices")) {
            const unsigned int cnt = strtoul10(splitter[2]);
            msh.vertex_positions.resize(cnt);

            for(unsigned int cur = 0;cur < cnt && ++splitter;++cur) {
                const char* s = splitter->c_str();

                aiVector3D& v = msh.vertex_positions[cur];

                SkipSpaces(&s);
                v.x = fast_atof(&s);
                SkipSpaces(&s);
                v.y = fast_atof(&s);
                SkipSpaces(&s);
                v.z = fast_atof(&s);
            }
        }
        else if (splitter.match_start("Texture Vertices")) {
            const unsigned int cnt = strtoul10(splitter[2]);
            msh.texture_coords.resize(cnt);

            for(unsigned int cur = 0;cur < cnt && ++splitter;++cur) {
                const char* s = splitter->c_str();

                aiVector2D& v = msh.texture_coords[cur];

                SkipSpaces(&s);
                v.x = fast_atof(&s);
                SkipSpaces(&s);
                v.y = fast_atof(&s);
            }
        }
        else if (splitter.match_start("Faces")) {
            const unsigned int cnt = strtoul10(splitter[1]);
            msh.faces.reserve(cnt);

            for(unsigned int cur = 0; cur < cnt && ++splitter ;++cur) {
                if (splitter.match_start("Hole")) {
                    LogWarn_Ascii(splitter,"Skipping unsupported `Hole` line");
                    continue;
                }

                if (!splitter.match_start("Face")) {
                    ThrowException("Expected Face line");
                }

                msh.faces.push_back(Face());
                Face& face = msh.faces.back();

                face.indices.resize(strtoul10(splitter[2]));
                face.flags = strtoul10(splitter[4]);
                face.material = strtoul10(splitter[6]);

                const char* s = (++splitter)->c_str();
                for(size_t i = 0; i < face.indices.size(); ++i) {
                    if(!SkipSpaces(&s)) {
                        ThrowException("Expected EOL token in Face entry");
                    }
                    if ('<' != *s++) {
                        ThrowException("Expected < token in Face entry");
                    }
                    face.indices[i].pos_idx = strtoul10(s,&s);
                    if (',' != *s++) {
                        ThrowException("Expected , token in Face entry");
                    }
                    face.indices[i].uv_idx = strtoul10(s,&s);
                    if ('>' != *s++) {
                        ThrowException("Expected < token in Face entry");
                    }
                }
            }
            if (nfo.version <= 4) {
                break;
            }
        }
        else if (splitter.match_start("DrawFlags")) {
            msh.draw_flags = strtoul10(splitter[1]);
            break;
        }
    }
}
Пример #8
0
// ------------------------------------------------------------------------------------------------
void COBImporter::LogDebug_Ascii(const LineSplitter& splitter, const format& message)   {
    LogDebug_Ascii(message << " [at line "<< splitter.get_index()<<"]");
}