Use Window instead of Stage
[platform/core/uifw/dali-demo.git] / examples / rendering-skybox / look-camera.cpp
1 /*
2  * Copyright (c) 2020 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 #include "look-camera.h"
19
20 #include <dali/public-api/render-tasks/render-task-list.h>
21 #include <dali/public-api/render-tasks/render-task.h>
22 #include <dali/public-api/events/touch-data.h>
23 #include <dali/public-api/events/touch-event.h>
24
25 using namespace Dali;
26
27 namespace
28 {
29 // Input sensitivity, the larger value, the more sensitive input
30 // Default value has been chosen empirically
31 const float   CAMERA_SENSITIVITY        ( 90.0f );
32
33 // Vertical angle limit of the camera
34 const float   CAMERA_VERTICAL_LIMIT     ( 80.0f );
35
36 // Position where camera is instantiated by default
37 const Vector3 CAMERA_DEFAULT_POSITION   ( 0.0f, 0.0f, 3.0f );
38
39 // Field-of-View in degrees
40 const float   CAMERA_DEFAULT_FOV        ( 60.0f );
41
42 // Near plane
43 const float   CAMERA_DEFAULT_NEAR       ( 0.1f );
44
45 // Far plane
46 const float   CAMERA_DEFAULT_FAR        ( 100.0f );
47
48 // Default forward vector
49 const Vector3 CAMERA_FORWARD            ( 0.0f, 0.0f, 1.0f );
50
51 // Default up vector
52 const Vector3 CAMERA_UP                 ( Vector3::YAXIS );
53 }
54
55 LookCamera::LookCamera()
56 : mCameraYawPitch( 0.0f, 180.0f ),
57   mFovY( CAMERA_DEFAULT_FOV ),
58   mNear( CAMERA_DEFAULT_NEAR ),
59   mFar( CAMERA_DEFAULT_FAR ),
60   mCameraPosition( CAMERA_DEFAULT_POSITION )
61 {
62 }
63
64 LookCamera::~LookCamera()
65 {
66   mTimer.Stop();
67   mCameraActor.Remove( mInterceptorActor );
68 }
69
70 void LookCamera::Initialise( Window window, const Vector3& position, float fovY, float near, float far )
71 {
72   mWindow = window;
73
74   mFovY = fovY;
75   mNear = near;
76   mFar = far;
77
78   // Camera position is shadowed in order to avoid using.GetCurrentProperty< Vector3 >( Actor::Property::POSITION )
79   mCameraPosition = position;
80
81   // Initialise default camera
82   InitialiseDefaultCamera();
83
84   // Create input interceptor actor
85   CreateInterceptorActor();
86
87   // Start timer
88   mTimer = Timer::New( 16 );
89   mTimer.TickSignal().Connect( this, &LookCamera::OnTick );
90   mTimer.Start();
91 }
92
93 bool LookCamera::OnTick()
94 {
95   Vector2 windowSize = mWindow.GetSize();
96
97   // ---------------------------------------------------------------------
98   // update rotation
99   Vector2 tmp( mScreenLookDelta );
100   mScreenLookDelta = Vector2::ZERO;
101
102   float yaw = ( (tmp.y / windowSize.x ) * CAMERA_SENSITIVITY );
103   float pitch = ( (tmp.x / windowSize.y ) * CAMERA_SENSITIVITY );
104   mCameraYawPitch.x -= yaw;
105   mCameraYawPitch.y -= pitch;
106   if( abs( mCameraYawPitch.x ) > CAMERA_VERTICAL_LIMIT )
107   {
108     mCameraYawPitch.x = CAMERA_VERTICAL_LIMIT * ((mCameraYawPitch.x < 0) ? -1.0f : 1.0f );
109   }
110
111   Quaternion rotation;
112   Quaternion rotX( Degree( mCameraYawPitch.x), Vector3( 1.0f, 0.0f, 0.0f ) );
113   Quaternion rotY( Degree( mCameraYawPitch.y), Vector3( 0.0f, 1.0f, 0.0f ) );
114   rotation = ( rotY * rotX );
115
116   mCameraActor.SetProperty( Actor::Property::ORIENTATION, rotation );
117
118   return true;
119 }
120
121 void LookCamera::InitialiseDefaultCamera()
122 {
123   mCameraActor = mWindow.GetRenderTaskList().GetTask(0).GetCameraActor();
124   mCameraActor.SetProperty( Dali::Actor::Property::NAME, "LookCamera" );
125   mCameraActor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
126   mCameraActor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
127   mCameraActor.SetFieldOfView( Radian( Degree( mFovY ) ) );
128
129   // should be read from file
130   mCameraActor.SetNearClippingPlane( mNear );
131   mCameraActor.SetFarClippingPlane( mFar );
132   mCameraActor.SetProperty( Actor::Property::POSITION, mCameraPosition );
133 }
134
135 void LookCamera::CreateInterceptorActor()
136 {
137   Vector2 windowSize = mWindow.GetSize();
138
139   mInterceptorActor = Actor::New();
140   mInterceptorActor.SetProperty( Dali::Actor::Property::NAME, "InputInterceptor" );
141   mInterceptorActor.SetProperty( Actor::Property::SIZE, Vector3( windowSize.width, windowSize.height, 1 ) );
142   mInterceptorActor.SetProperty( Actor::Property::POSITION, Vector3( 0.0, 0.0, 1.0  ) );
143   mInterceptorActor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
144   mInterceptorActor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
145   mCameraActor.Add( mInterceptorActor );
146
147   // Connect TouchSignal to interceptor actor
148   mInterceptorActor.TouchSignal().Connect( this, &LookCamera::OnTouch );
149 }
150
151 bool LookCamera::OnTouch( Actor actor, const TouchData& touch )
152 {
153   for( int i = 0; i < (int)touch.GetPointCount() && i < 3; ++i )
154   {
155     Vector2 position( touch.GetScreenPosition( i ) );
156
157     // touch started
158     if( touch.GetState( i ) == PointState::STARTED )
159     {
160       mOldTouchLookPosition = position;
161     }
162     else if( touch.GetState( i ) == PointState::FINISHED ||
163              touch.GetState( i ) == PointState::LEAVE ||
164              touch.GetState( i ) == PointState::INTERRUPTED
165              )
166     {
167       mScreenLookDelta = Vector2::ZERO;
168       mOldTouchLookPosition = Vector2::ZERO;
169     }
170     else // on motion
171     {
172       mScreenLookDelta.x += ( position.x - mOldTouchLookPosition.x );
173       mScreenLookDelta.y += ( position.y - mOldTouchLookPosition.y );
174       mOldTouchLookPosition = position;
175     }
176   }
177
178   return true;
179 }