2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali-toolkit/internal/controls/scene3d-view/scene3d-view-impl.h>
22 #include <dali/integration-api/debug.h>
25 #include <dali-toolkit/devel-api/asset-manager/asset-manager.h>
39 const char* const IMAGE_BRDF_FILE_NAME = "brdfLUT.png";
41 // glTF file extension
42 const std::string GLTF_EXT( ".gltf" );
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 } };
52 Scene3dView::Scene3dView()
53 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
54 mRoot( Actor::New() ),
57 mDefaultCamera( CameraActor::New() ),
59 mLightType( Toolkit::Scene3dView::LightType::NONE ),
60 mLightVector( Vector3::ONE ),
61 mLightColor( Vector3::ONE )
65 Scene3dView::~Scene3dView()
69 Toolkit::Scene3dView Scene3dView::New( const std::string& filePath )
71 Scene3dView* impl = new Scene3dView();
73 Dali::Toolkit::Scene3dView handle = Dali::Toolkit::Scene3dView( *impl );
75 // Second-phase init of the implementation
76 // This can only be done after the CustomActor connection has been made...
77 impl->mFilePath = filePath;
83 Toolkit::Scene3dView Scene3dView::New( const std::string& filePath, const std::string& diffuseTexturePath, const std::string& specularTexturePath, Vector4 scaleFactor )
85 Scene3dView* impl = new Scene3dView();
87 Dali::Toolkit::Scene3dView handle = Dali::Toolkit::Scene3dView( *impl );
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 );
98 bool Scene3dView::CreateScene()
100 if( std::string::npos != mFilePath.rfind( GLTF_EXT ) )
102 Internal::Gltf::Loader gltfloader;
103 return( gltfloader.LoadScene( mFilePath, *this ) );
109 uint32_t Scene3dView::GetAnimationCount()
111 return mAnimationArray.size();
114 bool Scene3dView::PlayAnimation( uint32_t index )
116 if( GetAnimationCount() <= index )
121 mAnimationArray[index].Play();
125 bool Scene3dView::PlayAnimations()
127 for( auto&& animation : mAnimationArray )
135 bool Scene3dView::SetLight( Toolkit::Scene3dView::LightType type, Vector3 lightVector, Vector3 lightColor )
137 if( type > Toolkit::Scene3dView::LightType::DIRECTIONAL_LIGHT )
142 mLightType = static_cast<Toolkit::Scene3dView::LightType>(
143 ( mLightType >= Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT ) ?
144 Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT + type :
147 mLightVector = lightVector;
148 mLightColor = lightColor;
150 for( auto&& shader : mShaderArray )
152 shader.RegisterProperty( "uLightType", ( GetLightType() & ~Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT ) );
153 shader.RegisterProperty( "uLightVector", lightVector );
154 shader.RegisterProperty( "uLightColor", lightColor );
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 )
162 uint32_t byteSize = bytesPerPixel * xFaceSize * yFaceSize;
163 uint8_t* destBuffer = reinterpret_cast<uint8_t*>( malloc( byteSize + 4u ) );
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 )
171 memcpy( destBuffer + destOffset, sourceBuffer + srcOffset, destStride );
172 srcOffset += srcStride;
173 destOffset += destStride;
179 void Scene3dView::UploadTextureFace( Texture& texture, Devel::PixelBuffer pixelBuffer, uint32_t faceIndex )
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();
186 CubeType cubeType = ( imageWidth / 4 == imageHeight / 3 ) ? CROSS_HORIZONTAL :
187 ( ( imageWidth / 6 == imageHeight ) ? ARRAY_HORIZONTAL : NONE );
189 uint32_t faceSize = 0;
190 if( cubeType == CROSS_HORIZONTAL )
192 faceSize = imageWidth / 4;
194 else if( cubeType == ARRAY_HORIZONTAL )
196 faceSize = imageWidth / 6;
203 uint32_t xOffset = CUBEMAP_INDEX_X[cubeType][faceIndex] * faceSize;
204 uint32_t yOffset = CUBEMAP_INDEX_Y[cubeType][faceIndex] * faceSize;
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 );
211 void Scene3dView::SetCubeMap( const std::string& diffuseTexturePath, const std::string& specularTexturePath, Vector4 scaleFactor )
213 mLightType = Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT;
216 const std::string imageDirPath = AssetManager::GetDaliImagePath();
217 const std::string imageBrdfUrl = imageDirPath + IMAGE_BRDF_FILE_NAME;
218 mBRDFTexture = LoadTexture( imageBrdfUrl.c_str(), true );
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 )
230 UploadTextureFace( mDiffuseTexture, diffusePixelBuffer, i );
232 mDiffuseTexture.GenerateMipmaps();
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 )
240 UploadTextureFace( mSpecularTexture, specularPixelBuffer, i );
242 mSpecularTexture.GenerateMipmaps();
244 mIBLScaleFactor = scaleFactor;
247 bool Scene3dView::SetDefaultCamera( const Dali::Camera::Type type, const float nearPlane, const Vector3 cameraPosition )
249 mDefaultCamera.SetParentOrigin( ParentOrigin::CENTER );
250 mDefaultCamera.SetAnchorPoint( AnchorPoint::CENTER );
251 mDefaultCamera.SetType( type );
252 mDefaultCamera.SetNearClippingPlane( nearPlane );
253 mDefaultCamera.SetPosition( cameraPosition );
257 void Scene3dView::AddCamera( CameraActor cameraActor )
259 mCameraActorArray.push_back( cameraActor );
262 void Scene3dView::AddAnimation( Animation animation )
264 mAnimationArray.push_back( animation );
267 void Scene3dView::AddShader( Shader shader )
269 mShaderArray.push_back( shader );
272 Actor Scene3dView::GetRoot()
277 CameraActor Scene3dView::GetDefaultCamera()
279 return mDefaultCamera;
282 uint32_t Scene3dView::GetCameraCount()
284 return mCameraActorArray.size();
287 CameraActor Scene3dView::GetCamera( uint32_t cameraIndex )
289 CameraActor cameraActor;
290 if( cameraIndex >= mCameraActorArray.size() )
294 cameraActor = mCameraActorArray[cameraIndex];
298 Toolkit::Scene3dView::LightType Scene3dView::GetLightType()
303 Vector3 Scene3dView::GetLightVector()
308 Vector3 Scene3dView::GetLightColor()
313 Vector4 Scene3dView::GetIBLScaleFactor()
315 return mIBLScaleFactor;
318 Texture Scene3dView::GetBRDFTexture()
323 Texture Scene3dView::GetSpecularTexture()
325 return mSpecularTexture;
328 Texture Scene3dView::GetDiffuseTexture()
330 return mDiffuseTexture;
333 Texture Scene3dView::LoadTexture( const char *imageUrl, bool generateMipmaps )
337 Devel::PixelBuffer pixelBuffer = LoadImageFromFile( imageUrl );
340 texture = Texture::New( TextureType::TEXTURE_2D, pixelBuffer.GetPixelFormat(), pixelBuffer.GetWidth(), pixelBuffer.GetHeight() );
341 PixelData pixelData = Devel::PixelBuffer::Convert( pixelBuffer );
342 texture.Upload( pixelData );
344 if( generateMipmaps )
346 texture.GenerateMipmaps();
353 void Scene3dView::OnInitialize()
355 mRoot.SetParentOrigin( ParentOrigin::CENTER );
356 mRoot.SetAnchorPoint( AnchorPoint::CENTER );
358 Layer layer = Layer::New();
359 layer.SetBehavior( Layer::LAYER_3D );
360 layer.SetParentOrigin( ParentOrigin::CENTER );
361 layer.SetAnchorPoint( AnchorPoint::CENTER );
365 // Apply some default resizing rules.
366 self.SetParentOrigin( ParentOrigin::CENTER );
367 self.SetAnchorPoint( AnchorPoint::CENTER );
373 }//namespace Internal