Fix to light animation in model3d-view control
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / model3d-view / model3d-view-impl.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include "model3d-view-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/object/type-registry.h>
23 #include <dali/public-api/animation/constraint.h>
24 #include <dali/public-api/animation/constraint-source.h>
25 #include <dali/public-api/animation/constraints.h>
26 #include <dali/devel-api/object/type-registry-helper.h>
27 #include <dali-toolkit/public-api/controls/model3d-view/model3d-view.h>
28 #include <dali/public-api/images/resource-image.h>
29 #include <dali/devel-api/adaptor-framework/file-loader.h>
30
31 // INTERNAL INCLUDES
32 #include <dali-toolkit/internal/controls/model3d-view/obj-loader.h>
33
34 namespace Dali
35 {
36
37 namespace Toolkit
38 {
39
40 namespace Internal
41 {
42
43 namespace
44 {
45
46 // Type registration
47 BaseHandle Create()
48 {
49   return Toolkit::Model3dView::New();
50 }
51
52 // Setup properties, signals and actions using the type-registry.
53 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::Model3dView, Toolkit::Control, Create );
54
55 DALI_PROPERTY_REGISTRATION( Toolkit, Model3dView, "geometry-url", STRING, GEOMETRY_URL)
56 DALI_PROPERTY_REGISTRATION( Toolkit, Model3dView, "material-url", STRING, MATERIAL_URL)
57 DALI_PROPERTY_REGISTRATION( Toolkit, Model3dView, "images-url", STRING, IMAGES_URL)
58 DALI_PROPERTY_REGISTRATION( Toolkit, Model3dView, "illumination-type", INTEGER, ILLUMINATION_TYPE)
59 DALI_PROPERTY_REGISTRATION( Toolkit, Model3dView, "texture0-url", STRING, TEXTURE0_URL)
60 DALI_PROPERTY_REGISTRATION( Toolkit, Model3dView, "texture1-url", STRING, TEXTURE1_URL)
61 DALI_PROPERTY_REGISTRATION( Toolkit, Model3dView, "texture2-url", STRING, TEXTURE2_URL)
62
63 DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, Model3dView, "light-position", VECTOR3, LIGHT_POSITION)
64
65 DALI_TYPE_REGISTRATION_END()
66
67
68 #define MAKE_SHADER(A)#A
69
70 //  Diffuse illumination shader
71
72 const char* SIMPLE_VERTEX_SHADER = MAKE_SHADER(
73   attribute highp vec3 aPosition;\n
74   attribute highp vec2 aTexCoord;\n
75   attribute highp vec3 aNormal;\n
76   varying mediump vec3 vIllumination;\n
77   uniform mediump vec3 uSize;\n
78   uniform mediump mat4 uMvpMatrix;\n
79   uniform mediump mat4 uModelView;\n
80   uniform mediump mat3 uNormalMatrix;
81   uniform mediump mat4 uObjectMatrix;\n
82   uniform mediump vec3 uLightPosition;\n
83   \n
84   void main()\n
85   {\n
86     vec4 vertexPosition = vec4(aPosition*min(uSize.x, uSize.y), 1.0);\n
87     vertexPosition = uObjectMatrix * vertexPosition;\n
88     vertexPosition = uMvpMatrix * vertexPosition;\n
89     \n
90     //Illumination in Model-View space - Transform attributes and uniforms\n
91     vec4 vertPos4 = uModelView * vec4(aPosition.xyz, 1.0);\n
92     vec3 vertPos = vec3(vertPos4) / vertPos4.w;\n
93     \n
94     vec3 normalInterp = uNormalMatrix * aNormal;\n
95     \n
96     vec4 lightPos4 = uModelView * vec4(uLightPosition, 1.0);\n
97     vec3 lightPos = vec3(lightPos4) / lightPos4.w;\n
98     \n
99     vec3 vecToLight = normalize( lightPos.xyz - vertPos.xyz );\n
100     \n
101     float lightDiffuse = dot( vecToLight, normalInterp );\n
102     lightDiffuse = max(0.0,lightDiffuse);\n
103     vIllumination = vec3(lightDiffuse * 0.5 + 0.5);\n
104     \n
105     gl_Position = vertexPosition;\n
106   }\n
107 );
108
109 const char* SIMPLE_FRAGMENT_SHADER = MAKE_SHADER(
110   precision mediump float;\n
111   varying mediump vec3 vIllumination;\n
112   uniform lowp vec4 uColor;\n
113   \n
114   void main()\n
115   {\n
116     gl_FragColor.rgb = vIllumination.rgb * uColor.rgb;\n
117     gl_FragColor.a = uColor.a;\n
118   }\n
119 );
120
121 //  Diffuse and specular illumination shader with albedo texture
122
123 const char* VERTEX_SHADER = MAKE_SHADER(
124   attribute highp vec3 aPosition;\n
125   attribute highp vec2 aTexCoord;\n
126   attribute highp vec3 aNormal;\n
127   varying mediump vec2 vTexCoord;\n
128   varying mediump vec3 vIllumination;\n
129   varying mediump float vSpecular;\n
130   uniform mediump vec3 uSize;\n
131   uniform mediump mat4 uMvpMatrix;\n
132   uniform mediump mat4 uModelView;
133   uniform mediump mat3 uNormalMatrix;
134   uniform mediump mat4 uObjectMatrix;\n
135   uniform mediump vec3 uLightPosition;\n
136   \n
137   void main()
138   {\n
139     vec4 vertexPosition = vec4(aPosition*min(uSize.x, uSize.y), 1.0);\n
140     vertexPosition = uObjectMatrix * vertexPosition;\n
141     vertexPosition = uMvpMatrix * vertexPosition;\n
142     \n
143     //Illumination in Model-View space - Transform attributes and uniforms\n
144     vec4 vertPos4 = uModelView * vec4(aPosition.xyz, 1.0);\n
145     vec3 vertPos = vec3(vertPos4) / vertPos4.w;\n
146     \n
147     vec4 lightPos4 = uModelView * vec4(uLightPosition, 1.0);\n
148     vec3 lightPos = vec3(lightPos4) / lightPos4.w;\n
149     \n
150     vec3 normalInterp = normalize(uNormalMatrix * aNormal);\n
151     \n
152     vec3 vecToLight = normalize( lightPos.xyz - vertPos.xyz );\n
153     vec3 viewDir = normalize(-vertPos);
154     \n
155     vec3 halfVector = normalize(viewDir + vecToLight);
156     \n
157     float lightDiffuse = dot( vecToLight, normalInterp );\n
158     lightDiffuse = max(0.0,lightDiffuse);\n
159     vIllumination = vec3(lightDiffuse * 0.5 + 0.5);\n
160     \n
161     // this is blinn phong
162     //float specAngle = max(dot(halfVector, normalInterp), 0.0);\n
163     //vSpecular = pow(specAngle, 16.0);\n
164     \n
165     // this is phong (for comparison)
166     vec3 reflectDir = reflect(-vecToLight, normalInterp);
167     float specAngle = max(dot(reflectDir, viewDir), 0.0);
168     // note that the exponent is different here
169     vSpecular = pow(specAngle, 16.0/4.0);
170     \n
171     vTexCoord = aTexCoord;\n
172     gl_Position = vertexPosition;\n
173   }\n
174 );
175
176 const char* FRAGMENT_SHADER = MAKE_SHADER(
177   precision mediump float;\n
178   varying mediump vec2 vTexCoord;\n
179   varying mediump vec3 vIllumination;\n
180   varying mediump float vSpecular;\n
181   uniform sampler2D sDiffuse;\n
182   uniform lowp vec4 uColor;\n
183   \n
184   void main()\n
185   {\n
186     vec4 texture = texture2D( sDiffuse, vTexCoord );\n
187     gl_FragColor.rgb = vIllumination.rgb * texture.rgb * uColor.rgb + vSpecular * 0.3;\n
188     gl_FragColor.a = texture.a * uColor.a;\n
189   }\n
190 );
191
192 //  Diffuse and specular illumination shader with albedo texture, normal map and gloss map shader
193
194 const char* NRMMAP_VERTEX_SHADER = MAKE_SHADER(
195   attribute highp vec3 aPosition;\n
196   attribute highp vec2 aTexCoord;\n
197   attribute highp vec3 aNormal;\n
198   attribute highp vec3 aTangent;\n
199   attribute highp vec3 aBiNormal;\n
200   varying mediump vec2 vTexCoord;\n
201   varying mediump vec3 vLightDirection;\n
202   varying mediump vec3 vHalfVector;\n
203   uniform mediump vec3 uSize;\n
204   uniform mediump mat4 uMvpMatrix;\n
205   uniform mediump mat4 uModelView;
206   uniform mediump mat3 uNormalMatrix;
207   uniform mediump mat4 uObjectMatrix;\n
208   uniform mediump vec3 uLightPosition;\n
209   \n
210   void main()
211   {\n
212     vec4 vertexPosition = vec4(aPosition*min(uSize.x, uSize.y), 1.0);\n
213     vertexPosition = uObjectMatrix * vertexPosition;\n
214     vertexPosition = uMvpMatrix * vertexPosition;\n
215     \n
216     vTexCoord = aTexCoord;\n
217     \n
218     vec3 vNormal = normalize(uNormalMatrix * aNormal);\n
219     vec3 vTangent = normalize(uNormalMatrix * aTangent);\n
220     vec3 vBiNormal = normalize(uNormalMatrix * aBiNormal);\n
221     \n
222     vec4 vertPos4 = uModelView * vec4(aPosition.xyz, 1.0);\n
223     vec3 vertPos = vec3(vertPos4) / vertPos4.w;\n
224     \n
225     vec4 lightPos4 = uModelView * vec4(uLightPosition, 1.0);\n
226     vec3 lightPos = vec3(lightPos4) / lightPos4.w;\n
227     \n
228     vec3 vecToLight = lightPos - vertPos;
229     vLightDirection.x = dot(vecToLight, vTangent);
230     vLightDirection.y = dot(vecToLight, vBiNormal);
231     vLightDirection.z = dot(vecToLight, vNormal);
232     vLightDirection = normalize(vLightDirection);
233     \n
234     vec3 viewDir = normalize(vertPos);
235     \n
236     vec3 halfVector = normalize(viewDir + vecToLight);
237     vHalfVector.x = dot (halfVector, vTangent);
238     vHalfVector.y = dot (halfVector, vBiNormal);
239     vHalfVector.z = dot (halfVector, vNormal);
240     \n
241     gl_Position = vertexPosition;\n
242
243     //vHalfVector = aTangent;
244   }\n
245 );
246
247 const char* NRMMAP_FRAGMENT_SHADER = MAKE_SHADER(
248   precision mediump float;\n
249   varying mediump vec2 vTexCoord;\n
250   varying mediump vec3 vLightDirection;\n
251   varying mediump vec3 vHalfVector;\n
252   uniform sampler2D sDiffuse;\n
253   uniform sampler2D sNormal;\n
254   uniform sampler2D sGloss;\n
255   uniform lowp vec4 uColor;\n
256   \n
257   void main()\n
258   {\n
259     vec4 texture = texture2D( sDiffuse, vTexCoord );\n
260     vec4 nrmMap = texture2D( sNormal, vTexCoord ) * 2.0 - 1.0;\n
261     vec4 glossMap = texture2D( sGloss, vTexCoord );\n
262     \n
263     vec3 normalizedLightDirection = normalize(vLightDirection);\n
264     float lightDiffuse = max( 0.0, dot( nrmMap.xyz, normalizedLightDirection ) );\n
265     lightDiffuse = lightDiffuse * 0.5 + 0.5;\n
266     \n
267     float shininess = pow (max (dot (vHalfVector, nrmMap.xyz), 0.0), 16.0)  ;
268     \n
269     gl_FragColor.rgb = texture.rgb * uColor.rgb * lightDiffuse + shininess * glossMap.rgb;\n
270     gl_FragColor.a = texture.a * uColor.a;\n
271
272     //gl_FragColor.rgb = vHalfVector.rgb;
273   }\n
274 );
275
276
277 } // anonymous namespace
278
279 using namespace Dali;
280
281 void LookAt(Matrix& result, const Vector3& eye, const Vector3& target, const Vector3& up)
282 {
283   Vector3 vZ = target - eye;
284   vZ.Normalize();
285
286   Vector3 vX = up.Cross(vZ);
287   vX.Normalize();
288
289   Vector3 vY = vZ.Cross(vX);
290   vY.Normalize();
291
292   result.SetInverseTransformComponents(vX, vY, vZ, eye);
293 }
294
295
296 Model3dView::Model3dView()
297   : Control( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) )
298 {
299   mTexture0Url = "";
300   mTexture1Url = "";
301   mTexture2Url = "";
302
303   mIlluminationType = Toolkit::Model3dView::DIFFUSE_WITH_NORMAL_MAP;
304
305   mCameraFOV = Math::PI_OVER_180 * 45.f;
306
307   mControlSize = Vector2(100.,100.);
308 }
309
310 Model3dView::~Model3dView()
311 {
312 }
313
314 Toolkit::Model3dView Model3dView::New()
315 {
316   Model3dView* impl = new Model3dView();
317
318   Dali::Toolkit::Model3dView handle = Dali::Toolkit::Model3dView( *impl );
319
320   // Second-phase init of the implementation
321   // This can only be done after the CustomActor connection has been made...
322   impl->Initialize();
323
324   return handle;
325 }
326
327 void Model3dView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
328 {
329   Toolkit::Model3dView model3dView = Toolkit::Model3dView::DownCast( Dali::BaseHandle( object ) );
330
331   if( model3dView )
332   {
333     Model3dView& impl( GetImpl( model3dView ) );
334     switch( index )
335     {
336       case Toolkit::Model3dView::Property::GEOMETRY_URL:
337       {
338         if( value.Get(impl.mObjUrl) )
339         {
340           impl.LoadGeometry();
341           impl.CreateGeometry();
342         }
343         break;
344       }
345       case Toolkit::Model3dView::Property::MATERIAL_URL:
346       {
347         if( value.Get(impl.mMaterialUrl) )
348         {
349           impl.LoadMaterial();
350           impl.CreateMaterial();
351         }
352         break;
353       }
354       case Toolkit::Model3dView::Property::IMAGES_URL:
355       {
356         if( value.Get(impl.mImagesUrl) )
357         {
358           impl.LoadTextures();
359         }
360         break;
361       }
362       case Toolkit::Model3dView::Property::ILLUMINATION_TYPE:
363       {
364         int illuminationType;
365         if( value.Get(illuminationType) )
366         {
367           impl.mIlluminationType = Toolkit::Model3dView::IlluminationType(illuminationType);
368           impl.CreateGeometry();
369           impl.CreateMaterial();
370           impl.LoadTextures();
371         }
372         break;
373       }
374       case Toolkit::Model3dView::Property::TEXTURE0_URL:
375       {
376         value.Get(impl.mTexture0Url);
377         break;
378       }
379       case Toolkit::Model3dView::Property::TEXTURE1_URL:
380       {
381         value.Get(impl.mTexture1Url);
382         break;
383       }
384       case Toolkit::Model3dView::Property::TEXTURE2_URL:
385       {
386         value.Get(impl.mTexture2Url);
387         break;
388       }
389     }
390   }
391 }
392
393 Property::Value Model3dView::GetProperty( BaseObject* object, Property::Index index )
394 {
395   Property::Value value;
396
397   Toolkit::Model3dView model3dView = Toolkit::Model3dView::DownCast( Dali::BaseHandle( object ) );
398
399   if( model3dView )
400   {
401     Model3dView& impl( GetImpl( model3dView ) );
402     switch( index )
403     {
404       case Toolkit::Model3dView::Property::GEOMETRY_URL:
405       {
406         value = impl.mObjUrl;
407         break;
408       }
409       case Toolkit::Model3dView::Property::MATERIAL_URL:
410       {
411         value = impl.mMaterialUrl;
412         break;
413       }
414       case Toolkit::Model3dView::Property::IMAGES_URL:
415       {
416         value = impl.mImagesUrl;
417         break;
418       }
419       case Toolkit::Model3dView::Property::ILLUMINATION_TYPE:
420       {
421         value = int(impl.mIlluminationType);
422         break;
423       }
424       case Toolkit::Model3dView::Property::TEXTURE0_URL:
425       {
426         value = impl.mTexture0Url;
427         break;
428       }
429       case Toolkit::Model3dView::Property::TEXTURE1_URL:
430       {
431         value = impl.mTexture1Url;
432         break;
433       }
434       case Toolkit::Model3dView::Property::TEXTURE2_URL:
435       {
436         value = impl.mTexture2Url;
437         break;
438       }
439     }
440   }
441
442   return value;
443 }
444
445 /////////////////////////////////////////////////////////////
446
447
448 void Model3dView::OnStageConnection( int depth )
449 {
450   CustomActor self = Self();
451   self.AddRenderer( mRenderer );
452
453   if( mObjLoader.IsSceneLoaded() )
454   {
455     mMesh = mObjLoader.CreateGeometry(mIlluminationType);
456
457     CreateMaterial();
458     LoadTextures();
459
460     mRenderer.SetGeometry( mMesh );
461
462     //create constraint for lightPosition Property with uLightPosition in the shader
463     Vector3 lightPosition( 0, 0, 0 );
464     Dali::Property::Index lightProperty = mShader.RegisterProperty( "uLightPosition", lightPosition );
465     Constraint constraint = Constraint::New<Vector3>( mShader, lightProperty, EqualToConstraint() );
466     constraint.AddSource( Source( self, Toolkit::Model3dView::Property::LIGHT_POSITION ) );
467     constraint.Apply();
468   }
469 }
470
471 ///////////////////////////////////////////////////////////
472 //
473 // Private methods
474 //
475
476 void Model3dView::OnInitialize()
477 {
478   //Create empty versions of the geometry and material so we always have a Renderer
479   Geometry mesh = Geometry::New();
480   Shader shader = Shader::New( SIMPLE_VERTEX_SHADER, SIMPLE_FRAGMENT_SHADER, (Shader::ShaderHints)(Shader::HINT_REQUIRES_SELF_DEPTH_TEST | Shader::HINT_MODIFIES_GEOMETRY) );
481   Material material = Material::New( shader );
482   mRenderer = Renderer::New( mesh, material );
483 }
484
485 void Model3dView::LoadGeometry()
486 {
487   //Load file in adaptor
488   std::streampos fileSize;
489   Dali::Vector<char> fileContent;
490
491   if (FileLoader::ReadFile(mObjUrl,fileSize,fileContent,FileLoader::TEXT))
492   {
493     mObjLoader.ClearArrays();
494
495     std::string materialUrl;
496     mObjLoader.Load(fileContent.Begin(), fileSize, materialUrl);
497
498     //Get size information from the obj loaded
499     mSceneCenter = mObjLoader.GetCenter();
500     mSceneSize = mObjLoader.GetSize();
501   }
502   else
503   {
504     //Error
505   }
506 }
507
508 void Model3dView::LoadMaterial()
509 {
510   //Load file in adaptor
511   std::streampos fileSize;
512   Dali::Vector<char> fileContent;
513
514   if( FileLoader::ReadFile(mMaterialUrl, fileSize, fileContent, FileLoader::TEXT) )
515   {
516     mObjLoader.LoadMaterial(fileContent.Begin(), fileSize, mTexture0Url, mTexture1Url, mTexture2Url);
517   }
518   else
519   {
520     //Error
521   }
522 }
523
524 void Model3dView::Load()
525 {
526   LoadGeometry();
527   LoadMaterial();
528 }
529
530 void Model3dView::OnRelayout( const Vector2& size, RelayoutContainer& container )
531 {
532   UpdateView();
533 }
534
535 void Model3dView::UpdateView()
536 {
537   if( mObjLoader.IsSceneLoaded() )
538   {
539     //The object will always be centred
540
541     Matrix scaleMatrix;
542     scaleMatrix.SetIdentityAndScale(Vector3(1.0, -1.0, 1.0));
543
544     mShader.RegisterProperty( "uObjectMatrix", scaleMatrix );
545   }
546 }
547
548 void Model3dView::CreateGeometry()
549 {
550   if( mObjLoader.IsSceneLoaded() )
551   {
552     mMesh = mObjLoader.CreateGeometry(mIlluminationType);
553
554     if( mRenderer )
555     {
556       mRenderer.SetGeometry( mMesh );
557     }
558   }
559 }
560
561 void Model3dView::UpdateShaderUniforms()
562 {
563   if( mShader )
564   {
565     //Update shader related info, uniforms, etc. for the new shader
566     UpdateView();
567
568     Vector3 lightPosition( 0, 0, 0 );
569     Dali::Property::Index lightProperty = mShader.RegisterProperty( "uLightPosition", lightPosition );
570
571     CustomActor self = Self();
572
573     //create constraint for lightPosition Property with uLightPosition in the shader
574     if( lightProperty )
575     {
576       Constraint constraint = Constraint::New<Vector3>( mShader, lightProperty, EqualToConstraint() );
577       constraint.AddSource( Source( self, Toolkit::Model3dView::Property::LIGHT_POSITION ) );
578       constraint.Apply();
579     }
580   }
581 }
582
583 void Model3dView::CreateMaterial()
584 {
585   if( mObjLoader.IsMaterialLoaded() && (mTexture0Url != ""))
586   {
587     if( (mTexture2Url != "") && (mTexture1Url != "") && (mIlluminationType == Toolkit::Model3dView::DIFFUSE_WITH_NORMAL_MAP))
588     {
589       mShader = Shader::New( NRMMAP_VERTEX_SHADER, NRMMAP_FRAGMENT_SHADER, (Shader::ShaderHints)(Shader::HINT_REQUIRES_SELF_DEPTH_TEST | Shader::HINT_MODIFIES_GEOMETRY) );
590     }
591     else if(mIlluminationType == Toolkit::Model3dView::DIFFUSE_WITH_TEXTURE)
592     {
593       mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER, (Shader::ShaderHints)(Shader::HINT_REQUIRES_SELF_DEPTH_TEST | Shader::HINT_MODIFIES_GEOMETRY) );
594     }
595     else
596     {
597       mShader = Shader::New( SIMPLE_VERTEX_SHADER, SIMPLE_FRAGMENT_SHADER, (Shader::ShaderHints)(Shader::HINT_REQUIRES_SELF_DEPTH_TEST | Shader::HINT_MODIFIES_GEOMETRY) );
598     }
599   }
600   else
601   {
602     mShader = Shader::New( SIMPLE_VERTEX_SHADER, SIMPLE_FRAGMENT_SHADER, (Shader::ShaderHints)(Shader::HINT_REQUIRES_SELF_DEPTH_TEST | Shader::HINT_MODIFIES_GEOMETRY) );
603   }
604
605   mMaterial = Material::New( mShader );
606
607   mMaterial.SetFaceCullingMode(Material::NONE);
608
609   if( mRenderer )
610   {
611     mRenderer.SetMaterial( mMaterial );
612   }
613
614   UpdateShaderUniforms();
615 }
616
617 void Model3dView::LoadTextures()
618 {
619   if( !mMaterial )
620     return ;
621
622   if( mTexture0Url != "" )
623   {
624     std::string imgUrl = mImagesUrl + mTexture0Url;
625
626     //Load textures
627     Image tex0 = ResourceImage::New( imgUrl );
628     if( tex0 )
629     {
630       Sampler sampler = Sampler::New( tex0, "sDiffuse" );
631       sampler.SetWrapMode(Sampler::REPEAT,Sampler::REPEAT);
632       sampler.SetAffectsTransparency(false);
633
634       mMaterial.AddSampler( sampler );
635     }
636   }
637
638   if( (mTexture1Url != "") && (mIlluminationType == Toolkit::Model3dView::DIFFUSE_WITH_NORMAL_MAP) )
639   {
640     std::string imgUrl = mImagesUrl + mTexture1Url;
641
642     //Load textures
643     Image tex1 = ResourceImage::New( imgUrl );
644     if (tex1)
645     {
646       Sampler sampler = Sampler::New( tex1, "sNormal" );
647       sampler.SetWrapMode(Sampler::REPEAT,Sampler::REPEAT);
648       sampler.SetAffectsTransparency(false);
649       sampler.SetFilterMode(Sampler::LINEAR,Sampler::LINEAR);
650
651       mMaterial.AddSampler( sampler );
652     }
653   }
654
655   if( (mTexture2Url != "") && (mIlluminationType == Toolkit::Model3dView::DIFFUSE_WITH_NORMAL_MAP) )
656   {
657     std::string imgUrl = mImagesUrl + mTexture2Url;
658
659     //Load textures
660     Image tex2 = ResourceImage::New( imgUrl );
661     if( tex2 )
662     {
663       Sampler sampler = Sampler::New( tex2, "sGloss" );
664       sampler.SetWrapMode(Sampler::REPEAT,Sampler::REPEAT);
665       sampler.SetAffectsTransparency(false);
666       sampler.SetFilterMode(Sampler::LINEAR,Sampler::LINEAR);
667
668       mMaterial.AddSampler( sampler );
669     }
670   }
671 }
672
673 } // namespace Internal
674 } // namespace Toolkit
675 } // namespace Dali