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>
36 // glTF file extension
37 const std::string GLTF_EXT( ".gltf" );
42 const uint32_t CUBEMAP_INDEX_X[2][6] = { { 2, 0, 1, 1, 1, 3 }, { 0, 1, 2, 3, 4, 5 } };
43 const uint32_t CUBEMAP_INDEX_Y[2][6] = { { 1, 1, 0, 2, 1, 1 }, { 0, 0, 0, 0, 0, 0 } };
47 Scene3dView::Scene3dView()
48 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
49 mRoot( Actor::New() ),
52 mDefaultCamera( CameraActor::New() ),
54 mLightType( Toolkit::Scene3dView::LightType::NONE ),
55 mLightVector( Vector3::ONE ),
56 mLightColor( Vector3::ONE )
60 Scene3dView::~Scene3dView()
64 Toolkit::Scene3dView Scene3dView::New( const std::string& filePath )
66 Scene3dView* impl = new Scene3dView();
68 Dali::Toolkit::Scene3dView handle = Dali::Toolkit::Scene3dView( *impl );
70 // Second-phase init of the implementation
71 // This can only be done after the CustomActor connection has been made...
72 impl->mFilePath = filePath;
78 Toolkit::Scene3dView Scene3dView::New( const std::string& filePath, const std::string& diffuseTexturePath, const std::string& specularTexturePath, Vector4 scaleFactor )
80 Scene3dView* impl = new Scene3dView();
82 Dali::Toolkit::Scene3dView handle = Dali::Toolkit::Scene3dView( *impl );
84 // Second-phase init of the implementation
85 // This can only be done after the CustomActor connection has been made...
86 impl->mFilePath = filePath;
87 impl->SetCubeMap( diffuseTexturePath, specularTexturePath, scaleFactor );
93 bool Scene3dView::CreateScene()
95 if( std::string::npos != mFilePath.rfind( GLTF_EXT ) )
97 Internal::Gltf::Loader gltfloader;
98 return( gltfloader.LoadScene( mFilePath, *this ) );
104 uint32_t Scene3dView::GetAnimationCount()
106 return mAnimationArray.size();
109 bool Scene3dView::PlayAnimation( uint32_t index )
111 if( GetAnimationCount() <= index )
116 mAnimationArray[index].Play();
120 bool Scene3dView::PlayAnimations()
122 for( auto&& animation : mAnimationArray )
130 bool Scene3dView::SetLight( Toolkit::Scene3dView::LightType type, Vector3 lightVector, Vector3 lightColor )
132 if( type > Toolkit::Scene3dView::LightType::DIRECTIONAL_LIGHT )
137 mLightType = static_cast<Toolkit::Scene3dView::LightType>(
138 ( mLightType >= Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT ) ?
139 Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT + type :
142 mLightVector = lightVector;
143 mLightColor = lightColor;
145 for( auto&& shader : mShaderArray )
147 shader.RegisterProperty( "uLightType", ( GetLightType() & ~Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT ) );
148 shader.RegisterProperty( "uLightVector", lightVector );
149 shader.RegisterProperty( "uLightColor", lightColor );
155 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 )
157 uint32_t byteSize = bytesPerPixel * xFaceSize * yFaceSize;
158 uint8_t* destBuffer = reinterpret_cast<uint8_t*>( malloc( byteSize + 4u ) );
160 int32_t srcStride = width * bytesPerPixel;
161 int32_t destStride = xFaceSize * bytesPerPixel;
162 int32_t srcOffset = xOffset * bytesPerPixel + yOffset * srcStride;
163 int32_t destOffset = 0;
164 for( uint16_t row = yOffset; row < yOffset + yFaceSize; ++row )
166 memcpy( destBuffer + destOffset, sourceBuffer + srcOffset, destStride );
167 srcOffset += srcStride;
168 destOffset += destStride;
174 void Scene3dView::UploadTextureFace( Texture& texture, Devel::PixelBuffer pixelBuffer, uint32_t faceIndex )
176 uint8_t* imageBuffer = pixelBuffer.GetBuffer();
177 uint32_t bytesPerPixel = Pixel::GetBytesPerPixel( pixelBuffer.GetPixelFormat() );
178 uint32_t imageWidth = pixelBuffer.GetWidth();
179 uint32_t imageHeight = pixelBuffer.GetHeight();
181 CubeType cubeType = ( imageWidth / 4 == imageHeight / 3 ) ? CROSS_HORIZONTAL :
182 ( ( imageWidth / 6 == imageHeight ) ? ARRAY_HORIZONTAL : NONE );
184 uint32_t faceSize = 0;
185 if( cubeType == CROSS_HORIZONTAL )
187 faceSize = imageWidth / 4;
189 else if( cubeType == ARRAY_HORIZONTAL )
191 faceSize = imageWidth / 6;
198 uint32_t xOffset = CUBEMAP_INDEX_X[cubeType][faceIndex] * faceSize;
199 uint32_t yOffset = CUBEMAP_INDEX_Y[cubeType][faceIndex] * faceSize;
201 uint8_t* tempImageBuffer = GetCroppedBuffer( imageBuffer, bytesPerPixel, imageWidth, imageHeight, xOffset, yOffset, faceSize, faceSize );
202 PixelData pixelData = PixelData::New( tempImageBuffer, faceSize * faceSize * bytesPerPixel, faceSize, faceSize, pixelBuffer.GetPixelFormat(), PixelData::FREE );
203 texture.Upload( pixelData, CubeMapLayer::POSITIVE_X + faceIndex, 0, 0, 0, faceSize, faceSize );
206 void Scene3dView::SetCubeMap( const std::string& diffuseTexturePath, const std::string& specularTexturePath, Vector4 scaleFactor )
208 mLightType = Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT;
211 std::string imageBrdfUrl = DALI_IMAGE_DIR "brdfLUT.png";
212 mBRDFTexture = LoadTexture( imageBrdfUrl.c_str(), true );
219 Devel::PixelBuffer diffusePixelBuffer = LoadImageFromFile( diffuseTexturePath );
220 uint32_t diffuseFaceSize = diffusePixelBuffer.GetWidth() / 4;
221 mDiffuseTexture = Texture::New( TextureType::TEXTURE_CUBE, diffusePixelBuffer.GetPixelFormat(), diffuseFaceSize, diffuseFaceSize );
222 for( uint32_t i = 0; i < 6; ++i )
224 UploadTextureFace( mDiffuseTexture, diffusePixelBuffer, i );
226 mDiffuseTexture.GenerateMipmaps();
229 Devel::PixelBuffer specularPixelBuffer = LoadImageFromFile( specularTexturePath );
230 uint32_t specularFaceSize = specularPixelBuffer.GetWidth() / 4;
231 mSpecularTexture = Texture::New( TextureType::TEXTURE_CUBE, specularPixelBuffer.GetPixelFormat(), specularFaceSize, specularFaceSize );
232 for( uint32_t i = 0; i < 6; ++i )
234 UploadTextureFace( mSpecularTexture, specularPixelBuffer, i );
236 mSpecularTexture.GenerateMipmaps();
238 mIBLScaleFactor = scaleFactor;
241 bool Scene3dView::SetDefaultCamera( const Dali::Camera::Type type, const float nearPlane, const Vector3 cameraPosition )
243 mDefaultCamera.SetParentOrigin( ParentOrigin::CENTER );
244 mDefaultCamera.SetAnchorPoint( AnchorPoint::CENTER );
245 mDefaultCamera.SetType( type );
246 mDefaultCamera.SetNearClippingPlane( nearPlane );
247 mDefaultCamera.SetPosition( cameraPosition );
251 void Scene3dView::AddCamera( CameraActor cameraActor )
253 mCameraActorArray.push_back( cameraActor );
256 void Scene3dView::AddAnimation( Animation animation )
258 mAnimationArray.push_back( animation );
261 void Scene3dView::AddShader( Shader shader )
263 mShaderArray.push_back( shader );
266 Actor Scene3dView::GetRoot()
271 CameraActor Scene3dView::GetDefaultCamera()
273 return mDefaultCamera;
276 uint32_t Scene3dView::GetCameraCount()
278 return mCameraActorArray.size();
281 CameraActor Scene3dView::GetCamera( uint32_t cameraIndex )
283 CameraActor cameraActor;
284 if( cameraIndex >= mCameraActorArray.size() )
288 cameraActor = mCameraActorArray[cameraIndex];
292 Toolkit::Scene3dView::LightType Scene3dView::GetLightType()
297 Vector3 Scene3dView::GetLightVector()
302 Vector3 Scene3dView::GetLightColor()
307 Vector4 Scene3dView::GetIBLScaleFactor()
309 return mIBLScaleFactor;
312 Texture Scene3dView::GetBRDFTexture()
317 Texture Scene3dView::GetSpecularTexture()
319 return mSpecularTexture;
322 Texture Scene3dView::GetDiffuseTexture()
324 return mDiffuseTexture;
327 Texture Scene3dView::LoadTexture( const char *imageUrl, bool generateMipmaps )
331 Devel::PixelBuffer pixelBuffer = LoadImageFromFile( imageUrl );
334 texture = Texture::New( TextureType::TEXTURE_2D, pixelBuffer.GetPixelFormat(), pixelBuffer.GetWidth(), pixelBuffer.GetHeight() );
335 PixelData pixelData = Devel::PixelBuffer::Convert( pixelBuffer );
336 texture.Upload( pixelData );
338 if( generateMipmaps )
340 texture.GenerateMipmaps();
347 void Scene3dView::OnInitialize()
349 mRoot.SetParentOrigin( ParentOrigin::CENTER );
350 mRoot.SetAnchorPoint( AnchorPoint::CENTER );
352 Layer layer = Layer::New();
353 layer.SetBehavior( Layer::LAYER_3D );
354 layer.SetParentOrigin( ParentOrigin::CENTER );
355 layer.SetAnchorPoint( AnchorPoint::CENTER );
359 // Apply some default resizing rules.
360 self.SetParentOrigin( ParentOrigin::CENTER );
361 self.SetAnchorPoint( AnchorPoint::CENTER );
367 }//namespace Internal