2 * Copyright (c) 2014 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 "../shared/view.h"
21 #include <dali/dali.h>
22 #include <dali-toolkit/dali-toolkit.h>
26 using namespace Dali::Toolkit;
28 using namespace DemoHelper;
32 const char* gModelFile = DALI_MODEL_DIR "AlbumCute.dae";
33 const char* gBinaryModelFile = DALI_MODEL_DIR "AlbumCute.dali-bin";
35 const char* BACKGROUND_IMAGE( DALI_IMAGE_DIR "background-default.png" );
36 const char* TOOLBAR_IMAGE( DALI_IMAGE_DIR "top-bar.png" );
38 const char* APPLICATION_TITLE_PAN_LIGHT( "Lighting: Pan Light" );
39 const char* APPLICATION_TITLE_PAN_OBJECT( "Lighting: Pan Object" );
40 const char* APPLICATION_TITLE_PAN_SCENE( "Lighting: Pan Scene" );
41 const char* APPLICATION_TITLE_ROTATE_SCENE( "Lighting: Rotate Scene" );
42 const char* CHANGE_EFFECT_IMAGE( DALI_IMAGE_DIR "icon-change.png" );
43 const char* RESET_ICON( DALI_IMAGE_DIR "icon-reset.png" );
45 const Quaternion JAUNTY_ROTATION(Math::PI/5.0f, Math::PI/5.0f, 0.0f); // Euler angles
46 const float MIN_PINCH_SCALE( 0.3f );
47 const float MAX_PINCH_SCALE( 2.05f );
49 const float R3_2(0.8660254);
50 const Vector3 TOP_POINT( 0.0f, -1.0f, 0.0f);
51 const Vector3 LEFT_POINT( -R3_2, 0.5f, 0.0f);
52 const Vector3 RIGHT_POINT( R3_2, 0.5f, 0.0f);
53 const Vector3 FRONT_POINT( 0.0f, 0.0f, 20.0f);
55 const Vector2 DEFAULT_STAGE_SIZE( 480.0f, 800.0f );
60 * This example shows a fixed point light onto an animating model
61 * casting a shadow onto a wall. The whole scene can be rotated.
64 class TestApp : public ConnectionTracker
70 * @param application class, stored as reference
72 TestApp(Application &app)
75 mTranslation(Vector3::ZERO),
78 mLightLongitudinal(0.0f),
80 mObjectLongitudinal(0.0f),
81 mObjectAxisTilt(0.0f),
83 mScaleAtPinchStart(0.5f),
86 app.InitSignal().Connect(this, &TestApp::Create);
87 app.TerminateSignal().Connect(this, &TestApp::Terminate);
92 // Nothing to do here; All the members of this class get deleted automatically and they delete their children
96 struct PositionInFrontOf
102 Vector3 operator()( const Vector3& current, const PropertyInput& property )
104 Vector3 position = property.GetVector3();
110 struct QuaternionEqualToConstraint
112 QuaternionEqualToConstraint()
116 Quaternion operator()( const Quaternion& current, const PropertyInput& property )
118 return property.GetQuaternion();
124 * This method gets called once the main loop of application is up and running
126 void Create(Application& app)
128 srand(0); // Want repeatable path
130 Stage::GetCurrent().KeyEventSignal().Connect(this, &TestApp::OnKeyEvent);
132 mModel = Model::New(gBinaryModelFile); // trigger model load
133 mModel.LoadingFinishedSignal().Connect(this, &TestApp::BinaryModelLoaded);
135 CreateToolbarAndView(app);
136 CreateShadowViewAndLights();
139 void CreateToolbarAndView(Application& app)
141 // Creates a default view with a default tool bar.
142 // The view is added to the stage.
143 Toolkit::ToolBar toolBar;
144 mContents = DemoHelper::CreateView( app,
151 // Add an effect-changing button on the right of the tool bar.
152 Image imageChangeEffect = ResourceImage::New( CHANGE_EFFECT_IMAGE );
153 Toolkit::PushButton effectChangeButton = Toolkit::PushButton::New();
154 effectChangeButton.SetBackgroundImage(imageChangeEffect);
155 effectChangeButton.ClickedSignal().Connect( this, &TestApp::OnEffectButtonClicked );
156 toolBar.AddControl( effectChangeButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HorizontalRight, DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
158 // Add title to the tool bar.
159 mTitleActor = Toolkit::TextView::New();
160 toolBar.AddControl( mTitleActor, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarTitlePercentage, Toolkit::Alignment::HorizontalCenter );
163 mTitleActor.SetText( APPLICATION_TITLE_PAN_SCENE );
164 mTitleActor.SetSize( Font::New().MeasureText( APPLICATION_TITLE_PAN_SCENE ) );
165 mTitleActor.SetStyleToCurrentText( DemoHelper::GetDefaultTextStyle() );
168 Image resetImage = ResourceImage::New( RESET_ICON );
169 Toolkit::PushButton resetButton = Toolkit::PushButton::New();
170 resetButton.SetBackgroundImage( resetImage );
171 resetButton.ClickedSignal().Connect( this, &TestApp::OnResetPressed );
172 toolBar.AddControl( resetButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HorizontalCenter, DemoHelper::DEFAULT_PLAY_PADDING );
175 mView.SetPosition(Vector3(0.0f, 0.0f, -50));
177 mContents.SetPosition(mTranslation);
178 mContents.SetRotation(CalculateWorldRotation(Radian(mLongitudinal), Radian(mAxisTilt)));
179 mContents.SetScale(mPinchScale, mPinchScale, mPinchScale);
181 mPanGestureDetector = PanGestureDetector::New();
182 mPanGestureDetector.Attach( mView );
183 mPanGestureDetector.DetectedSignal().Connect(this, &TestApp::OnPan);
185 mPinchGestureDetector = PinchGestureDetector::New();
186 mPinchGestureDetector.Attach( mView );
187 mPinchGestureDetector.DetectedSignal().Connect(this, &TestApp::OnPinch);
189 mTapGestureDetector = TapGestureDetector::New(1, 1);
190 mTapGestureDetector.Attach( mView );
191 mTapGestureDetector.DetectedSignal().Connect(this, &TestApp::OnTap);
195 * This method gets called once the model is loaded by the resource manager
197 void BinaryModelLoaded(Model model)
199 if( model.GetLoadingState() == ResourceLoadingSucceeded )
201 std::cout << "Succeeded loading binary model" << std::endl;
207 std::cout << "Failed loading binary model" << std::endl;
209 mModel = Model::New(gModelFile);
210 mModel.LoadingFinishedSignal().Connect(this, &TestApp::ModelLoaded);
214 void ModelLoaded(Model model)
216 if( model.GetLoadingState() == ResourceLoadingSucceeded )
218 std::cout << "Succeeded loading collada model" << std::endl;
220 model.Save(gBinaryModelFile);
225 std::cout << "Failed loading collada model" << std::endl;
231 void CreateShadowViewAndLights()
233 mShadowView = Toolkit::ShadowView::New();
234 mShadowView.SetName("Container");
235 mShadowView.SetParentOrigin(ParentOrigin::CENTER);
236 mShadowView.SetAnchorPoint(AnchorPoint::CENTER);
237 mShadowView.SetSizeMode( SIZE_EQUAL_TO_PARENT );
238 mShadowView.SetPointLightFieldOfView( Math::PI / 2.0f);
239 mContents.Add(mShadowView);
241 Image brickWall = ResourceImage::New(DALI_IMAGE_DIR "brick-wall.jpg");
242 mShadowPlaneBg = ImageActor::New(brickWall);
243 mShadowPlaneBg.SetParentOrigin(ParentOrigin::CENTER);
244 mShadowPlaneBg.SetAnchorPoint(AnchorPoint::CENTER);
245 mShadowPlaneBg.SetName("Plane");
246 mShadowPlaneBg.SetSize(1000.0f, 1000.0f);
247 mContents.Add(mShadowPlaneBg);
248 mShadowPlaneBg.SetPosition(Vector3(50.0f, 50.0f, -200.0f));
250 mShadowView.SetShadowPlane(mShadowPlaneBg);
251 mShadowView.Activate();
253 mLightAnchor = Actor::New();
254 mLightAnchor.SetParentOrigin(ParentOrigin::CENTER);
255 mLightAnchor.SetAnchorPoint(AnchorPoint::CENTER);
256 mLightAnchor.SetRotation(CalculateWorldRotation(Radian(mLightLongitudinal), Radian(mLightAxisTilt)));
258 // Work out a scaling factor as the initial light position was calculated for desktop
259 // Need to scale light position as model size is based on stage size (i.e. much bigger on device)
260 Vector2 stageSize( Stage::GetCurrent().GetSize() );
261 float scaleFactor = stageSize.x / DEFAULT_STAGE_SIZE.x;
263 mCastingLight = Actor::New();
264 mCastingLight.SetParentOrigin(ParentOrigin::CENTER);
265 mCastingLight.SetAnchorPoint(AnchorPoint::CENTER);
266 mCastingLight.SetPosition( Vector3( 0.0f, 0.0f, 800.0f ) * scaleFactor );
269 style.SetFontPointSize( PointSize(DemoHelper::ScalePointSize(20.0f)) );
270 style.SetFontName("Times New Roman");
271 style.SetFontStyle("Book");
273 TextActorParameters parameters( style, TextActorParameters::FONT_DETECTION_ON );
274 TextActor text = TextActor::New("Light", parameters);
275 text.SetColor(Color::BLUE);
277 mCastingLight.Add(text);
278 mLightAnchor.Add(mCastingLight);
279 mShadowPlaneBg.Add(mLightAnchor);
281 text.SetParentOrigin(ParentOrigin::CENTER);
282 mShadowView.SetPointLight(mCastingLight);
287 mModelActor = ModelActorFactory::BuildActorTree(mModel, ""); // Gets root actor
291 Vector2 stageSize(Stage::GetCurrent().GetSize());
293 mModelActor.SetSize(250.0f, 250.0f);
294 mModelActor.SetPosition(0.0f, 0.0f, 130.0f);
297 Light keylight = Light::New("KeyLight");
298 keylight.SetFallOff(Vector2(10000.0f, 10000.0f));
299 //keylight.SetSpecularColor(Vector3::ZERO);
300 mKeyLightActor = LightActor::New();
301 mKeyLightActor.SetParentOrigin(ParentOrigin::CENTER);
302 mKeyLightActor.SetName(keylight.GetName());
304 //Add all the actors to the stage
305 mCastingLight.Add(mKeyLightActor);
306 mKeyLightActor.SetLight(keylight);
308 mShadowView.Add(mModelActor);
311 if (mModel.NumberOfAnimations())
313 mModelAnimation = ModelActorFactory::BuildAnimation(mModel, mModelActor, 0);
314 mModelAnimation.SetDuration(4.0f);
315 mModelAnimation.SetLooping(true);
316 mModelAnimation.Play();
323 Quaternion CalculateWorldRotation(Radian longitude, Radian axisTilt )
325 Quaternion q(longitude, Vector3::YAXIS);
326 Quaternion p(axisTilt, Vector3::XAXIS);
330 void OnTap(Dali::Actor actor, const TapGesture& gesture)
334 //mAnimation.Pause();
335 mModelAnimation.Pause();
341 mModelAnimation.Play();
346 void OnPan(Actor actor, const PanGesture& gesture)
348 switch (gesture.state)
350 case Gesture::Continuing:
356 mLightLongitudinal += gesture.displacement.x/4.0f;
357 mLightAxisTilt -= gesture.displacement.y/6.0f;
358 mLightAxisTilt = Clamp<float>(mLightAxisTilt, -90.0f, 90.0f);
359 mLightAnchor.SetRotation(CalculateWorldRotation(Radian(mLightLongitudinal), Radian(mLightAxisTilt)));
365 mTranslation += Vector3(gesture.displacement.x, gesture.displacement.y, 0.f);
366 mContents.SetPosition(mTranslation);
372 mLongitudinal += gesture.displacement.x/4.0f;
373 mAxisTilt -= gesture.displacement.y/6.0f;
374 mAxisTilt = Clamp<float>(mAxisTilt, -90.0f, 90.0f);
375 mContents.SetRotation(CalculateWorldRotation(Radian(mLongitudinal), Radian(mAxisTilt)));
381 mObjectLongitudinal += gesture.displacement.x/4.0f;
382 mObjectAxisTilt -= gesture.displacement.y/6.0f;
383 mObjectAxisTilt = Clamp<float>(mObjectAxisTilt, -90.0f, 90.0f);
384 mModelActor.SetRotation(CalculateWorldRotation(Radian(mObjectLongitudinal), Radian(mObjectAxisTilt)));
391 case Gesture::Finished:
392 // Start animation at last known speed
400 void OnPinch(Actor actor, const PinchGesture& gesture)
402 if (gesture.state == Gesture::Started)
404 mScaleAtPinchStart = mContents.GetCurrentScale().x;
406 mPinchScale = Clamp(mScaleAtPinchStart * gesture.scale, MIN_PINCH_SCALE, MAX_PINCH_SCALE);
408 mContents.SetScale(mPinchScale, mPinchScale, mPinchScale);
411 void Terminate(Application& app)
415 Stage::GetCurrent().Remove(mModelActor);
419 Stage::GetCurrent().Remove(mKeyLightActor);
423 Stage::GetCurrent().Remove(mView);
427 void OnKeyEvent(const KeyEvent& event)
429 if(event.state == KeyEvent::Down)
431 if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
438 bool OnEffectButtonClicked( Toolkit::Button button )
443 mPanState = ROTATE_SCENE;
444 mTitleActor.SetText( APPLICATION_TITLE_ROTATE_SCENE );
445 mTitleActor.SetSize( Font::New().MeasureText( APPLICATION_TITLE_ROTATE_SCENE ) );
448 mPanState = PAN_LIGHT;
449 mTitleActor.SetText( APPLICATION_TITLE_PAN_LIGHT );
450 mTitleActor.SetSize( Font::New().MeasureText( APPLICATION_TITLE_PAN_LIGHT ) );
453 mPanState = PAN_OBJECT;
454 mTitleActor.SetText( APPLICATION_TITLE_PAN_OBJECT );
455 mTitleActor.SetSize( Font::New().MeasureText( APPLICATION_TITLE_PAN_OBJECT ) );
458 mPanState = PAN_SCENE;
459 mTitleActor.SetText( APPLICATION_TITLE_PAN_SCENE );
460 mTitleActor.SetSize( Font::New().MeasureText( APPLICATION_TITLE_PAN_SCENE ) );
466 mTitleActor.SetStyleToCurrentText(DemoHelper::GetDefaultTextStyle());
471 bool OnResetPressed( Toolkit::Button button )
474 mTranslation = Vector3::ZERO;
475 mContents.SetPosition(mTranslation);
476 // Align scene so that light anchor orientation is Z Axis
477 mAxisTilt = -mLightAxisTilt;
478 mLongitudinal = -mLightLongitudinal;
479 mContents.SetRotation(CalculateWorldRotation(Radian(mLongitudinal), Radian(mAxisTilt)));
490 LightActor mKeyLightActor;
491 Animation mAnimation;
492 Animation mModelAnimation;
494 Toolkit::ShadowView mShadowView;
495 ImageActor mShadowPlaneBg;
496 ImageActor mShadowPlane;
500 PanGestureDetector mPanGestureDetector;
501 PinchGestureDetector mPinchGestureDetector;
502 TapGestureDetector mTapGestureDetector;
503 Vector3 mTranslation;
504 Degree mLongitudinal;
506 Degree mLightLongitudinal;
507 Degree mLightAxisTilt;
508 Degree mObjectLongitudinal;
509 Degree mObjectAxisTilt;
511 float mScaleAtPinchStart;
513 Toolkit::TextView mTitleActor;
526 /*****************************************************************************/
529 RunTest(Application& app)
535 /*****************************************************************************/
538 main(int argc, char **argv)
540 Application app = Application::New(&argc, &argv);