2 * Copyright (c) 2022 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-scene3d/public-api/loader/camera-parameters.h"
18 #include "dali-scene3d/public-api/loader/utils.h"
19 #include "dali/devel-api/actors/camera-actor-devel.h"
20 #include "dali/integration-api/debug.h"
21 #include "dali/public-api/actors/camera-actor.h"
22 #include "dali/public-api/math/quaternion.h"
33 * @brief Creates a perspective matrix.
35 * @param[out] result The perspective matrix.
36 * @param[in] left The coordinate for the left vertical clipping plane.
37 * @param[in] right The coordinate for the right vertical clipping plane.
38 * @param[in] bottom The coordinate for the bottom horizontal clipping plane.
39 * @param[in] top The coordinate for the top horizontal clipping plane.
40 * @param[in] near The distance to the near depth clipping plane.
41 * @param[in] far The distance to the far depth clipping plane.
42 * @param[in] invertYAxis Whether to invert the 'Y' axis.
44 void Frustum(Matrix& result, float left, float right, float bottom, float top, float nearPlane, float farPlane, bool invertYAxis)
46 float deltaZ = farPlane - nearPlane;
47 if((nearPlane <= 0.0f) || (farPlane <= 0.0f) || Equals(right, left) || Equals(bottom, top) || (deltaZ <= 0.0f))
49 DALI_LOG_ERROR("Invalid parameters passed into Frustum!\n");
50 DALI_ASSERT_DEBUG("Invalid parameters passed into Frustum!");
54 float deltaX = right - left;
55 float deltaY = invertYAxis ? bottom - top : top - bottom;
59 float* m = result.AsFloat();
60 m[0] = -2.0f * nearPlane / deltaX;
61 m[1] = m[2] = m[3] = 0.0f;
63 m[5] = -2.0f * nearPlane / deltaY;
64 m[4] = m[6] = m[7] = 0.0f;
66 m[8] = (right + left) / deltaX;
67 m[9] = (top + bottom) / deltaY;
68 m[10] = (nearPlane + farPlane) / deltaZ;
71 m[14] = -2.0f * nearPlane * farPlane / deltaZ;
72 m[12] = m[13] = m[15] = 0.0f;
76 * @brief Creates a perspective projection matrix.
80 * @param[out] result The perspective projection matrix.
81 * @param[in] fovy The vertical field of view.
82 * @param[in] aspect The aspect ratio.
83 * @param[in] nearPlane The distance to the near depth clipping plane.
84 * @param[in] farPlane The distance to the far depth clipping plane.
85 * @param[in] invertYAxis Whether to invert the 'Y' axis.
87 void Perspective(Matrix& result, float fovy, float aspect, float nearPlane, float farPlane, bool invertYAxis)
89 float frustumH = tanf(fovy * 0.5f) * nearPlane;
90 float frustumW = frustumH * aspect;
92 Frustum(result, -frustumW, frustumW, -frustumH, frustumH, nearPlane, farPlane, invertYAxis);
96 * @brief Creates an orthographic projection matrix.
98 * @param[out] result The orthographic projection matrix.
99 * @param[in] left The coordinate for the left vertical clipping plane.
100 * @param[in] right The coordinate for the right vertical clipping plane.
101 * @param[in] bottom The coordinate for the bottom horizontal clipping plane.
102 * @param[in] top The coordinate for the top horizontal clipping plane.
103 * @param[in] nearPlane The distance to the near depth clipping plane.
104 * @param[in] farPlane The distance to the far depth clipping plane.
105 * @param[in] invertYAxis Whether to invert the 'Y' axis.
107 void Orthographic(Matrix& result, float left, float right, float bottom, float top, float nearPlane, float farPlane, bool invertYAxis)
109 if(Equals(right, left) || Equals(top, bottom) || Equals(farPlane, nearPlane))
111 DALI_LOG_ERROR("Cannot create orthographic projection matrix with a zero dimension.\n");
112 DALI_ASSERT_DEBUG("Cannot create orthographic projection matrix with a zero dimension.");
116 float deltaX = right - left;
117 float deltaY = invertYAxis ? bottom - top : top - bottom;
118 float deltaZ = farPlane - nearPlane;
120 float* m = result.AsFloat();
121 m[0] = -2.0f / deltaX;
127 m[5] = -2.0f / deltaY;
133 m[10] = 2.0f / deltaZ;
135 m[12] = -(right + left) / deltaX;
136 m[13] = -(top + bottom) / deltaY;
137 m[14] = -(nearPlane + farPlane) / deltaZ;
143 ViewProjection CameraParameters::GetViewProjection() const
145 ViewProjection viewProjection;
146 // The projection matrix.
149 Perspective(viewProjection.GetProjection(),
150 Radian(Degree(yFov)),
158 Orthographic(viewProjection.GetProjection(),
159 -orthographicSize * aspectRatio,
160 orthographicSize * aspectRatio,
169 const Quaternion viewQuaternion(ANGLE_180, Vector3::YAXIS);
171 Quaternion cameraOrientation;
173 matrix.GetTransformComponents(translation, cameraOrientation, scale);
174 cameraOrientation *= viewQuaternion;
176 viewProjection.GetView().SetInverseTransformComponents(scale,
180 viewProjection.Update();
181 return viewProjection;
184 void CameraParameters::CalculateTransformComponents(Vector3& position, Quaternion& orientation, Vector3& scale) const
186 matrix.GetTransformComponents(position, orientation, scale);
188 // The CameraActor is expected to look down the negative Z axis, towards the scene.
189 // Here we emulate the default direction of the camera in DALi.
190 Quaternion viewQuaternion(ANGLE_180, Vector3::YAXIS);
191 orientation *= viewQuaternion;
194 void CameraParameters::ConfigureCamera(CameraActor& camera) const
196 SetActorCentered(camera);
200 camera.SetProjectionMode(Camera::PERSPECTIVE_PROJECTION);
201 camera.SetNearClippingPlane(zNear);
202 camera.SetFarClippingPlane(zFar);
203 camera.SetFieldOfView(Radian(Degree(yFov)));
207 camera.SetProjectionMode(Camera::ORTHOGRAPHIC_PROJECTION);
208 camera.SetNearClippingPlane(zNear);
209 camera.SetFarClippingPlane(zFar);
210 camera.SetAspectRatio(aspectRatio);
211 camera.SetProperty(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE, orthographicSize);
215 Vector3 camTranslation;
217 Quaternion camOrientation;
218 CalculateTransformComponents(camTranslation, camOrientation, camScale);
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);
226 } // namespace Loader
227 } // namespace Scene3D