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
|