コード例 #1
0
ファイル: geometry.cpp プロジェクト: ryden/Slackgine
// Load/Save
bool Geometry::load(l3m::Model* model, l3m::IStream& fp, float version)
{
    // Geometry name
    if ( fp.readStr( &m_geometry.name() ) == -1 )
        return setError ( "Error reading the geometry name" );

    // Geometry boundaries
    float values[7];
    if ( fp.readFloat(values, 7) != 7 )
        return setError ( "Error reading the geometry boundary data" );
    m_geometry.boundingBox() = BoundingBox ( values[0], values[1], values[2], values[3], values[4], values[5] );
    m_geometry.boundingSphere() = BoundingSphere ( values[6] );

    // Geometry centroid
    if ( fp.readVector(&m_geometry.centroid()) != 1 )
        return setError ( "Error reading the geometry centroid" );

    // Geometry armature pose
    b8 hasPose;
    if ( !fp.readBoolean(&hasPose) )
        return setError ( "Error reading the geometry pose" );
    if ( hasPose )
    {
        if ( !fp.readStr(&m_poseUrl) )
            return setError ( "Error reading the geometry pose url" );
        model->registerDeltaResolver( this, Geometry::resolvePoseDelta, 0 );
    }

    // Read the vertex data
    u32 numVertices;
    if ( fp.read32 ( &numVertices, 1 ) != 1 )
        return setError ( "Error reading the vertex count" );
    Vertex* vertices = ( Vertex* )sgMalloc ( sizeof(Vertex) * numVertices );
    if ( fp.readFloat(vertices->base(), numVertices*sizeof(Vertex)/sizeof(float)) != (ssize_t)(numVertices*sizeof(Vertex)/sizeof(float)) )
        return setError ( "Error reading the vertex data" );
    m_geometry.set ( vertices, numVertices );

    // Vertex layers
    u32 numLayers;
    if ( fp.read32 ( &numLayers, 1 ) != 1 )
        return setError ( "Error reading the vertex layer count" );
    for ( u32 i = 0; i < numLayers; ++i )
    {
        // Vertex layer name
        std::string name;
        if ( fp.readStr ( &name ) == -1 )
            return setError ( "Error reading the vertex layer name" );

        // Vertex layer level count
        u32 numLevels;
        if ( fp.read32 ( &numLevels, 1 ) != 1 )
            return setError ( "Error reading the vertex layer level count" );

        // Vertex layer element size
        u32 elementSize;
        if ( fp.read32 ( &elementSize, 1 ) != 1 )
            return setError ( "Error reading the vertex layer element size" );

        // Vertex layer data
        void* data = m_geometry.createVertexLayer ( name, numLevels, 0, elementSize );
        if ( fp.readData ( reinterpret_cast < char * > ( data ), elementSize, numLevels*numVertices ) != (ssize_t)(numLevels*numVertices) )
            return setError ( "Error reading the vertex layer data" );
    }

    // Read the meshes headers
    u32 numMeshes;
    if ( fp.read32 ( &numMeshes, 1 ) != 1 )
        return setError ( "Error reading the number of meshes" );

    // Read the meshes
    for ( u32 i = 0; i < numMeshes; ++i )
    {
        // Read the mesh name
        std::string name;
        fp.readStr(&name);

        // Read the polygon type
        u32 polyType_;
        if ( fp.read32 ( &polyType_, 1 ) != 1 )
            return setError ( "Error reading the polygon type" );
        Mesh::PolygonType polyType = static_cast < Mesh::PolygonType > ( polyType_ );

        // Read the material
        b8 thereIsMaterial;
        std::string materialName;

        if ( !fp.readBoolean(&thereIsMaterial) )
            return setError ( "Error reading the material" );
        if ( thereIsMaterial )
        {
            if ( fp.readStr ( &materialName ) == 0 )
                return setError ( "Error reading the material name" );
        }

        // Read the index data
        u32 numIndices;
        if ( fp.read32 ( &numIndices, 1 ) != 1 )
            return setError ( "Error reading the index count" );
        u32* indices = ( u32* )sgMalloc ( sizeof(u32) * numIndices );
        if ( fp.read32 ( indices, numIndices ) != (ssize_t)numIndices )
            return setError ( "Error reading the index data" );

        // Create the mesh
        Mesh* mesh = sgNew Mesh ();
        mesh->name () = name;
        mesh->set ( indices, numIndices, polyType );
        m_geometry.loadMesh( mesh );

        // Defer the material reference
        if ( thereIsMaterial )
        {
            MaterialDeltaData* matDelta = sgNew MaterialDeltaData ();
            matDelta->name = materialName;
            matDelta->mesh = mesh;
            model->registerDeltaResolver ( this, Geometry::resolveMaterialDelta, matDelta );
        }
    }

    // find the morph object for this geometry (if there is one)
    model->registerDeltaResolver( this, Geometry::resolveMorphDelta, 0 );

    return true;
}