2 * Copyright (c) 2020 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 "look-camera.h"
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>
29 // Input sensitivity, the larger value, the more sensitive input
30 // Default value has been chosen empirically
31 const float CAMERA_SENSITIVITY ( 90.0f );
33 // Vertical angle limit of the camera
34 const float CAMERA_VERTICAL_LIMIT ( 80.0f );
36 // Position where camera is instantiated by default
37 const Vector3 CAMERA_DEFAULT_POSITION ( 0.0f, 0.0f, 3.0f );
39 // Field-of-View in degrees
40 const float CAMERA_DEFAULT_FOV ( 60.0f );
43 const float CAMERA_DEFAULT_NEAR ( 0.1f );
46 const float CAMERA_DEFAULT_FAR ( 100.0f );
48 // Default forward vector
49 const Vector3 CAMERA_FORWARD ( 0.0f, 0.0f, 1.0f );
52 const Vector3 CAMERA_UP ( Vector3::YAXIS );
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 )
64 LookCamera::~LookCamera()
67 mCameraActor.Remove( mInterceptorActor );
70 void LookCamera::Initialise( Window window, const Vector3& position, float fovY, float near, float far )
78 // Camera position is shadowed in order to avoid using.GetCurrentProperty< Vector3 >( Actor::Property::POSITION )
79 mCameraPosition = position;
81 // Initialise default camera
82 InitialiseDefaultCamera();
84 // Create input interceptor actor
85 CreateInterceptorActor();
88 mTimer = Timer::New( 16 );
89 mTimer.TickSignal().Connect( this, &LookCamera::OnTick );
93 bool LookCamera::OnTick()
95 Vector2 windowSize = mWindow.GetSize();
97 // ---------------------------------------------------------------------
99 Vector2 tmp( mScreenLookDelta );
100 mScreenLookDelta = Vector2::ZERO;
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 )
108 mCameraYawPitch.x = CAMERA_VERTICAL_LIMIT * ((mCameraYawPitch.x < 0) ? -1.0f : 1.0f );
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 );
116 mCameraActor.SetProperty( Actor::Property::ORIENTATION, rotation );
121 void LookCamera::InitialiseDefaultCamera()
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 ) ) );
129 // should be read from file
130 mCameraActor.SetNearClippingPlane( mNear );
131 mCameraActor.SetFarClippingPlane( mFar );
132 mCameraActor.SetProperty( Actor::Property::POSITION, mCameraPosition );
135 void LookCamera::CreateInterceptorActor()
137 Vector2 windowSize = mWindow.GetSize();
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 );
147 // Connect TouchSignal to interceptor actor
148 mInterceptorActor.TouchSignal().Connect( this, &LookCamera::OnTouch );
151 bool LookCamera::OnTouch( Actor actor, const TouchData& touch )
153 for( int i = 0; i < (int)touch.GetPointCount() && i < 3; ++i )
155 Vector2 position( touch.GetScreenPosition( i ) );
158 if( touch.GetState( i ) == PointState::STARTED )
160 mOldTouchLookPosition = position;
162 else if( touch.GetState( i ) == PointState::FINISHED ||
163 touch.GetState( i ) == PointState::LEAVE ||
164 touch.GetState( i ) == PointState::INTERRUPTED
167 mScreenLookDelta = Vector2::ZERO;
168 mOldTouchLookPosition = Vector2::ZERO;
172 mScreenLookDelta.x += ( position.x - mOldTouchLookPosition.x );
173 mScreenLookDelta.y += ( position.y - mOldTouchLookPosition.y );
174 mOldTouchLookPosition = position;