1 /*
2     Copyright (c) 2008-2009 NetAllied Systems GmbH
3 
4     This file is part of COLLADASaxFrameworkLoader.
5 
6     Licensed under the MIT Open Source License,
7     for details please see LICENSE file or the website
8     http://www.opensource.org/licenses/mit-license.php
9 */
10 
11 #include "COLLADASaxFWLStableHeaders.h"
12 #include "COLLADASaxFWLLibraryEffectsLoader.h"
13 #include "COLLADASaxFWLFileLoader.h"
14 
15 #include "COLLADAFWIWriter.h"
16 #include "COLLADAFWEffect.h"
17 #include "COLLADAFWImage.h"
18 
19 
20 namespace COLLADASaxFWL
21 {
22 
23     //------------------------------
LibraryEffectsLoader(IFilePartLoader * callingFilePartLoader)24 	LibraryEffectsLoader::LibraryEffectsLoader( IFilePartLoader* callingFilePartLoader )
25 		: LibraryImagesLoader(callingFilePartLoader)
26 		, mCurrentEffect(0)
27         , mTransparency(1)
28 		, mOpaqueMode(UNSPECIFIED_OPAQUE)
29         , mCurrentProfile(PROFILE_NONE)
30         , mCurrentShaderParameterType(UNKNOWN_SHADER_TYPE)
31         , mCurrentColorValueIndex(0)
32         , mCurrentSamplerWrapS(COLLADAFW::Sampler::WRAP_MODE_WRAP)
33         , mCurrentSamplerWrapT(COLLADAFW::Sampler::WRAP_MODE_WRAP)
34         , mCurrentSampler(0)
35 		, mNextSamplerIndex(0)
36         , mInProfileCommonTechnique (false)
37         , mInTexture (false)
38         , mInSurface (false)
39         , mSurfaceIndex (0)
40         , mInSampler2D (false)
41 	{
42 	}
43 
44     //------------------------------
~LibraryEffectsLoader()45 	LibraryEffectsLoader::~LibraryEffectsLoader()
46 	{
47 	}
48 
49 	//------------------------------
setCommonEffectShaderType(COLLADAFW::EffectCommon::ShaderType shaderType)50 	bool LibraryEffectsLoader::setCommonEffectShaderType( COLLADAFW::EffectCommon::ShaderType shaderType )
51 	{
52 		switch ( mCurrentProfile )
53 		{
54 		case PROFILE_COMMON:
55 			mCurrentEffect->getCommonEffects().back()->setShaderType( shaderType );
56 			break;
57         default:
58             break;
59 		}
60 		return true;
61 	}
62 
63 	//------------------------------
getCurrentColorOrTexture(const bool forTexture)64 	COLLADAFW::ColorOrTexture* LibraryEffectsLoader::getCurrentColorOrTexture ( const bool forTexture /*= false*/)
65 	{
66 		switch ( mCurrentShaderParameterType )
67 		{
68 		case SHADER_PARAMETER_EMISSION:
69 			{
70 				return &mCurrentEffect->getCommonEffects().back()->getEmission();
71 			}
72 		case SHADER_PARAMETER_AMBIENT:
73 			{
74 				return &mCurrentEffect->getCommonEffects().back()->getAmbient();
75 			}
76 		case SHADER_PARAMETER_DIFFUSE:
77 			{
78 				return &mCurrentEffect->getCommonEffects().back()->getDiffuse();
79 			}
80 		case SHADER_PARAMETER_SPECULAR:
81 			{
82 				return &mCurrentEffect->getCommonEffects().back()->getSpecular();
83 			}
84 		case SHADER_PARAMETER_REFLECTIVE:
85 			{
86 				return &mCurrentEffect->getCommonEffects().back()->getReflective();
87 			}
88 		case SHADER_PARAMETER_TRANSPARENT:
89 			{
90                 if ( forTexture )
91                     return &mCurrentEffect->getCommonEffects().back()->getOpacity();
92                 else
93     				return &mTransparent;
94 			}
95 		default:
96 			return 0;
97 		}
98 	}
99 
100 	//------------------------------
handleColorData(const float * data,size_t length)101 	bool LibraryEffectsLoader::handleColorData( const float* data, size_t length )
102 	{
103 		switch ( mCurrentProfile )
104 		{
105 		case PROFILE_COMMON:
106 			{
107 				COLLADAFW::ColorOrTexture* colorOrTexture = getCurrentColorOrTexture();
108 				colorOrTexture->setType(COLLADAFW::ColorOrTexture::COLOR);
109 				handleColorData(data, length, colorOrTexture->getColor());
110 
111 				break;
112 			}
113         default:
114             break;
115 		}
116 		return true;
117 
118 	}
119 
120 	//------------------------------
handleColorData(const float * data,size_t length,COLLADAFW::Color & color)121 	bool LibraryEffectsLoader::handleColorData( const float* data, size_t length, COLLADAFW::Color& color )
122 	{
123 		for ( size_t i = 0; i < length; ++i)
124 		{
125 			switch ( mCurrentColorValueIndex )
126 			{
127 			case 0:
128 				color.setRed(data[i]);
129 				break;
130 			case 1:
131 				color.setGreen(data[i]);
132 				break;
133 			case 2:
134 				color.setBlue(data[i]);
135 				break;
136 			case 3:
137 				color.setAlpha(data[i]);
138 				break;
139 			}
140 			mCurrentColorValueIndex++;
141 		}
142 		return true;
143 	}
144 
145 
146 	//------------------------------
handleTexture(const texture__AttributeData & attributeData)147 	bool LibraryEffectsLoader::handleTexture( const texture__AttributeData& attributeData )
148 	{
149 		bool success = true;
150 		switch ( mCurrentProfile )
151 		{
152 		case PROFILE_COMMON:
153 			{
154                 // Get the current color or texture element.
155 				COLLADAFW::ColorOrTexture* colorOrTexture = getCurrentColorOrTexture ( true );
156 
157                 // Check if the texture is referenced.
158                 String textureSid = (const char *)attributeData.texture;
159 				SidSamplerInfoMap::const_iterator it = mEffectProfileSidSamplerInfoMap.find(textureSid);
160 				if ( it == mEffectProfileSidSamplerInfoMap.end() )
161                 {
162                     it = mEffectSidSamplerInfoMap.find((const char*)attributeData.texture);
163                     if ( it == mEffectSidSamplerInfoMap.end() )
164                     {
165 						String msg("Texture with sid \"" + textureSid + "\" not found");
166 						if ( mCurrentEffect )
167 						{
168 							msg += " in effect with id \"" + mCurrentEffect->getOriginalId() + "\"";
169 						}
170 						msg += ".";
171                         success = handleFWLError ( SaxFWLError::ERROR_UNRESOLVED_REFERENCE, msg );
172                         break;
173                     }
174                 }
175 
176 				// Push the texture sid of the current sampler in the list of used samplers
177 				// of the current effect profile.
178 				size_t samplerIndex = 0;
179 				StringIndexMap::const_iterator samplerIt = mEffectProfileSamplersMap.find(textureSid);
180 				if ( samplerIt == mEffectProfileSamplersMap.end() )
181 				{
182 					// This sid has not been used before. Add to map with next index
183 					samplerIndex = mNextSamplerIndex;
184 					mEffectProfileSamplersMap.insert(std::make_pair(textureSid, mNextSamplerIndex++));
185 				}
186 				else
187 				{
188 					// This sid is already in the map. Use its index
189 					samplerIndex = samplerIt->second;
190 				}
191 
192 				// Initialize the texture element.
193 				/* const SamplerInfo& samplerInfo = it->second; */ /* UNUSED */
194 				colorOrTexture->setType(COLLADAFW::ColorOrTexture::TEXTURE);
195 				COLLADAFW::Texture& texture = colorOrTexture->getTexture();
196                 texture.setUniqueId ( createUniqueId(COLLADAFW::Texture::ID()) );
197 				texture.setSamplerId( samplerIndex );
198 				if ( attributeData.texcoord )
199 				{
200 					texture.setTextureMapId( getTextureMapIdBySematic( attributeData.texcoord) );
201                     texture.setTexcoord(attributeData.texcoord);
202                 }
203 
204 				break;
205 			}
206             /*
207                 PROFILE_BRIDGE,
208                 PROFILE_CG,
209                 PROFILE_GLES,
210                 PROFILE_GLES2,
211                 PROFILE_GLSL,
212                 PROFILE_COMMON,
213                 PROFILE_NONE
214               */
215             default:
216                 break;
217 		}
218 		return success;
219 
220 	}
221 
222 	//------------------------------
handleExtraEffectTextures(const COLLADAFW::PointerArray<COLLADAFW::TextureAttributes> & effectTextures)223 	bool LibraryEffectsLoader::handleExtraEffectTextures( const COLLADAFW::PointerArray<COLLADAFW::TextureAttributes>& effectTextures )
224 	{
225 		bool success = true;
226 
227 		size_t countExtraTextures = effectTextures.getCount();
228 		if( countExtraTextures == 0 )
229 			return success;
230 
231 // 		switch ( mCurrentProfile )
232 // 		{
233 // 		case PROFILE_COMMON:
234 //			{
235 
236 		for( size_t iTexture = 0; iTexture < countExtraTextures; ++iTexture )
237 		{
238 			COLLADAFW::TextureAttributes* textureAttributes = effectTextures[iTexture];
239 			if( textureAttributes == 0 )
240 				continue;
241 
242 			// Check if the texture is referenced.
243 			const String& textureSid = textureAttributes->textureSampler;
244 			SidSamplerInfoMap::const_iterator it = mEffectProfileSidSamplerInfoMap.find(textureSid);
245 			if ( it == mEffectProfileSidSamplerInfoMap.end() )
246 			{
247 				it = mEffectSidSamplerInfoMap.find( textureSid );
248 				if ( it == mEffectSidSamplerInfoMap.end() )
249 				{
250 					String msg("Texture with sid \"" + textureSid + "\" not found");
251 					if ( mCurrentEffect )
252 					{
253 						msg += " in effect with id \"" + mCurrentEffect->getOriginalId() + "\"";
254 					}
255 					msg += ".";
256 					success = handleFWLError ( SaxFWLError::ERROR_UNRESOLVED_REFERENCE, msg );
257 					continue;;
258 				}
259 			}
260 
261 			// Push the texture sid of the current sampler in the list of used samplers
262 			// of the current effect profile.
263 			size_t samplerIndex = 0;
264 			StringIndexMap::const_iterator samplerIt = mEffectProfileSamplersMap.find(textureSid);
265 			if ( samplerIt == mEffectProfileSamplersMap.end() )
266 			{
267 				// This sid has not been used before. Add to map with next index
268 				samplerIndex = mNextSamplerIndex;
269 				mEffectProfileSamplersMap.insert(std::make_pair(textureSid, mNextSamplerIndex++));
270 			}
271 			else
272 			{
273 				// This sid is already in the map. Use its index
274 				samplerIndex = samplerIt->second;
275 			}
276 
277 			// Initialize the texture element.
278 			//bumpMap.setUniqueId ( createUniqueId(COLLADAFW::Texture::ID()) ); //texture id?
279 			textureAttributes->samplerId = samplerIndex;
280 			if ( !(textureAttributes->texCoord.empty()) )
281 				textureAttributes->textureMapId = getTextureMapIdBySematic( textureAttributes->texCoord );
282 		}
283 
284 //				break;
285 //			}
286 //		}
287 		return success;
288 	}
289 
290 	//------------------------------
calculateLuminance(const COLLADAFW::Color & color)291 	double LibraryEffectsLoader::calculateLuminance ( const COLLADAFW::Color& color )
292 	{
293 		return ( (color.getRed () * 0.212671) + (color.getGreen () * 0.715160) + (color.getBlue () * 0.072169) );
294 	}
295 
296 	//------------------------------
calculateOpacity()297 	void LibraryEffectsLoader::calculateOpacity ()
298 	{
299 		// If we have already a texture as opacity, we don't need to calculate the opacity color.
300 		COLLADAFW::ColorOrTexture& opacity = mCurrentEffect->getCommonEffects ().back ()->getOpacity ();
301 		if ( opacity.isTexture () ) return;
302 
303 		// Calculate the opacity.
304 		if ( mTransparent.isColor () )
305 		{
306 			opacity.setType ( COLLADAFW::ColorOrTexture::COLOR );
307 			COLLADAFW::Color& opaqueColor = opacity.getColor ();
308 
309 			COLLADAFW::Color& transparentColor = mTransparent.getColor ();
310 			switch ( mOpaqueMode )
311 			{
312 			case LibraryEffectsLoader::A_ZERO:
313 				{
314 					opaqueColor.setRed ( 1 - transparentColor.getAlpha () * mTransparency.getFloatValue () );
315 					opaqueColor.setGreen ( 1 - transparentColor.getAlpha () * mTransparency.getFloatValue () );
316 					opaqueColor.setBlue ( 1 - transparentColor.getAlpha () * mTransparency.getFloatValue () );
317 					opaqueColor.setAlpha ( 1 - transparentColor.getAlpha () * mTransparency.getFloatValue () );
318 					break;
319 				}
320 			case LibraryEffectsLoader::RGB_ONE:
321 				{
322 					opaqueColor.setRed ( transparentColor.getRed () * mTransparency.getFloatValue () );
323 					opaqueColor.setGreen ( transparentColor.getGreen () * mTransparency.getFloatValue () );
324 					opaqueColor.setBlue ( transparentColor.getBlue () * mTransparency.getFloatValue () );
325 					opaqueColor.setAlpha ( calculateLuminance ( transparentColor ) * mTransparency.getFloatValue () );
326 					break;
327 				}
328 			case LibraryEffectsLoader::RGB_ZERO:
329 				{
330 					opaqueColor.setRed ( 1 - transparentColor.getRed () * mTransparency.getFloatValue () );
331 					opaqueColor.setGreen ( 1 - transparentColor.getGreen () * mTransparency.getFloatValue () );
332 					opaqueColor.setBlue ( 1 - transparentColor.getBlue () * mTransparency.getFloatValue () );
333 					opaqueColor.setAlpha ( 1 - calculateLuminance ( transparentColor ) * mTransparency.getFloatValue () );
334 					break;
335 				}
336             case LibraryEffectsLoader::A_ONE:
337 			case LibraryEffectsLoader::UNSPECIFIED_OPAQUE:
338 			default:
339 				{
340 					// A_ONE is the default:
341 					opaqueColor.setRed ( transparentColor.getAlpha () * mTransparency.getFloatValue () );
342 					opaqueColor.setGreen ( transparentColor.getAlpha () * mTransparency.getFloatValue () );
343 					opaqueColor.setBlue ( transparentColor.getAlpha () * mTransparency.getFloatValue () );
344 					opaqueColor.setAlpha ( transparentColor.getAlpha () * mTransparency.getFloatValue () );
345 					break;
346 				}
347 			}
348 
349 
350 			// Reset the transparent color.
351 			transparentColor.set (-1,-1,-1,-1);
352 		}
353 		else
354 		{
355 			opacity.setType ( COLLADAFW::ColorOrTexture::COLOR );
356 			COLLADAFW::Color& opaqueColor = opacity.getColor ();
357 
358 			switch ( mOpaqueMode )
359 			{
360 			case LibraryEffectsLoader::A_ONE:
361 			case LibraryEffectsLoader::RGB_ONE:
362 				{
363 					opaqueColor.set ( mTransparency.getFloatValue (), mTransparency.getFloatValue (), mTransparency.getFloatValue (), mTransparency.getFloatValue () );
364 					break;
365 				}
366 			case LibraryEffectsLoader::A_ZERO:
367 			case LibraryEffectsLoader::RGB_ZERO:
368 				{
369 					opaqueColor.set ( 1-mTransparency.getFloatValue (), 1-mTransparency.getFloatValue (), 1-mTransparency.getFloatValue (), 1-mTransparency.getFloatValue () );
370 					break;
371 				}
372 			case LibraryEffectsLoader::UNSPECIFIED_OPAQUE:
373 			default:
374 				{
375 					// A_ONE is the default:
376 					opaqueColor.set ( mTransparency.getFloatValue (), mTransparency.getFloatValue (), mTransparency.getFloatValue (), mTransparency.getFloatValue () );
377 					break;
378 				}
379 			}
380 		}
381 
382 		// Reset the transparent, transparency and opaque values.
383 		mTransparency = 1;
384 		mTransparent.setType ( COLLADAFW::ColorOrTexture::UNSPECIFIED );
385 		mOpaqueMode = LibraryEffectsLoader::UNSPECIFIED_OPAQUE;
386 	}
387 
388 	//------------------------------
begin__effect(const effect__AttributeData & attributeData)389 	bool LibraryEffectsLoader::begin__effect( const effect__AttributeData& attributeData )
390 	{
391 		mCurrentEffect = FW_NEW COLLADAFW::Effect(createUniqueIdFromId(attributeData.id, COLLADAFW::Effect::ID()));
392 
393         if ( attributeData.name )
394             mCurrentEffect->setName ( (const char*)attributeData.name );
395         else if ( attributeData.id )
396             mCurrentEffect->setName ( (const char*)attributeData.id );
397 
398         if ( attributeData.id )
399             mCurrentEffect->setOriginalId ( (const char*)attributeData.id );
400 
401         addToSidTree( attributeData.id, 0);
402 
403         return true;
404 	}
405 
406 	//------------------------------
end__effect()407 	bool LibraryEffectsLoader::end__effect()
408 	{
409 		COLLADASaxFWL::FileLoader* fileLoader = getFileLoader();
410 		fileLoader->addEffect(mCurrentEffect);
411 
412         mCurrentEffect = 0;
413         SidSamplerInfoMap::iterator samplerIt = mEffectSidSamplerInfoMap.begin();
414         for ( ; samplerIt != mEffectSidSamplerInfoMap.end(); ++samplerIt)
415         {
416             SamplerInfo& samplerInfo = samplerIt->second;
417             delete samplerInfo.sampler;
418         }
419         mEffectSidSamplerInfoMap.clear();
420         mEffectSidSurfaceMap.clear();
421 
422         moveUpInSidTree();
423 
424 		return true;
425 	}
426 
427 	//------------------------------
begin__profile_COMMON(const profile_COMMON__AttributeData & attributeData)428 	bool LibraryEffectsLoader::begin__profile_COMMON( const profile_COMMON__AttributeData& attributeData )
429 	{
430 		mCurrentProfile = PROFILE_COMMON;
431 		mCurrentEffect->getCommonEffects().append(FW_NEW COLLADAFW::EffectCommon() );
432 		addToSidTree( attributeData.id, 0);
433 
434         if ( attributeData.id )
435             mCurrentEffect->getCommonEffects ().back ()->setOriginalId ( (const char*)attributeData.id );
436 
437 		return true;
438 	}
439 
440 	//------------------------------
end__profile_COMMON()441 	bool LibraryEffectsLoader::end__profile_COMMON()
442 	{
443         // Store values original transparency and transparent values
444         mCurrentEffect->getCommonEffects ().back ()->setTransparent (mTransparent);
445         mCurrentEffect->getCommonEffects ().back ()->setTransparency(mTransparency);
446         mCurrentEffect->getCommonEffects ().back ()->setOpaqueMode((COLLADAFW::EffectCommon::OpaqueMode)mOpaqueMode);
447 
448 		// Calculate the opacity value.
449 		calculateOpacity ();
450 
451 		const COLLADAFW::PointerArray<COLLADAFW::TextureAttributes>& effectTextures = mCurrentEffect->getExtraTextures();
452 		handleExtraEffectTextures( effectTextures );
453 
454         // Fill the array of samplers of the current profile.
455         if ( !fillSamplerArray() )
456 			return false;
457 
458         SidSamplerInfoMap::iterator samplerIt = mEffectProfileSidSamplerInfoMap.begin();
459         for ( ; samplerIt != mEffectProfileSidSamplerInfoMap.end(); ++samplerIt)
460         {
461             SamplerInfo& samplerInfo = samplerIt->second;
462             delete samplerInfo.sampler;
463         }
464         mEffectProfileSidSamplerInfoMap.clear();
465         mEffectProfileSidSurfaceMap.clear();
466         mEffectProfileSamplersMap.clear ();
467 		mNextSamplerIndex = 0;
468 
469 		mTransparent.getColor ().set ( -1, -1, -1, -1 );
470 		mCurrentProfile = PROFILE_NONE;
471 
472 		moveUpInSidTree();
473 
474         return true;
475 	}
476 
477 	//------------------------------
begin__surface____fx_surface_common(const surface____fx_surface_common__AttributeData & attributeData)478 	bool LibraryEffectsLoader::begin__surface____fx_surface_common( const surface____fx_surface_common__AttributeData& attributeData )
479 	{
480         mInSurface = true;
481         ++mSurfaceIndex;
482 
483 		mCurrentSurface.surfaceType = attributeData.type;
484 		return true;
485 	}
486 
487 	//------------------------------
end__surface____fx_surface_common()488 	bool LibraryEffectsLoader::end__surface____fx_surface_common()
489 	{
490         // Check if we have a surface defined directly under an effect or under an effect profile.
491         if ( mCurrentProfile == PROFILE_NONE )
492             mEffectSidSurfaceMap.insert(std::make_pair(mCurrentNewParamSid, mCurrentSurface));
493         else
494             mEffectProfileSidSurfaceMap.insert(std::make_pair(mCurrentNewParamSid, mCurrentSurface));
495 
496         mInSurface = false;
497 
498         return true;
499 	}
500 
501 	//------------------------------
begin__init_from____fx_surface_init_from_common(const init_from____fx_surface_init_from_common__AttributeData & attributeData)502     bool LibraryEffectsLoader::begin__init_from____fx_surface_init_from_common( const init_from____fx_surface_init_from_common__AttributeData& attributeData ) {
503 		mCurrentSurfaceInitFrom.clear();
504         return true;
505     }
506 
507 	//------------------------------
end__init_from____fx_surface_init_from_common()508 	bool LibraryEffectsLoader::end__init_from____fx_surface_init_from_common()
509 	{
510 		mCurrentSurface.imageUniqueId = createUniqueIdFromId((const ParserChar*)mCurrentSurfaceInitFrom.c_str(), COLLADAFW::Image::ID());
511 		return true;
512 	}
513 
514 	//------------------------------
data__init_from____fx_surface_init_from_common(const ParserChar * data,size_t length)515 	bool LibraryEffectsLoader::data__init_from____fx_surface_init_from_common( const ParserChar* data, size_t length )
516 	{
517 		mCurrentSurfaceInitFrom.append((const char* )data, length);
518 		return true;
519 	}
520 
521     //------------------------------
begin__instance_image(const instance_image__AttributeData & attributeData)522     bool LibraryEffectsLoader::begin__instance_image( const instance_image__AttributeData& attributeData )
523     {
524         if ( (attributeData.present_attributes & instance_image__AttributeData::ATTRIBUTE_URL_PRESENT) == instance_image__AttributeData::ATTRIBUTE_URL_PRESENT )
525         {
526             mCurrentSampler->setSource(createUniqueIdFromUrl(attributeData.url, COLLADAFW::Image::ID()));
527         }
528         return true;
529     }
530 
531     //------------------------------
begin__newparam____fx_newparam_common(const newparam____fx_newparam_common__AttributeData & attributeData)532     bool LibraryEffectsLoader::begin__newparam____fx_newparam_common( const newparam____fx_newparam_common__AttributeData& attributeData )
533     {
534         if ( attributeData.sid )
535             mCurrentNewParamSid = (const char *)attributeData.sid;
536         return true;
537     }
538 
539     //------------------------------
end__newparam____fx_newparam_common()540     bool LibraryEffectsLoader::end__newparam____fx_newparam_common()
541     {
542         mCurrentNewParamSid.clear();
543         return true;
544     }
545 
546     //------------------------------
begin__newparam____cg_newparam(const newparam____cg_newparam__AttributeData & attributeData)547     bool LibraryEffectsLoader::begin__newparam____cg_newparam( const newparam____cg_newparam__AttributeData& attributeData )
548     {
549         addToSidTree( 0, (const char *) attributeData.sid );
550         return true;
551     }
552 
553 	//------------------------------
begin__newparam____common_newparam_type(const newparam____common_newparam_type__AttributeData & attributeData)554 	bool LibraryEffectsLoader::begin__newparam____common_newparam_type( const newparam____common_newparam_type__AttributeData& attributeData )
555 	{
556 		if ( attributeData.sid )
557 			mCurrentNewParamSid = (const char *)attributeData.sid;
558 		return true;
559 	}
560 
561 	//------------------------------
end__newparam____common_newparam_type()562 	bool LibraryEffectsLoader::end__newparam____common_newparam_type()
563 	{
564 		mCurrentNewParamSid.clear();
565 		return true;
566 	}
567 
568 	//------------------------------
begin__sampler2D____fx_sampler2D_common()569 	bool LibraryEffectsLoader::begin__sampler2D____fx_sampler2D_common()
570 	{
571 		mCurrentSamplerSource.clear();
572         mInSampler2D = true;
573 		mCurrentSampler = new COLLADAFW::Sampler( createUniqueId (COLLADAFW::Sampler::ID()));
574 		mCurrentSampler->setSamplerType( COLLADAFW::Sampler::SAMPLER_TYPE_2D );
575 		return true;
576 	}
577 
578 	//------------------------------
end__sampler2D____fx_sampler2D_common()579 	bool LibraryEffectsLoader::end__sampler2D____fx_sampler2D_common()
580 	{
581 		SamplerInfo samplerInfo;
582 		samplerInfo.sampler = mCurrentSampler;
583 		samplerInfo.id = 0;
584 		samplerInfo.surfaceSid = mCurrentSamplerSource;
585 
586 		samplerInfo.sampler->setWrapS(mCurrentSamplerWrapS);
587 		samplerInfo.sampler->setWrapT(mCurrentSamplerWrapT);
588 
589         // Check if we have a sampler defined directly under an effect or under an effect profile.
590         if ( mCurrentProfile == PROFILE_NONE )
591             mEffectSidSamplerInfoMap.insert(std::make_pair(mCurrentNewParamSid, samplerInfo));
592         else
593     		mEffectProfileSidSamplerInfoMap.insert(std::make_pair(mCurrentNewParamSid, samplerInfo));
594 
595 		mCurrentSampler = 0;
596 		mCurrentSamplerSource.clear();
597 
598 		mCurrentSamplerWrapS = COLLADAFW::Sampler::WRAP_MODE_WRAP;
599 		mCurrentSamplerWrapT = COLLADAFW::Sampler::WRAP_MODE_WRAP;
600 
601         mInSampler2D = false;
602 
603 		return true;
604 	}
605 
606 	//------------------------------
data__source____NCName(const ParserChar * data,size_t length)607 	bool LibraryEffectsLoader::data__source____NCName( const ParserChar* data, size_t length )
608 	{
609 		mCurrentSamplerSource.append((const char* )data, length);
610 		return true;
611 	}
612 
data__wrap_s____fx_sampler_wrap_common(const ENUM__fx_sampler_wrap_common value)613 	bool LibraryEffectsLoader::data__wrap_s____fx_sampler_wrap_common( const ENUM__fx_sampler_wrap_common value )
614 	{
615 		switch (value)
616 		{
617 			case ENUM__fx_sampler_wrap_common__CLAMP:
618 				mCurrentSamplerWrapS = COLLADAFW::Sampler::WRAP_MODE_CLAMP;
619 				break;
620 
621 			case ENUM__fx_sampler_wrap_common__MIRROR:
622 				mCurrentSamplerWrapS = COLLADAFW::Sampler::WRAP_MODE_MIRROR;
623 				break;
624 
625 			case ENUM__fx_sampler_wrap_common__WRAP:
626 				mCurrentSamplerWrapS = COLLADAFW::Sampler::WRAP_MODE_WRAP;
627 				break;
628 
629 			case ENUM__fx_sampler_wrap_common__BORDER:
630 				mCurrentSamplerWrapS = COLLADAFW::Sampler::WRAP_MODE_BORDER;
631 				break;
632 
633 			case ENUM__fx_sampler_wrap_common__NONE:
634 				mCurrentSamplerWrapS = COLLADAFW::Sampler::WRAP_MODE_NONE;
635 				break;
636 
637 			case ENUM__fx_sampler_wrap_common__NOT_PRESENT:
638 				mCurrentSamplerWrapS = COLLADAFW::Sampler::WRAP_MODE_UNSPECIFIED;
639 				break;
640             default:
641                 break;
642 		}
643 
644 		return true;
645 	}
646 
data__wrap_t____fx_sampler_wrap_common(const ENUM__fx_sampler_wrap_common value)647 	bool LibraryEffectsLoader::data__wrap_t____fx_sampler_wrap_common( const ENUM__fx_sampler_wrap_common value )
648 	{
649 		switch (value)
650 		{
651 			case ENUM__fx_sampler_wrap_common__CLAMP:
652 				mCurrentSamplerWrapT = COLLADAFW::Sampler::WRAP_MODE_CLAMP;
653 				break;
654 
655 			case ENUM__fx_sampler_wrap_common__MIRROR:
656 				mCurrentSamplerWrapT = COLLADAFW::Sampler::WRAP_MODE_MIRROR;
657 				break;
658 
659 			case ENUM__fx_sampler_wrap_common__WRAP:
660 				mCurrentSamplerWrapT = COLLADAFW::Sampler::WRAP_MODE_WRAP;
661 				break;
662 
663 			case ENUM__fx_sampler_wrap_common__BORDER:
664 				mCurrentSamplerWrapT = COLLADAFW::Sampler::WRAP_MODE_BORDER;
665 				break;
666 
667 			case ENUM__fx_sampler_wrap_common__NONE:
668 				mCurrentSamplerWrapT = COLLADAFW::Sampler::WRAP_MODE_NONE;
669 				break;
670 
671 			case ENUM__fx_sampler_wrap_common__NOT_PRESENT:
672 				mCurrentSamplerWrapT = COLLADAFW::Sampler::WRAP_MODE_UNSPECIFIED;
673 				break;
674             default:
675                 break;
676 		}
677 
678 		return true;
679 	}
680 
681 	//------------------------------
begin__profile_COMMON__technique(const profile_COMMON__technique__AttributeData & attributeData)682 	bool LibraryEffectsLoader::begin__profile_COMMON__technique( const profile_COMMON__technique__AttributeData& attributeData )
683 	{
684         mInProfileCommonTechnique = true;
685 
686 		addToSidTree( attributeData.id, attributeData.sid );
687 
688 		return true;
689 	}
690 
691 	//------------------------------
end__profile_COMMON__technique()692 	bool LibraryEffectsLoader::end__profile_COMMON__technique()
693 	{
694 		moveUpInSidTree();
695 
696         mInProfileCommonTechnique = false;
697 
698         return true;
699 	}
700 
701 	//------------------------------
begin__profile_COMMON__technique__constant()702 	bool LibraryEffectsLoader::begin__profile_COMMON__technique__constant()
703 	{
704 		return setCommonEffectShaderType(COLLADAFW::EffectCommon::SHADER_CONSTANT);
705 	}
706 
707 	//------------------------------
begin__lambert()708 	bool LibraryEffectsLoader::begin__lambert()
709 	{
710 		return setCommonEffectShaderType(COLLADAFW::EffectCommon::SHADER_LAMBERT);
711 	}
712 
713 	//------------------------------
begin__blinn()714 	bool LibraryEffectsLoader::begin__blinn()
715 	{
716 		return setCommonEffectShaderType(COLLADAFW::EffectCommon::SHADER_BLINN);
717 	}
718 
719 
720 	//------------------------------
begin__phong()721 	bool LibraryEffectsLoader::begin__phong()
722 	{
723 		return setCommonEffectShaderType(COLLADAFW::EffectCommon::SHADER_PHONG);
724 	}
725 
726 	//------------------------------
end__library_effects()727 	bool LibraryEffectsLoader::end__library_effects()
728 	{
729 		moveUpInSidTree();
730 		finish();
731 		return true;
732 	}
733 
734 	//------------------------------
begin__common_color_or_texture_type____color(const common_color_or_texture_type____color__AttributeData & attributeData)735 	bool LibraryEffectsLoader::begin__common_color_or_texture_type____color( const common_color_or_texture_type____color__AttributeData& attributeData )
736 	{
737 		COLLADAFW::ColorOrTexture* colorOrTexture = getCurrentColorOrTexture();
738 		addToSidTree( 0, attributeData.sid, &colorOrTexture->getColor() );
739 		return true;
740 	}
741 
742 	//------------------------------
end__common_color_or_texture_type____color()743 	bool LibraryEffectsLoader::end__common_color_or_texture_type____color()
744 	{
745 		mCurrentColorValueIndex = 0;
746 		moveUpInSidTree();
747 		return true;
748 	}
749 
750 	//------------------------------
data__common_color_or_texture_type____color(const float * data,size_t length)751 	bool LibraryEffectsLoader::data__common_color_or_texture_type____color( const float* data, size_t length )
752 	{
753 		return handleColorData(data, length);
754 	}
755 
756     //------------------------------
begin__texture(const texture__AttributeData & attributeData)757 	bool LibraryEffectsLoader::begin__texture( const texture__AttributeData& attributeData )
758 	{
759         mInTexture = true;
760 
761 		return handleTexture( attributeData);
762 	}
763 
764     //------------------------------
end__texture()765     bool LibraryEffectsLoader::end__texture ()
766     {
767         mInTexture = false;
768 
769         return true;
770     }
771 
772     //------------------------------
begin__common_float_or_param_type____float(const common_float_or_param_type____float__AttributeData & attributeData)773     bool LibraryEffectsLoader::begin__common_float_or_param_type____float ( const common_float_or_param_type____float__AttributeData& attributeData )
774     {
775         switch ( mCurrentShaderParameterType)
776         {
777         case SHADER_PARAMETER_SHININESS:
778             addToSidTree( 0, attributeData.sid, &mCurrentEffect->getCommonEffects().back()->getShininess() );
779             break;
780         case SHADER_PARAMETER_REFLECTIVITY:
781             addToSidTree( 0, attributeData.sid, &mCurrentEffect->getCommonEffects().back()->getReflectivity() );
782             break;
783         case SHADER_PARAMETER_INDEX_OF_REFRACTION:
784             addToSidTree( 0, attributeData.sid, &mCurrentEffect->getCommonEffects().back()->getIndexOfRefraction() );
785             break;
786         case SHADER_PARAMETER_TRANSPARENCY:
787             addToSidTree( 0, attributeData.sid, &mTransparency );
788             break;
789         default:
790             break;
791         }
792         return true;
793     }
794 
795     //------------------------------
end__common_float_or_param_type____float()796     bool LibraryEffectsLoader::end__common_float_or_param_type____float ()
797     {
798         moveUpInSidTree();
799         return true;
800     }
801 
802 	//------------------------------
data__common_float_or_param_type____float(float value)803 	bool LibraryEffectsLoader::data__common_float_or_param_type____float( float value )
804 	{
805 		switch ( mCurrentShaderParameterType)
806 		{
807 		case SHADER_PARAMETER_SHININESS:
808 			mCurrentEffect->getCommonEffects().back()->setShininess(value);
809 			break;
810 		case SHADER_PARAMETER_REFLECTIVITY:
811 			mCurrentEffect->getCommonEffects().back()->setReflectivity(value);
812 			break;
813 		case SHADER_PARAMETER_INDEX_OF_REFRACTION:
814 			mCurrentEffect->getCommonEffects().back()->setIndexOfRefraction(value);
815 			break;
816 		case SHADER_PARAMETER_TRANSPARENCY:
817 			mTransparency.setFloatValue (value);
818 			break;
819         default:
820             break;
821 		}
822 
823 		return true;
824 	}
825 
826 	//------------------------------
begin__emission()827 	bool LibraryEffectsLoader::begin__emission()
828 	{
829 		mCurrentShaderParameterType = SHADER_PARAMETER_EMISSION;
830 		return true;
831 	}
832 
833 	//------------------------------
end__emission()834 	bool LibraryEffectsLoader::end__emission()
835 	{
836 		mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE;
837 		return true;
838 	}
839 
840 	//------------------------------
begin__ambient____common_color_or_texture_type()841 	bool LibraryEffectsLoader::begin__ambient____common_color_or_texture_type()
842 	{
843 		mCurrentShaderParameterType = SHADER_PARAMETER_AMBIENT;
844 		return true;
845 	}
846 
847 	//------------------------------
end__ambient____common_color_or_texture_type()848 	bool LibraryEffectsLoader::end__ambient____common_color_or_texture_type()
849 	{
850 		mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE;
851 		return true;
852 	}
853 
854 	//------------------------------
begin__diffuse()855 	bool LibraryEffectsLoader::begin__diffuse()
856 	{
857 		mCurrentShaderParameterType = SHADER_PARAMETER_DIFFUSE;
858 		return true;
859 	}
860 
861 	//------------------------------
end__diffuse()862 	bool LibraryEffectsLoader::end__diffuse()
863 	{
864 		mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE;
865 		return true;
866 	}
867 
868 	//------------------------------
begin__specular()869 	bool LibraryEffectsLoader::begin__specular()
870 	{
871 		mCurrentShaderParameterType = SHADER_PARAMETER_SPECULAR;
872 		return true;
873 	}
874 
875 	//------------------------------
end__specular()876 	bool LibraryEffectsLoader::end__specular()
877 	{
878 		mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE;
879 		return true;
880 	}
881 
882 	//------------------------------
begin__shininess()883 	bool LibraryEffectsLoader::begin__shininess()
884 	{
885 		mCurrentShaderParameterType = SHADER_PARAMETER_SHININESS;
886 		return true;
887 	}
888 
889 	//------------------------------
end__shininess()890 	bool LibraryEffectsLoader::end__shininess()
891 	{
892 		mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE;
893 		return true;
894 	}
895 
896 	//------------------------------
begin__reflective()897 	bool LibraryEffectsLoader::begin__reflective()
898 	{
899 		mCurrentShaderParameterType = SHADER_PARAMETER_REFLECTIVE;
900 		return true;
901 	}
902 
903 	//------------------------------
end__reflective()904 	bool LibraryEffectsLoader::end__reflective()
905 	{
906 		mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE;
907 		return true;
908 	}
909 
910 	//------------------------------
begin__reflectivity()911 	bool LibraryEffectsLoader::begin__reflectivity()
912 	{
913 		mCurrentShaderParameterType = SHADER_PARAMETER_REFLECTIVITY;
914 		return true;
915 	}
916 
917 	//------------------------------
end__reflectivity()918 	bool LibraryEffectsLoader::end__reflectivity()
919 	{
920 		mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE;
921 		return true;
922 	}
923 
924 	//------------------------------
begin__transparent(const transparent__AttributeData & attributeData)925 	bool LibraryEffectsLoader::begin__transparent ( const transparent__AttributeData& attributeData )
926 	{
927 		ENUM__fx_opaque opaque = attributeData.opaque;
928 		switch ( opaque )
929 		{
930         case ENUM__fx_opaque__A_ZERO:
931             mOpaqueMode = A_ZERO;
932             break;
933 		case ENUM__fx_opaque__A_ONE:
934 			mOpaqueMode = A_ONE;
935 			break;
936 		case ENUM__fx_opaque__RGB_ZERO:
937 			mOpaqueMode = RGB_ZERO;
938 			break;
939         case ENUM__fx_opaque__RGB_ONE:
940             mOpaqueMode = RGB_ONE;
941             break;
942 		default:
943 			mOpaqueMode = UNSPECIFIED_OPAQUE;
944 			break;
945 		}
946 		mCurrentShaderParameterType = SHADER_PARAMETER_TRANSPARENT;
947 		return true;
948 	}
949 
950 
951 	//------------------------------
end__transparent()952 	bool LibraryEffectsLoader::end__transparent()
953 	{
954 		mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE;
955 		return true;
956 	}
957 
958 	//------------------------------
begin__transparency()959 	bool LibraryEffectsLoader::begin__transparency()
960 	{
961 		mCurrentShaderParameterType = SHADER_PARAMETER_TRANSPARENCY;
962 		return true;
963 	}
964 
965 	//------------------------------
end__transparency()966 	bool LibraryEffectsLoader::end__transparency()
967 	{
968 		mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE;
969 		return true;
970 	}
971 
972 	//------------------------------
begin__index_of_refraction()973 	bool LibraryEffectsLoader::begin__index_of_refraction()
974 	{
975 		mCurrentShaderParameterType = SHADER_PARAMETER_INDEX_OF_REFRACTION;
976 		return true;
977 	}
978 
979 	//------------------------------
end__index_of_refraction()980 	bool LibraryEffectsLoader::end__index_of_refraction()
981 	{
982 		mCurrentShaderParameterType = UNKNOWN_SHADER_TYPE;
983 		return true;
984 	}
985 
986     //------------------------------
fillSamplerArray()987     bool LibraryEffectsLoader::fillSamplerArray ()
988     {
989         COLLADAFW::EffectCommon& commonEffect =  *mCurrentEffect->getCommonEffects().back();
990         COLLADAFW::SamplerPointerArray& samplerArray = commonEffect.getSamplerPointerArray();
991 
992         // Iterate over the list of used samplers in the current effect profile
993         // and push them in the sampler array.
994 		size_t samplerCount = mEffectProfileSamplersMap.size();
995 		samplerArray.reallocMemory(samplerCount);
996 		samplerArray.setCount(samplerCount);
997         StringIndexMap::const_iterator it = mEffectProfileSamplersMap.begin ();
998         while ( it != mEffectProfileSamplersMap.end () )
999         {
1000             String samplerSid = it->first;
1001 			size_t samplerIndex = it->second;
1002 
1003             bool validSampler =  false;
1004             SidSamplerInfoMap::iterator samplerIt = mEffectProfileSidSamplerInfoMap.find ( samplerSid );
1005 
1006             if ( samplerIt == mEffectProfileSidSamplerInfoMap.end () )
1007             {
1008                 samplerIt = mEffectSidSamplerInfoMap.find ( samplerSid );
1009                 if ( samplerIt != mEffectSidSamplerInfoMap.end () ) validSampler = true;
1010             }
1011             else validSampler = true;
1012 
1013             if ( validSampler )
1014             {
1015                 SamplerInfo& samplerInfo = samplerIt->second;
1016                 samplerInfo.id = samplerArray.getCount();
1017                 COLLADAFW::Sampler* sampler = samplerInfo.sampler;
1018                 sampler->setSid(samplerSid);
1019                 if ( !sampler->getSourceImage().isValid() )
1020                 {
1021                     bool validSurface = false;
1022                     SidSurfaceMap::const_iterator surfaceIt = mEffectProfileSidSurfaceMap.find( samplerInfo.surfaceSid );
1023                     if ( surfaceIt == mEffectProfileSidSurfaceMap.end() )
1024                     {
1025                         surfaceIt = mEffectSidSurfaceMap.find( samplerInfo.surfaceSid );
1026                         if ( surfaceIt != mEffectSidSurfaceMap.end() ) validSurface = true;
1027                     }
1028                     else validSurface = true;
1029                     if ( validSurface )
1030                     {
1031                         const Surface& surface = surfaceIt->second;
1032                         sampler->setSource(surface.imageUniqueId);
1033 
1034                         // copy sampler into common effect
1035                         samplerArray[samplerIndex] = sampler->clone();
1036                     }
1037                 }
1038                 else
1039                 {
1040 					samplerArray[samplerIndex] = sampler->clone();
1041                 }
1042             }
1043             else
1044 			{
1045 				// we a null sampler here, to ensure the index of all of the following sampler remain correct
1046 				samplerArray[samplerIndex] = 0;
1047 
1048 				if ( !handleFWLError ( SaxFWLError::ERROR_UNRESOLVED_REFERENCE, "No sampler for texture \"" + samplerSid + "\" defined!" ))
1049 					return false;
1050 			}
1051             ++it;
1052         }
1053 
1054 		return true;
1055     }
1056 
data__minfilter(const ENUM__fx_sampler_filter_common value)1057     bool LibraryEffectsLoader::data__minfilter( const ENUM__fx_sampler_filter_common value )
1058     {
1059         COLLADAFW::Sampler::SamplerFilter filter = COLLADAFW::Sampler::SAMPLER_FILTER_UNSPECIFIED;
1060         if ( mCurrentSampler ) {
1061             switch (value) {
1062                 case ENUM__fx_sampler_filter_common__NOT_PRESENT:
1063                 case ENUM__fx_sampler_filter_common__COUNT:
1064                 case ENUM__fx_sampler_filter_common__NONE:
1065                     filter = COLLADAFW::Sampler::SAMPLER_FILTER_NONE;
1066                     break;
1067                 case ENUM__fx_sampler_filter_common__NEAREST:
1068                     filter = COLLADAFW::Sampler::SAMPLER_FILTER_NEAREST;
1069                     break;
1070                 case ENUM__fx_sampler_filter_common__LINEAR:
1071                     filter = COLLADAFW::Sampler::SAMPLER_FILTER_LINEAR;
1072                     break;
1073                 case ENUM__fx_sampler_filter_common__NEAREST_MIPMAP_NEAREST:
1074                     filter = COLLADAFW::Sampler::SAMPLER_FILTER_NEAREST_MIPMAP_NEAREST;
1075                     break;
1076                 case ENUM__fx_sampler_filter_common__LINEAR_MIPMAP_NEAREST:
1077                     filter = COLLADAFW::Sampler::SAMPLER_FILTER_LINEAR_MIPMAP_NEAREST;
1078                     break;
1079                 case ENUM__fx_sampler_filter_common__NEAREST_MIPMAP_LINEAR:
1080                     filter = COLLADAFW::Sampler::SAMPLER_FILTER_NEAREST_MIPMAP_LINEAR;
1081                     break;
1082                 case ENUM__fx_sampler_filter_common__LINEAR_MIPMAP_LINEAR:
1083                     filter = COLLADAFW::Sampler::SAMPLER_FILTER_LINEAR_MIPMAP_LINEAR;
1084                     break;
1085             }
1086             mCurrentSampler->setMinFilter(filter);
1087         }
1088 
1089         return true;
1090     }
1091 
1092 
1093     //------------------------------
getUniqueId()1094     const COLLADAFW::UniqueId& LibraryEffectsLoader::getUniqueId ()
1095     {
1096         if ( mCurrentSampler )
1097             return mCurrentSampler->getUniqueId ();
1098         else if ( mCurrentEffect )
1099             return mCurrentEffect->getUniqueId ();
1100         return COLLADAFW::UniqueId::INVALID;
1101     }
1102 
1103 	//------------------------------
getObject()1104 	COLLADAFW::Object* LibraryEffectsLoader::getObject()
1105 	{
1106 		if ( mCurrentSampler )
1107 			return mCurrentSampler;
1108 		else if ( mCurrentEffect )
1109 			return mCurrentEffect;
1110 		return 0;
1111 	}
1112 
1113 } // namespace COLLADASaxFWL
1114