2 * Copyright (c) 2021 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.
17 #include "dali-scene-loader/public-api/camera-parameters.h"
18 #include "dali-scene-loader/public-api/utils.h"
19 #include "dali/integration-api/debug.h"
20 #include "dali/public-api/actors/camera-actor.h"
21 #include "dali/public-api/math/quaternion.h"
30 * @brief Creates a perspective matrix.
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.
41 void Frustum(Matrix& result, float left, float right, float bottom, float top, float nearPlane, float farPlane, bool invertYAxis)
43 float deltaZ = farPlane - nearPlane;
44 if((nearPlane <= 0.0f) || (farPlane <= 0.0f) || Equals(right, left) || Equals(bottom, top) || (deltaZ <= 0.0f))
46 DALI_LOG_ERROR("Invalid parameters passed into Frustum!\n");
47 DALI_ASSERT_DEBUG("Invalid parameters passed into Frustum!");
51 float deltaX = right - left;
52 float deltaY = invertYAxis ? bottom - top : top - bottom;
56 float* m = result.AsFloat();
57 m[0] = -2.0f * nearPlane / deltaX;
58 m[1] = m[2] = m[3] = 0.0f;
60 m[5] = -2.0f * nearPlane / deltaY;
61 m[4] = m[6] = m[7] = 0.0f;
63 m[8] = (right + left) / deltaX;
64 m[9] = (top + bottom) / deltaY;
65 m[10] = (nearPlane + farPlane) / deltaZ;
68 m[14] = -2.0f * nearPlane * farPlane / deltaZ;
69 m[12] = m[13] = m[15] = 0.0f;
73 * @brief Creates a perspective projection matrix.
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.
84 void Perspective(Matrix& result, float fovy, float aspect, float nearPlane, float farPlane, bool invertYAxis)
86 float frustumH = tanf(fovy * 0.5f) * nearPlane;
87 float frustumW = frustumH * aspect;
89 Frustum(result, -frustumW, frustumW, -frustumH, frustumH, nearPlane, farPlane, invertYAxis);
93 * @brief Creates an orthographic projection matrix.
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.
104 void Orthographic(Matrix& result, float left, float right, float bottom, float top, float nearPlane, float farPlane, bool invertYAxis)
106 if(Equals(right, left) || Equals(top, bottom) || Equals(farPlane, nearPlane))
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.");
113 float deltaX = right - left;
114 float deltaY = invertYAxis ? bottom - top : top - bottom;
115 float deltaZ = farPlane - nearPlane;
117 float* m = result.AsFloat();
118 m[0] = -2.0f / deltaX;
124 m[5] = -2.0f / deltaY;
130 m[10] = 2.0f / deltaZ;
132 m[12] = -(right + left) / deltaX;
133 m[13] = -(top + bottom) / deltaY;
134 m[14] = -(nearPlane + farPlane) / deltaZ;
140 ViewProjection CameraParameters::GetViewProjection() const
142 ViewProjection viewProjection;
143 // The projection matrix.
146 Perspective(viewProjection.GetProjection(),
147 Radian(Degree(yFov)),
155 Orthographic(viewProjection.GetProjection(),
166 const Quaternion viewQuaternion(ANGLE_180, Vector3::YAXIS);
168 Quaternion cameraOrientation;
170 matrix.GetTransformComponents(translation, cameraOrientation, scale);
171 cameraOrientation *= viewQuaternion;
173 viewProjection.GetView().SetInverseTransformComponents(scale,
177 viewProjection.Update();
178 return viewProjection;
181 void CameraParameters::CalculateTransformComponents(Vector3& position, Quaternion& orientation, Vector3& scale) const
183 matrix.GetTransformComponents(position, orientation, scale);
185 // The CameraActor is expected to look down the negative Z axis, towards the scene.
186 // Here we emulate the default direction of the camera in DALi.
187 Quaternion viewQuaternion(ANGLE_180, Vector3::YAXIS);
188 orientation *= viewQuaternion;
191 void CameraParameters::ConfigureCamera(CameraActor& camera) const
193 SetActorCentered(camera);
197 camera.SetProjectionMode(Camera::PERSPECTIVE_PROJECTION);
198 camera.SetNearClippingPlane(zNear);
199 camera.SetFarClippingPlane(zFar);
200 camera.SetFieldOfView(Radian(Degree(yFov)));
204 camera.SetProjectionMode(Camera::ORTHOGRAPHIC_PROJECTION);
205 camera.SetOrthographicProjection(orthographicSize.x,
214 Vector3 camTranslation;
216 Quaternion camOrientation;
217 CalculateTransformComponents(camTranslation, camOrientation, camScale);
219 camera.SetInvertYAxis(true);
220 camera.SetProperty(Actor::Property::POSITION, camTranslation);
221 camera.SetProperty(Actor::Property::ORIENTATION, camOrientation);
222 camera.SetProperty(Actor::Property::SCALE, camScale);
225 } // namespace SceneLoader