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.
18 #include "scene-impl.h"
21 #include <dali/integration-api/debug.h>
33 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
34 mRoot( Actor::New() ),
35 mDefaultCamera( CameraActor::New() ),
36 mLightType( Toolkit::Scene::LightType::NONE ),
37 mLightVector( Vector3::ONE ),
38 mLightColor( Vector3::ONE )
46 Toolkit::Scene Scene::New( const std::string& filePath )
48 Scene* impl = new Scene();
50 Dali::Toolkit::Scene handle = Dali::Toolkit::Scene( *impl );
52 // Second-phase init of the implementation
53 // This can only be done after the CustomActor connection has been made...
55 impl->CreateScene( filePath );
60 Toolkit::Scene Scene::New( const std::string& filePath, const std::string& diffuseTexturePath, const std::string& specularTexturePath, Vector4 ScaleFactor )
62 Scene* impl = new Scene();
64 Dali::Toolkit::Scene handle = Dali::Toolkit::Scene( *impl );
66 // Second-phase init of the implementation
67 // This can only be done after the CustomActor connection has been made...
69 impl->SetCubeMap( diffuseTexturePath, specularTexturePath, ScaleFactor );
70 impl->CreateScene( filePath );
75 bool Scene::CreateScene( const std::string& filePath )
77 if( std::string::npos != filePath.rfind( GLTF_EXT ) )
79 Internal::GltfLoader gltfloader;
80 return( gltfloader.LoadScene( filePath, *this ) );
86 uint32_t Scene::GetAnimationCount()
88 return mAnimationArray.size();
91 bool Scene::PlayAnimation( uint32_t index )
93 if( GetAnimationCount() <= index )
98 mAnimationArray[index].Play();
102 bool Scene::PlayAnimations()
104 if( GetAnimationCount() == 0 )
109 for( unsigned int i=0; i<mAnimationArray.size(); ++i )
117 bool Scene::SetLight( Toolkit::Scene::LightType type, Vector3 lightVector, Vector3 lightColor )
119 if( type > Toolkit::Scene::LightType::DIRECTIONAL_LIGHT )
124 mLightType = static_cast<Toolkit::Scene::LightType>(
125 ( mLightType >= Toolkit::Scene::LightType::IMAGE_BASED_LIGHT ) ?
126 Toolkit::Scene::LightType::IMAGE_BASED_LIGHT + type :
129 mLightVector = lightVector;
130 mLightColor = lightColor;
132 for( unsigned int i = 0; i<mShaderArray.size(); ++i )
134 mShaderArray[i].RegisterProperty( "uLightType", ( GetLightType() & ~Toolkit::Scene::LightType::IMAGE_BASED_LIGHT ) );
135 mShaderArray[i].RegisterProperty( "uLightVector", lightVector );
136 mShaderArray[i].RegisterProperty( "uLightColor", lightColor );
142 unsigned char* Scene::CropBuffer( unsigned char* sourceBuffer, unsigned int bytesPerPixel, unsigned int width, unsigned int height, unsigned int xOffset, unsigned int yOffset, unsigned int xFaceSize, unsigned int yFaceSize )
144 unsigned int byteSize = bytesPerPixel * xFaceSize * yFaceSize;
145 unsigned char* destBuffer = reinterpret_cast<unsigned char*>( malloc( byteSize + 4u ) );
147 int srcStride = width * bytesPerPixel;
148 int destStride = xFaceSize * bytesPerPixel;
149 int srcOffset = xOffset * bytesPerPixel + yOffset * srcStride;
151 for( uint16_t row = yOffset; row < yOffset + yFaceSize; ++row )
153 memcpy( destBuffer + destOffset, sourceBuffer + srcOffset, destStride );
154 srcOffset += srcStride;
155 destOffset += destStride;
161 void Scene::UploadTextureFace( Texture& texture, Devel::PixelBuffer pixelBuffer, int faceIndex )
163 unsigned char* imageBuffer = pixelBuffer.GetBuffer();
164 unsigned int bytesPerPixel = Pixel::GetBytesPerPixel( pixelBuffer.GetPixelFormat() );
165 unsigned int imageWidth = pixelBuffer.GetWidth();
166 unsigned int imageHeight = pixelBuffer.GetHeight();
168 CubeType cubeType = ( imageWidth / 4 == imageHeight / 3 ) ? CROSS_HORIZENTAL :
169 ( ( imageWidth / 6 == imageHeight ) ? ARRAY_HORIZENTAL : NONE );
172 if( cubeType == CROSS_HORIZENTAL )
174 faceSize = imageWidth / 4;
176 else if( cubeType == ARRAY_HORIZENTAL )
178 faceSize = imageWidth / 6;
181 unsigned int xOffset = cubeMap_index_x[cubeType][faceIndex] * faceSize;
182 unsigned int yOffset = cubeMap_index_y[cubeType][faceIndex] * faceSize;
184 unsigned char* tempImageBuffer = CropBuffer( imageBuffer, bytesPerPixel, imageWidth, imageHeight, xOffset, yOffset, faceSize, faceSize );
185 PixelData pixelData = PixelData::New( tempImageBuffer, faceSize * faceSize * bytesPerPixel, faceSize, faceSize, pixelBuffer.GetPixelFormat(), PixelData::FREE );
186 texture.Upload( pixelData, CubeMapLayer::POSITIVE_X + faceIndex, 0, 0, 0, faceSize, faceSize );
189 void Scene::SetCubeMap( const std::string& diffuseTexturePath, const std::string& specularTexturePath, Vector4 ScaleFactor )
191 mLightType = Toolkit::Scene::LightType::IMAGE_BASED_LIGHT;
194 std::string imageBrdfUrl = DALI_IMAGE_DIR "brdfLUT.png";
195 mBRDFTexture = LoadTexture( imageBrdfUrl.c_str(), true );
202 Devel::PixelBuffer diffusePixelBuffer = LoadImageFromFile( diffuseTexturePath );
203 int diffuseFaceSize = diffusePixelBuffer.GetWidth() / 4;
204 mDiffuseTexture = Texture::New( TextureType::TEXTURE_CUBE, diffusePixelBuffer.GetPixelFormat(), diffuseFaceSize, diffuseFaceSize );
205 for( int i = 0; i<6; ++i )
207 UploadTextureFace( mDiffuseTexture, diffusePixelBuffer, i );
209 mDiffuseTexture.GenerateMipmaps();
212 Devel::PixelBuffer specularPixelBuffer = LoadImageFromFile( specularTexturePath );
213 int specularFaceSize = specularPixelBuffer.GetWidth() / 4;
214 mSpecularTexture = Texture::New( TextureType::TEXTURE_CUBE, specularPixelBuffer.GetPixelFormat(), specularFaceSize, specularFaceSize );
215 for( int i = 0; i<6; ++i )
217 UploadTextureFace( mSpecularTexture, specularPixelBuffer, i );
219 mSpecularTexture.GenerateMipmaps();
221 mIBLScaleFactor = ScaleFactor;
224 bool Scene::SetDefaultCamera( const Dali::Camera::Type type, const float nearPlane, const Vector3 cameraPosition )
226 mDefaultCamera.SetParentOrigin( ParentOrigin::CENTER );
227 mDefaultCamera.SetAnchorPoint( AnchorPoint::CENTER );
228 mDefaultCamera.SetType( type );
229 mDefaultCamera.SetNearClippingPlane( nearPlane );
230 mDefaultCamera.SetPosition( cameraPosition );
234 void Scene::AddCamera( CameraActor& cameraActor )
236 mCameraActorArray.push_back( cameraActor );
239 void Scene::AddAnimation( Animation& animation )
241 mAnimationArray.push_back( animation );
244 void Scene::AddShader( Shader shader )
246 mShaderArray.push_back( shader );
249 Actor Scene::GetRoot()
254 CameraActor Scene::GetDefaultCamera()
256 return mDefaultCamera;
259 CameraActor Scene::GetCamera( const int cameraIndex )
261 if( cameraIndex < 0 )
263 return GetDefaultCamera();
265 return mCameraActorArray[cameraIndex];
268 Toolkit::Scene::LightType Scene::GetLightType()
273 Vector3 Scene::GetLightVector()
278 Vector3 Scene::GetLightColor()
283 Vector4 Scene::GetIBLScaleFactor()
285 return mIBLScaleFactor;
288 Texture Scene::GetBRDFTexture()
293 Texture Scene::GetSpecularTexture()
295 return mSpecularTexture;
298 Texture Scene::GetDiffuseTexture()
300 return mDiffuseTexture;
303 Texture Scene::LoadTexture( const char *imageUrl, bool generateMipmaps )
307 Devel::PixelBuffer pixelBuffer = LoadImageFromFile( imageUrl );
310 texture = Texture::New( TextureType::TEXTURE_2D, pixelBuffer.GetPixelFormat(), pixelBuffer.GetWidth(), pixelBuffer.GetHeight() );
311 PixelData pixelData = Devel::PixelBuffer::Convert( pixelBuffer );
312 texture.Upload( pixelData );
314 if( generateMipmaps )
316 texture.GenerateMipmaps();
323 void Scene::OnInitialize()
325 mRoot.SetParentOrigin( ParentOrigin::CENTER );
326 mRoot.SetAnchorPoint( AnchorPoint::CENTER );
328 Layer layer = Layer::New();
329 layer.SetBehavior( Layer::LAYER_3D );
330 layer.SetParentOrigin( ParentOrigin::CENTER );
331 layer.SetAnchorPoint( AnchorPoint::CENTER );
335 // Apply some default resizing rules.
336 self.SetParentOrigin( ParentOrigin::CENTER );
337 self.SetAnchorPoint( AnchorPoint::CENTER );
340 mShaderArray.clear();
341 mCameraActorArray.clear();
342 mAnimationArray.clear();
345 }//namespace Internal