Further Setter/Getter public API removal from Dali::Actor
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / scene3d-view / scene3d-view-impl.cpp
1 /*
2  * Copyright (c) 2018 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 <dali-toolkit/internal/controls/scene3d-view/scene3d-view-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23
24 // INTERNAL INCLUDES
25 #include <dali-toolkit/devel-api/asset-manager/asset-manager.h>
26
27 namespace Dali
28 {
29
30 namespace Toolkit
31 {
32
33 namespace Internal
34 {
35
36 namespace
37 {
38
39 const char* const IMAGE_BRDF_FILE_NAME = "brdfLUT.png";
40
41 // glTF file extension
42 const std::string GLTF_EXT( ".gltf" );
43
44 /**
45  * cube map face index
46  */
47 const uint32_t CUBEMAP_INDEX_X[2][6] = { { 2, 0, 1, 1, 1, 3 }, { 0, 1, 2, 3, 4, 5 } };
48 const uint32_t CUBEMAP_INDEX_Y[2][6] = { { 1, 1, 0, 2, 1, 1 }, { 0, 0, 0, 0, 0, 0 } };
49
50 }//namespace
51
52 Scene3dView::Scene3dView()
53   : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
54   mRoot( Actor::New() ),
55   mShaderArray(),
56   mCameraActorArray(),
57   mDefaultCamera( CameraActor::New() ),
58   mAnimationArray(),
59   mLightType( Toolkit::Scene3dView::LightType::NONE ),
60   mLightVector( Vector3::ONE ),
61   mLightColor( Vector3::ONE )
62 {
63 }
64
65 Scene3dView::~Scene3dView()
66 {
67 }
68
69 Toolkit::Scene3dView Scene3dView::New( const std::string& filePath )
70 {
71   Scene3dView* impl = new Scene3dView();
72
73   Dali::Toolkit::Scene3dView handle = Dali::Toolkit::Scene3dView( *impl );
74
75   // Second-phase init of the implementation
76   // This can only be done after the CustomActor connection has been made...
77   impl->mFilePath = filePath;
78   impl->Initialize();
79
80   return handle;
81 }
82
83 Toolkit::Scene3dView Scene3dView::New( const std::string& filePath, const std::string& diffuseTexturePath, const std::string& specularTexturePath, Vector4 scaleFactor )
84 {
85   Scene3dView* impl = new Scene3dView();
86
87   Dali::Toolkit::Scene3dView handle = Dali::Toolkit::Scene3dView( *impl );
88
89   // Second-phase init of the implementation
90   // This can only be done after the CustomActor connection has been made...
91   impl->mFilePath = filePath;
92   impl->SetCubeMap( diffuseTexturePath, specularTexturePath, scaleFactor );
93   impl->Initialize();
94
95   return handle;
96 }
97
98 bool Scene3dView::CreateScene()
99 {
100   if( std::string::npos != mFilePath.rfind( GLTF_EXT ) )
101   {
102     Internal::Gltf::Loader gltfloader;
103     return( gltfloader.LoadScene( mFilePath, *this ) );
104   }
105
106   return false;
107 }
108
109 uint32_t Scene3dView::GetAnimationCount()
110 {
111   return mAnimationArray.size();
112 }
113
114 bool Scene3dView::PlayAnimation( uint32_t index )
115 {
116   if( GetAnimationCount() <= index )
117   {
118     return false;
119   }
120
121   mAnimationArray[index].Play();
122   return true;
123 }
124
125 bool Scene3dView::PlayAnimations()
126 {
127   for( auto&& animation : mAnimationArray )
128   {
129     animation.Play();
130   }
131
132   return true;
133 }
134
135 bool Scene3dView::SetLight( Toolkit::Scene3dView::LightType type, Vector3 lightVector, Vector3 lightColor )
136 {
137   if( type > Toolkit::Scene3dView::LightType::DIRECTIONAL_LIGHT )
138   {
139     return false;
140   }
141
142   mLightType = static_cast<Toolkit::Scene3dView::LightType>(
143                ( mLightType >= Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT ) ?
144                Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT + type :
145                type );
146
147   mLightVector = lightVector;
148   mLightColor = lightColor;
149
150   for( auto&& shader : mShaderArray )
151   {
152     shader.RegisterProperty( "uLightType", ( GetLightType() & ~Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT ) );
153     shader.RegisterProperty( "uLightVector", lightVector );
154     shader.RegisterProperty( "uLightColor", lightColor );
155   }
156
157   return true;
158 }
159
160 uint8_t* Scene3dView::GetCroppedBuffer( uint8_t* sourceBuffer, uint32_t bytesPerPixel, uint32_t width, uint32_t height, uint32_t xOffset, uint32_t yOffset, uint32_t xFaceSize, uint32_t yFaceSize )
161 {
162   uint32_t byteSize = bytesPerPixel * xFaceSize * yFaceSize;
163   uint8_t* destBuffer = reinterpret_cast<uint8_t*>( malloc( byteSize + 4u ) );
164
165   int32_t srcStride = width * bytesPerPixel;
166   int32_t destStride = xFaceSize * bytesPerPixel;
167   int32_t srcOffset = xOffset * bytesPerPixel + yOffset * srcStride;
168   int32_t destOffset = 0;
169   for( uint16_t row = yOffset; row < yOffset + yFaceSize; ++row )
170   {
171     memcpy( destBuffer + destOffset, sourceBuffer + srcOffset, destStride );
172     srcOffset += srcStride;
173     destOffset += destStride;
174   }
175
176   return destBuffer;
177 }
178
179 void Scene3dView::UploadTextureFace( Texture& texture, Devel::PixelBuffer pixelBuffer, uint32_t faceIndex )
180 {
181   uint8_t* imageBuffer = pixelBuffer.GetBuffer();
182   uint32_t bytesPerPixel = Pixel::GetBytesPerPixel( pixelBuffer.GetPixelFormat() );
183   uint32_t imageWidth = pixelBuffer.GetWidth();
184   uint32_t imageHeight = pixelBuffer.GetHeight();
185
186   CubeType cubeType = ( imageWidth / 4 == imageHeight / 3 ) ? CROSS_HORIZONTAL :
187     ( ( imageWidth / 6 == imageHeight ) ? ARRAY_HORIZONTAL : NONE );
188
189   uint32_t faceSize = 0;
190   if( cubeType == CROSS_HORIZONTAL )
191   {
192     faceSize = imageWidth / 4;
193   }
194   else if( cubeType == ARRAY_HORIZONTAL )
195   {
196     faceSize = imageWidth / 6;
197   }
198   else
199   {
200     return;
201   }
202
203   uint32_t xOffset = CUBEMAP_INDEX_X[cubeType][faceIndex] * faceSize;
204   uint32_t yOffset = CUBEMAP_INDEX_Y[cubeType][faceIndex] * faceSize;
205
206   uint8_t* tempImageBuffer = GetCroppedBuffer( imageBuffer, bytesPerPixel, imageWidth, imageHeight, xOffset, yOffset, faceSize, faceSize );
207   PixelData pixelData = PixelData::New( tempImageBuffer, faceSize * faceSize * bytesPerPixel, faceSize, faceSize, pixelBuffer.GetPixelFormat(), PixelData::FREE );
208   texture.Upload( pixelData, CubeMapLayer::POSITIVE_X + faceIndex, 0, 0, 0, faceSize, faceSize );
209 }
210
211 void Scene3dView::SetCubeMap( const std::string& diffuseTexturePath, const std::string& specularTexturePath, Vector4 scaleFactor )
212 {
213   mLightType = Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT;
214
215   // BRDF texture
216   const std::string imageDirPath = AssetManager::GetDaliImagePath();
217   const std::string imageBrdfUrl = imageDirPath + IMAGE_BRDF_FILE_NAME;
218   mBRDFTexture = LoadTexture( imageBrdfUrl.c_str(), true );
219   if( !mBRDFTexture )
220   {
221     return;
222   }
223
224   // Diffuse Cube Map
225   Devel::PixelBuffer diffusePixelBuffer = LoadImageFromFile( diffuseTexturePath );
226   uint32_t diffuseFaceSize = diffusePixelBuffer.GetWidth() / 4;
227   mDiffuseTexture = Texture::New( TextureType::TEXTURE_CUBE, diffusePixelBuffer.GetPixelFormat(), diffuseFaceSize, diffuseFaceSize );
228   for( uint32_t i = 0; i < 6; ++i )
229   {
230     UploadTextureFace( mDiffuseTexture, diffusePixelBuffer, i );
231   }
232   mDiffuseTexture.GenerateMipmaps();
233
234   // Specular Cube Map
235   Devel::PixelBuffer specularPixelBuffer = LoadImageFromFile( specularTexturePath );
236   uint32_t specularFaceSize = specularPixelBuffer.GetWidth() / 4;
237   mSpecularTexture = Texture::New( TextureType::TEXTURE_CUBE, specularPixelBuffer.GetPixelFormat(), specularFaceSize, specularFaceSize );
238   for( uint32_t i = 0; i < 6; ++i )
239   {
240     UploadTextureFace( mSpecularTexture, specularPixelBuffer, i );
241   }
242   mSpecularTexture.GenerateMipmaps();
243
244   mIBLScaleFactor = scaleFactor;
245 }
246
247 bool Scene3dView::SetDefaultCamera( const Dali::Camera::Type type, const float nearPlane, const Vector3 cameraPosition )
248 {
249   mDefaultCamera.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
250   mDefaultCamera.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
251   mDefaultCamera.SetType( type );
252   mDefaultCamera.SetNearClippingPlane( nearPlane );
253   mDefaultCamera.SetProperty( Actor::Property::POSITION, cameraPosition );
254   return true;
255 }
256
257 void Scene3dView::AddCamera( CameraActor cameraActor )
258 {
259   mCameraActorArray.push_back( cameraActor );
260 }
261
262 void Scene3dView::AddAnimation( Animation animation )
263 {
264   mAnimationArray.push_back( animation );
265 }
266
267 void Scene3dView::AddShader( Shader shader )
268 {
269   mShaderArray.push_back( shader );
270 }
271
272 Actor Scene3dView::GetRoot()
273 {
274   return mRoot;
275 }
276
277 CameraActor Scene3dView::GetDefaultCamera()
278 {
279   return mDefaultCamera;
280 }
281
282 uint32_t Scene3dView::GetCameraCount()
283 {
284   return mCameraActorArray.size();
285 }
286
287 CameraActor Scene3dView::GetCamera( uint32_t cameraIndex )
288 {
289   CameraActor cameraActor;
290   if( cameraIndex >= mCameraActorArray.size() )
291   {
292     return cameraActor;
293   }
294   cameraActor = mCameraActorArray[cameraIndex];
295   return cameraActor;
296 }
297
298 Toolkit::Scene3dView::LightType Scene3dView::GetLightType()
299 {
300   return mLightType;
301 }
302
303 Vector3 Scene3dView::GetLightVector()
304 {
305   return mLightVector;
306 }
307
308 Vector3 Scene3dView::GetLightColor()
309 {
310   return mLightColor;
311 }
312
313 Vector4 Scene3dView::GetIBLScaleFactor()
314 {
315   return mIBLScaleFactor;
316 }
317
318 Texture Scene3dView::GetBRDFTexture()
319 {
320   return mBRDFTexture;
321 }
322
323 Texture Scene3dView::GetSpecularTexture()
324 {
325   return mSpecularTexture;
326 }
327
328 Texture Scene3dView::GetDiffuseTexture()
329 {
330   return mDiffuseTexture;
331 }
332
333 Texture Scene3dView::LoadTexture( const char *imageUrl, bool generateMipmaps )
334 {
335   Texture texture;
336
337   Devel::PixelBuffer pixelBuffer = LoadImageFromFile( imageUrl );
338   if( pixelBuffer )
339   {
340     texture = Texture::New( TextureType::TEXTURE_2D, pixelBuffer.GetPixelFormat(), pixelBuffer.GetWidth(), pixelBuffer.GetHeight() );
341     PixelData pixelData = Devel::PixelBuffer::Convert( pixelBuffer );
342     texture.Upload( pixelData );
343
344     if( generateMipmaps )
345     {
346       texture.GenerateMipmaps();
347     }
348   }
349
350   return texture;
351 }
352
353 void Scene3dView::OnInitialize()
354 {
355   mRoot.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
356   mRoot.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
357
358   Layer layer = Layer::New();
359   layer.SetBehavior( Layer::LAYER_3D );
360   layer.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
361   layer.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
362   layer.Add( mRoot );
363
364   Actor self = Self();
365   // Apply some default resizing rules.
366   self.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
367   self.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
368   self.Add( layer );
369
370   CreateScene();
371 }
372
373 }//namespace Internal
374
375 }//namespace Toolkit
376
377 }//namespace Dali
378