Merge "Updated patch coverage script." into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-scene-loader / public-api / camera-parameters.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 #include "dali-scene-loader/public-api/camera-parameters.h"
18 #include "dali-scene-loader/public-api/utils.h"
19 #include "dali/public-api/actors/camera-actor.h"
20 #include "dali/public-api/math/quaternion.h"
21 #include "dali/integration-api/debug.h"
22
23 namespace Dali
24 {
25 namespace SceneLoader
26 {
27 namespace
28 {
29 /**
30  * @brief Creates a perspective matrix.
31  *
32  * @param[out] result The perspective matrix.
33  * @param[in] left The coordinate for the left vertical clipping plane.
34  * @param[in] right The coordinate for the right vertical clipping plane.
35  * @param[in] bottom The coordinate for the bottom horizontal clipping plane.
36  * @param[in] top The coordinate for the top horizontal clipping plane.
37  * @param[in] near The distance to the near depth clipping plane.
38  * @param[in] far The distance to the far depth clipping plane.
39  * @param[in] invertYAxis Whether to invert the 'Y' axis.
40  */
41 void Frustum( Matrix& result, float left, float right, float bottom, float top, float nearPlane, float farPlane, bool invertYAxis )
42 {
43   float deltaZ = farPlane - nearPlane;
44   if ((nearPlane <= 0.0f) || (farPlane <= 0.0f) || Equals(right, left) || Equals(bottom, top) || (deltaZ <= 0.0f))
45   {
46     DALI_LOG_ERROR("Invalid parameters passed into Frustum!\n");
47     DALI_ASSERT_DEBUG("Invalid parameters passed into Frustum!");
48     return;
49   }
50
51   float deltaX = right - left;
52   float deltaY = invertYAxis ? bottom - top : top - bottom;
53
54   result.SetIdentity();
55
56   float* m = result.AsFloat();
57   m[0] = -2.0f * nearPlane / deltaX;
58   m[1] = m[2] = m[3] = 0.0f;
59
60   m[5] = -2.0f * nearPlane / deltaY;
61   m[4] = m[6] = m[7] = 0.0f;
62
63   m[8] = (right + left) / deltaX;
64   m[9] = (top + bottom) / deltaY;
65   m[10] = (nearPlane + farPlane) / deltaZ;
66   m[11] = 1.0f;
67
68   m[14] = -2.0f * nearPlane * farPlane / deltaZ;
69   m[12] = m[13] = m[15] = 0.0f;
70 }
71
72 /**
73  * @brief Creates a perspective projection matrix.
74  *
75  * It calls Frustum()
76  *
77  * @param[out] result The perspective projection matrix.
78  * @param[in] fovy The vertical field of view.
79  * @param[in] aspect The aspect ratio.
80  * @param[in] nearPlane The distance to the near depth clipping plane.
81  * @param[in] farPlane The distance to the far depth clipping plane.
82  * @param[in] invertYAxis Whether to invert the 'Y' axis.
83  */
84 void Perspective( Matrix& result, float fovy, float aspect, float nearPlane, float farPlane, bool invertYAxis )
85 {
86   float frustumH = tanf( fovy * 0.5f ) * nearPlane;
87   float frustumW = frustumH * aspect;
88
89   Frustum( result, -frustumW, frustumW, -frustumH, frustumH, nearPlane, farPlane, invertYAxis );
90 }
91
92 /**
93 * @brief Creates an orthographic projection matrix.
94 *
95 * @param[out] result The orthographic projection matrix.
96 * @param[in] left The coordinate for the left vertical clipping plane.
97 * @param[in] right The coordinate for the right vertical clipping plane.
98 * @param[in] bottom The coordinate for the bottom horizontal clipping plane.
99 * @param[in] top The coordinate for the top horizontal clipping plane.
100 * @param[in] nearPlane The distance to the near depth clipping plane.
101 * @param[in] farPlane The distance to the far depth clipping plane.
102 * @param[in] invertYAxis Whether to invert the 'Y' axis.
103 */
104 void Orthographic(Matrix& result, float left, float right, float bottom, float top, float nearPlane, float farPlane, bool invertYAxis)
105 {
106   if (Equals(right, left) || Equals(top, bottom) || Equals(farPlane, nearPlane))
107   {
108     DALI_LOG_ERROR("Cannot create orthographic projection matrix with a zero dimension.\n");
109     DALI_ASSERT_DEBUG("Cannot create orthographic projection matrix with a zero dimension.");
110     return;
111   }
112
113   float deltaX = right - left;
114   float deltaY = invertYAxis ? bottom - top : top - bottom;
115   float deltaZ = farPlane - nearPlane;
116
117   float *m = result.AsFloat();
118   m[0] = -2.0f / deltaX;
119   m[1] = 0.0f;
120   m[2] = 0.0f;
121   m[3] = 0.0f;
122
123   m[4] = 0.0f;
124   m[5] = -2.0f / deltaY;
125   m[6] = 0.0f;
126   m[7] = 0.0f;
127
128   m[8] = 0.0f;
129   m[9] = 0.0f;
130   m[10] = 2.0f / deltaZ;
131   m[11] = 0.0f;
132   m[12] = -(right + left) / deltaX;
133   m[13] = -(top + bottom) / deltaY;
134   m[14] = -(nearPlane + farPlane) / deltaZ;
135   m[15] = 1.0f;
136 }
137
138 } // nonamespace
139
140 ViewProjection CameraParameters::GetViewProjection() const
141 {
142   ViewProjection viewProjection;
143   // The projection matrix.
144   if (isPerspective)
145   {
146     Perspective(viewProjection.GetProjection(),
147       Radian(Degree(yFov)),
148       1.f,
149       zNear,
150       zFar,
151       true);
152   }
153   else
154   {
155     Orthographic(viewProjection.GetProjection(),
156       orthographicSize.x,
157       orthographicSize.y,
158       orthographicSize.z,
159       orthographicSize.w,
160       zNear,
161       zFar,
162       true);
163
164   }
165
166   // The view matrix.
167   const Quaternion viewQuaternion(ANGLE_180, Vector3::YAXIS);
168   Vector3 translation;
169   Quaternion cameraOrientation;
170   Vector3 scale;
171   matrix.GetTransformComponents(translation, cameraOrientation, scale);
172   cameraOrientation *= viewQuaternion;
173
174   viewProjection.GetView().SetInverseTransformComponents(scale,
175     cameraOrientation,
176     translation);
177
178   viewProjection.Update();
179   return viewProjection;
180 }
181
182 void CameraParameters::CalculateTransformComponents(Vector3 & position, Quaternion & orientation, Vector3 & scale) const
183 {
184   matrix.GetTransformComponents(position, orientation, scale);
185
186   // The CameraActor is expected to look down the negative Z axis, towards the scene.
187   // Here we emulate the default direction of the camera in DALi.
188   Quaternion viewQuaternion(ANGLE_180, Vector3::YAXIS);
189   orientation *= viewQuaternion;
190 }
191
192 void CameraParameters::ConfigureCamera(CameraActor& camera) const
193 {
194   SetActorCentered(camera);
195
196   if (isPerspective)
197   {
198     camera.SetProjectionMode(Camera::PERSPECTIVE_PROJECTION);
199     camera.SetNearClippingPlane(zNear);
200     camera.SetFarClippingPlane(zFar);
201     camera.SetFieldOfView(Radian(Degree(yFov)));
202   }
203   else
204   {
205     camera.SetProjectionMode(Camera::ORTHOGRAPHIC_PROJECTION);
206     camera.SetOrthographicProjection(orthographicSize.x,
207       orthographicSize.y,
208       orthographicSize.z,
209       orthographicSize.w,
210       zNear,
211       zFar);
212   }
213
214   // model
215   Vector3 camTranslation;
216   Vector3 camScale;
217   Quaternion camOrientation;
218   CalculateTransformComponents(camTranslation, camOrientation, camScale);
219
220   camera.SetInvertYAxis(true);
221   camera.SetProperty(Actor::Property::POSITION, camTranslation);
222   camera.SetProperty(Actor::Property::ORIENTATION, camOrientation);
223   camera.SetProperty(Actor::Property::SCALE, camScale);
224 }
225
226 }
227 }