vrshoot

annotate libs/assimp/ObjFileMtlImporter.cpp @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
rev   line source
nuclear@0 1 /*
nuclear@0 2 ---------------------------------------------------------------------------
nuclear@0 3 Open Asset Import Library (assimp)
nuclear@0 4 ---------------------------------------------------------------------------
nuclear@0 5
nuclear@0 6 Copyright (c) 2006-2012, assimp team
nuclear@0 7
nuclear@0 8 All rights reserved.
nuclear@0 9
nuclear@0 10 Redistribution and use of this software in source and binary forms,
nuclear@0 11 with or without modification, are permitted provided that the following
nuclear@0 12 conditions are met:
nuclear@0 13
nuclear@0 14 * Redistributions of source code must retain the above
nuclear@0 15 copyright notice, this list of conditions and the
nuclear@0 16 following disclaimer.
nuclear@0 17
nuclear@0 18 * Redistributions in binary form must reproduce the above
nuclear@0 19 copyright notice, this list of conditions and the
nuclear@0 20 following disclaimer in the documentation and/or other
nuclear@0 21 materials provided with the distribution.
nuclear@0 22
nuclear@0 23 * Neither the name of the assimp team, nor the names of its
nuclear@0 24 contributors may be used to endorse or promote products
nuclear@0 25 derived from this software without specific prior
nuclear@0 26 written permission of the assimp team.
nuclear@0 27
nuclear@0 28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
nuclear@0 29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
nuclear@0 30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
nuclear@0 31 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
nuclear@0 32 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
nuclear@0 33 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
nuclear@0 34 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
nuclear@0 35 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
nuclear@0 36 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
nuclear@0 37 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
nuclear@0 38 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
nuclear@0 39 ---------------------------------------------------------------------------
nuclear@0 40 */
nuclear@0 41
nuclear@0 42 #include "AssimpPCH.h"
nuclear@0 43 #ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
nuclear@0 44
nuclear@0 45 #include "ObjFileMtlImporter.h"
nuclear@0 46 #include "ObjTools.h"
nuclear@0 47 #include "ObjFileData.h"
nuclear@0 48 #include "fast_atof.h"
nuclear@0 49
nuclear@0 50 namespace Assimp {
nuclear@0 51
nuclear@0 52 // Material specific token
nuclear@0 53 static const std::string DiffuseTexture = "map_kd";
nuclear@0 54 static const std::string AmbientTexture = "map_ka";
nuclear@0 55 static const std::string SpecularTexture = "map_ks";
nuclear@0 56 static const std::string OpacityTexture = "map_d";
nuclear@0 57 static const std::string BumpTexture1 = "map_bump";
nuclear@0 58 static const std::string BumpTexture2 = "map_Bump";
nuclear@0 59 static const std::string BumpTexture3 = "bump";
nuclear@0 60 static const std::string NormalTexture = "map_Kn";
nuclear@0 61 static const std::string DisplacementTexture = "disp";
nuclear@0 62 static const std::string SpecularityTexture = "map_ns";
nuclear@0 63
nuclear@0 64 // -------------------------------------------------------------------
nuclear@0 65 // Constructor
nuclear@0 66 ObjFileMtlImporter::ObjFileMtlImporter( std::vector<char> &buffer,
nuclear@0 67 const std::string & /*strAbsPath*/,
nuclear@0 68 ObjFile::Model *pModel ) :
nuclear@0 69 m_DataIt( buffer.begin() ),
nuclear@0 70 m_DataItEnd( buffer.end() ),
nuclear@0 71 m_pModel( pModel ),
nuclear@0 72 m_uiLine( 0 )
nuclear@0 73 {
nuclear@0 74 ai_assert( NULL != m_pModel );
nuclear@0 75 if ( NULL == m_pModel->m_pDefaultMaterial )
nuclear@0 76 {
nuclear@0 77 m_pModel->m_pDefaultMaterial = new ObjFile::Material;
nuclear@0 78 m_pModel->m_pDefaultMaterial->MaterialName.Set( "default" );
nuclear@0 79 }
nuclear@0 80 load();
nuclear@0 81 }
nuclear@0 82
nuclear@0 83 // -------------------------------------------------------------------
nuclear@0 84 // Destructor
nuclear@0 85 ObjFileMtlImporter::~ObjFileMtlImporter()
nuclear@0 86 {
nuclear@0 87 // empty
nuclear@0 88 }
nuclear@0 89
nuclear@0 90 // -------------------------------------------------------------------
nuclear@0 91 // Private copy constructor
nuclear@0 92 ObjFileMtlImporter::ObjFileMtlImporter(const ObjFileMtlImporter & /* rOther */ )
nuclear@0 93 {
nuclear@0 94 // empty
nuclear@0 95 }
nuclear@0 96
nuclear@0 97 // -------------------------------------------------------------------
nuclear@0 98 // Private copy constructor
nuclear@0 99 ObjFileMtlImporter &ObjFileMtlImporter::operator = ( const ObjFileMtlImporter & /*rOther */ )
nuclear@0 100 {
nuclear@0 101 return *this;
nuclear@0 102 }
nuclear@0 103
nuclear@0 104 // -------------------------------------------------------------------
nuclear@0 105 // Loads the material description
nuclear@0 106 void ObjFileMtlImporter::load()
nuclear@0 107 {
nuclear@0 108 if ( m_DataIt == m_DataItEnd )
nuclear@0 109 return;
nuclear@0 110
nuclear@0 111 while ( m_DataIt != m_DataItEnd )
nuclear@0 112 {
nuclear@0 113 switch (*m_DataIt)
nuclear@0 114 {
nuclear@0 115 case 'K':
nuclear@0 116 {
nuclear@0 117 ++m_DataIt;
nuclear@0 118 if (*m_DataIt == 'a') // Ambient color
nuclear@0 119 {
nuclear@0 120 ++m_DataIt;
nuclear@0 121 getColorRGBA( &m_pModel->m_pCurrentMaterial->ambient );
nuclear@0 122 }
nuclear@0 123 else if (*m_DataIt == 'd') // Diffuse color
nuclear@0 124 {
nuclear@0 125 ++m_DataIt;
nuclear@0 126 getColorRGBA( &m_pModel->m_pCurrentMaterial->diffuse );
nuclear@0 127 }
nuclear@0 128 else if (*m_DataIt == 's')
nuclear@0 129 {
nuclear@0 130 ++m_DataIt;
nuclear@0 131 getColorRGBA( &m_pModel->m_pCurrentMaterial->specular );
nuclear@0 132 }
nuclear@0 133 m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
nuclear@0 134 }
nuclear@0 135 break;
nuclear@0 136
nuclear@0 137 case 'd': // Alpha value
nuclear@0 138 {
nuclear@0 139 ++m_DataIt;
nuclear@0 140 getFloatValue( m_pModel->m_pCurrentMaterial->alpha );
nuclear@0 141 m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
nuclear@0 142 }
nuclear@0 143 break;
nuclear@0 144
nuclear@0 145 case 'N': // Shineness
nuclear@0 146 {
nuclear@0 147 ++m_DataIt;
nuclear@0 148 switch(*m_DataIt)
nuclear@0 149 {
nuclear@0 150 case 's':
nuclear@0 151 ++m_DataIt;
nuclear@0 152 getFloatValue(m_pModel->m_pCurrentMaterial->shineness);
nuclear@0 153 break;
nuclear@0 154 case 'i': //Index Of refraction
nuclear@0 155 ++m_DataIt;
nuclear@0 156 getFloatValue(m_pModel->m_pCurrentMaterial->ior);
nuclear@0 157 break;
nuclear@0 158 }
nuclear@0 159 m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
nuclear@0 160 break;
nuclear@0 161 }
nuclear@0 162 break;
nuclear@0 163
nuclear@0 164
nuclear@0 165 case 'm': // Texture
nuclear@0 166 case 'b': // quick'n'dirty - for 'bump' sections
nuclear@0 167 {
nuclear@0 168 getTexture();
nuclear@0 169 m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
nuclear@0 170 }
nuclear@0 171 break;
nuclear@0 172
nuclear@0 173 case 'n': // New material name
nuclear@0 174 {
nuclear@0 175 createMaterial();
nuclear@0 176 m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
nuclear@0 177 }
nuclear@0 178 break;
nuclear@0 179
nuclear@0 180 case 'i': // Illumination model
nuclear@0 181 {
nuclear@0 182 m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
nuclear@0 183 getIlluminationModel( m_pModel->m_pCurrentMaterial->illumination_model );
nuclear@0 184 m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
nuclear@0 185 }
nuclear@0 186 break;
nuclear@0 187
nuclear@0 188 default:
nuclear@0 189 {
nuclear@0 190 m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
nuclear@0 191 }
nuclear@0 192 break;
nuclear@0 193 }
nuclear@0 194 }
nuclear@0 195 }
nuclear@0 196
nuclear@0 197 // -------------------------------------------------------------------
nuclear@0 198 // Loads a color definition
nuclear@0 199 void ObjFileMtlImporter::getColorRGBA( aiColor3D *pColor )
nuclear@0 200 {
nuclear@0 201 ai_assert( NULL != pColor );
nuclear@0 202
nuclear@0 203 float r, g, b;
nuclear@0 204 m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, r );
nuclear@0 205 pColor->r = r;
nuclear@0 206
nuclear@0 207 m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, g );
nuclear@0 208 pColor->g = g;
nuclear@0 209
nuclear@0 210 m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, b );
nuclear@0 211 pColor->b = b;
nuclear@0 212 }
nuclear@0 213
nuclear@0 214 // -------------------------------------------------------------------
nuclear@0 215 // Loads the kind of illumination model.
nuclear@0 216 void ObjFileMtlImporter::getIlluminationModel( int &illum_model )
nuclear@0 217 {
nuclear@0 218 m_DataIt = CopyNextWord<DataArrayIt>( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE );
nuclear@0 219 illum_model = atoi(m_buffer);
nuclear@0 220 }
nuclear@0 221
nuclear@0 222 // -------------------------------------------------------------------
nuclear@0 223 // Loads a single float value.
nuclear@0 224 void ObjFileMtlImporter::getFloatValue( float &value )
nuclear@0 225 {
nuclear@0 226 m_DataIt = CopyNextWord<DataArrayIt>( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE );
nuclear@0 227 value = (float) fast_atof(m_buffer);
nuclear@0 228 }
nuclear@0 229
nuclear@0 230 // -------------------------------------------------------------------
nuclear@0 231 // Creates a material from loaded data.
nuclear@0 232 void ObjFileMtlImporter::createMaterial()
nuclear@0 233 {
nuclear@0 234 std::string line( "" );
nuclear@0 235 while ( !isNewLine( *m_DataIt ) ) {
nuclear@0 236 line += *m_DataIt;
nuclear@0 237 ++m_DataIt;
nuclear@0 238 }
nuclear@0 239
nuclear@0 240 std::vector<std::string> token;
nuclear@0 241 const unsigned int numToken = tokenize<std::string>( line, token, " " );
nuclear@0 242 std::string name( "" );
nuclear@0 243 if ( numToken == 1 ) {
nuclear@0 244 name = AI_DEFAULT_MATERIAL_NAME;
nuclear@0 245 } else {
nuclear@0 246 name = token[ 1 ];
nuclear@0 247 }
nuclear@0 248
nuclear@0 249 std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( name );
nuclear@0 250 if ( m_pModel->m_MaterialMap.end() == it) {
nuclear@0 251 // New Material created
nuclear@0 252 m_pModel->m_pCurrentMaterial = new ObjFile::Material();
nuclear@0 253 m_pModel->m_pCurrentMaterial->MaterialName.Set( name );
nuclear@0 254 m_pModel->m_MaterialLib.push_back( name );
nuclear@0 255 m_pModel->m_MaterialMap[ name ] = m_pModel->m_pCurrentMaterial;
nuclear@0 256 } else {
nuclear@0 257 // Use older material
nuclear@0 258 m_pModel->m_pCurrentMaterial = (*it).second;
nuclear@0 259 }
nuclear@0 260 }
nuclear@0 261
nuclear@0 262 // -------------------------------------------------------------------
nuclear@0 263 // Gets a texture name from data.
nuclear@0 264 void ObjFileMtlImporter::getTexture() {
nuclear@0 265 aiString *out( NULL );
nuclear@0 266
nuclear@0 267 const char *pPtr( &(*m_DataIt) );
nuclear@0 268 if ( !ASSIMP_strincmp( pPtr, DiffuseTexture.c_str(), DiffuseTexture.size() ) ) {
nuclear@0 269 // Diffuse texture
nuclear@0 270 out = & m_pModel->m_pCurrentMaterial->texture;
nuclear@0 271 } else if ( !ASSIMP_strincmp( pPtr,AmbientTexture.c_str(),AmbientTexture.size() ) ) {
nuclear@0 272 // Ambient texture
nuclear@0 273 out = & m_pModel->m_pCurrentMaterial->textureAmbient;
nuclear@0 274 } else if (!ASSIMP_strincmp( pPtr, SpecularTexture.c_str(), SpecularTexture.size())) {
nuclear@0 275 // Specular texture
nuclear@0 276 out = & m_pModel->m_pCurrentMaterial->textureSpecular;
nuclear@0 277 } else if ( !ASSIMP_strincmp( pPtr, OpacityTexture.c_str(), OpacityTexture.size() ) ) {
nuclear@0 278 // Opacity texture
nuclear@0 279 out = & m_pModel->m_pCurrentMaterial->textureOpacity;
nuclear@0 280 } else if (!ASSIMP_strincmp( pPtr,"map_ka",6)) {
nuclear@0 281 // Ambient texture
nuclear@0 282 out = & m_pModel->m_pCurrentMaterial->textureAmbient;
nuclear@0 283 } else if ( !ASSIMP_strincmp( pPtr, BumpTexture1.c_str(), BumpTexture1.size() ) ||
nuclear@0 284 !ASSIMP_strincmp( pPtr, BumpTexture2.c_str(), BumpTexture2.size() ) ||
nuclear@0 285 !ASSIMP_strincmp( pPtr, BumpTexture3.c_str(), BumpTexture3.size() ) ) {
nuclear@0 286 // Bump texture
nuclear@0 287 out = & m_pModel->m_pCurrentMaterial->textureBump;
nuclear@0 288 } else if (!ASSIMP_strincmp( pPtr,NormalTexture.c_str(), NormalTexture.size())) {
nuclear@0 289 // Normal map
nuclear@0 290 out = & m_pModel->m_pCurrentMaterial->textureNormal;
nuclear@0 291 } else if (!ASSIMP_strincmp( pPtr, DisplacementTexture.c_str(), DisplacementTexture.size() ) ) {
nuclear@0 292 // Displacement texture
nuclear@0 293 out = &m_pModel->m_pCurrentMaterial->textureDisp;
nuclear@0 294 } else if (!ASSIMP_strincmp( pPtr, SpecularityTexture.c_str(),SpecularityTexture.size() ) ) {
nuclear@0 295 // Specularity scaling (glossiness)
nuclear@0 296 out = & m_pModel->m_pCurrentMaterial->textureSpecularity;
nuclear@0 297 } else {
nuclear@0 298 DefaultLogger::get()->error("OBJ/MTL: Encountered unknown texture type");
nuclear@0 299 return;
nuclear@0 300 }
nuclear@0 301
nuclear@0 302 std::string strTexture;
nuclear@0 303 m_DataIt = getName<DataArrayIt>( m_DataIt, m_DataItEnd, strTexture );
nuclear@0 304 out->Set( strTexture );
nuclear@0 305 }
nuclear@0 306
nuclear@0 307 // -------------------------------------------------------------------
nuclear@0 308
nuclear@0 309 } // Namespace Assimp
nuclear@0 310
nuclear@0 311 #endif // !! ASSIMP_BUILD_NO_OBJ_IMPORTER