include/cinder/ObjLoader.h
Go to the documentation of this file.
00001 /*
00002  Copyright (c) 2010, The Barbarian Group
00003  All rights reserved.
00004 
00005  Redistribution and use in source and binary forms, with or without modification, are permitted provided that
00006  the following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and
00009     the following disclaimer.
00010     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
00011     the following disclaimer in the documentation and/or other materials provided with the distribution.
00012 
00013  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00014  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00015  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
00016  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00017  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00018  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00019  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00020  POSSIBILITY OF SUCH DAMAGE.
00021 */
00022 
00023 #pragma once
00024 
00025 #include "cinder/TriMesh.h"
00026 #include "cinder/Stream.h"
00027 
00028 #include <boost/logic/tribool.hpp>
00029 #include <boost/tuple/tuple_comparison.hpp>
00030 #include <map>
00031 
00032 namespace cinder {
00033 
00045 class ObjLoader {
00046  public:
00050     ObjLoader( std::shared_ptr<IStream> aStream, bool includeUVs = true );
00054     ObjLoader( DataSourceRef dataSource, bool includeUVs = true );
00058     ObjLoader( DataSourceRef dataSource, DataSourceRef materialSource, bool includeUVs = true );
00059     ~ObjLoader();
00060 
00066     void    load( TriMesh *destTriMesh, boost::tribool loadNormals = boost::logic::indeterminate, boost::tribool loadTexCoords = boost::logic::indeterminate, bool optimizeVertices = true );
00071     void    load( size_t groupIndex, TriMesh *destTriMesh, boost::tribool loadNormals = boost::logic::indeterminate, boost::tribool loadTexCoords = boost::logic::indeterminate, bool optimizeVertices = true );
00072     
00073     struct Material {
00074         Material() {
00075             Ka[0] = Ka[1] = Ka[2] = 0;
00076             Kd[0] = Kd[1] = Kd[2] = 1;
00077         }
00078 
00079         Material( const Material& rhs ) {
00080             mName = rhs.mName;
00081             Ka[0] = rhs.Ka[0];
00082             Ka[1] = rhs.Ka[1];
00083             Ka[2] = rhs.Ka[2];
00084             Kd[0] = rhs.Kd[0];
00085             Kd[1] = rhs.Kd[1];
00086             Kd[2] = rhs.Kd[2];
00087         }
00088 
00089         std::string mName;
00090         float       Ka[3];
00091         float       Kd[3];
00092     };
00093     
00094     struct Face {
00095         int                 mNumVertices;
00096         std::vector<int>    mVertexIndices;
00097         std::vector<int>    mTexCoordIndices;
00098         std::vector<int>    mNormalIndices;
00099         const Material*     mMaterial;
00100     };
00101 
00102     struct Group {
00103         std::string             mName;
00104         int                     mBaseVertexOffset, mBaseTexCoordOffset, mBaseNormalOffset;
00105         std::vector<Face>       mFaces;
00106         bool                    mHasTexCoords;
00107         bool                    mHasNormals;
00108     };
00109 
00111     static void     write( DataTargetRef dataTarget, const TriMesh &mesh, bool writeNormals = true, bool writeUVs = true );
00112     
00114     size_t      getNumGroups() const { return mGroups.size(); }
00115     
00117     const std::vector<Group>&       getGroups() const { return mGroups; }
00118     
00119  private:
00120     typedef boost::tuple<int,int> VertexPair;
00121     typedef boost::tuple<int,int,int> VertexTriple;
00122 
00123     void    parse( bool includeUVs );
00124 
00125     void    parseFace( Group *group, const Material *material, const std::string &s, bool includeUVs );
00126     void    parseMaterial( std::shared_ptr<IStream> material );
00127     void    loadInternalNoOptimize( const Group &group, TriMesh *destTriMesh, bool texCoords, bool normals );
00128     void    loadInternalNormalsTextures( const Group &group, std::map<boost::tuple<int,int,int>,int> &uniqueVerts, TriMesh *destTriMesh );
00129     void    loadInternalNormals( const Group &group, std::map<boost::tuple<int,int>,int> &uniqueVerts, TriMesh *destTriMesh );
00130     void    loadInternalTextures( const Group &group, std::map<boost::tuple<int,int>,int> &uniqueVerts, TriMesh *destTriMesh );
00131     void    loadInternal( const Group &group, std::map<int,int> &uniqueVerts, TriMesh *destTriMesh );   
00132  
00133     std::shared_ptr<IStream>        mStream;
00134     std::vector<Vec3f>              mVertices, mNormals;
00135     std::vector<Vec2f>              mTexCoords;
00136     std::vector<Group>              mGroups;
00137     std::map<std::string, Material> mMaterials;
00138 };
00139 
00140 } // namespace cinder