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/integration-api/debug.h"
20 #include "dali/public-api/actors/camera-actor.h"
21 #include "dali/public-api/math/quaternion.h"
32 * @brief Creates a perspective matrix.
34 * @param[out] result The perspective matrix.
35 * @param[in] left The coordinate for the left vertical clipping plane.
36 * @param[in] right The coordinate for the right vertical clipping plane.
37 * @param[in] bottom The coordinate for the bottom horizontal clipping plane.
38 * @param[in] top The coordinate for the top horizontal clipping plane.
39 * @param[in] near The distance to the near depth clipping plane.
40 * @param[in] far The distance to the far depth clipping plane.
41 * @param[in] invertYAxis Whether to invert the 'Y' axis.
43 void Frustum(Matrix& result, float left, float right, float bottom, float top, float nearPlane, float farPlane, bool invertYAxis)
45 float deltaZ = farPlane - nearPlane;
46 if((nearPlane <= 0.0f) || (farPlane <= 0.0f) || Equals(right, left) || Equals(bottom, top) || (deltaZ <= 0.0f))
48 DALI_LOG_ERROR("Invalid parameters passed into Frustum!\n");
49 DALI_ASSERT_DEBUG("Invalid parameters passed into Frustum!");
53 float deltaX = right - left;
54 float deltaY = invertYAxis ? bottom - top : top - bottom;
58 float* m = result.AsFloat();
59 m[0] = -2.0f * nearPlane / deltaX;
60 m[1] = m[2] = m[3] = 0.0f;
62 m[5] = -2.0f * nearPlane / deltaY;
63 m[4] = m[6] = m[7] = 0.0f;
65 m[8] = (right + left) / deltaX;
66 m[9] = (top + bottom) / deltaY;
67 m[10] = (nearPlane + farPlane) / deltaZ;
70 m[14] = -2.0f * nearPlane * farPlane / deltaZ;
71 m[12] = m[13] = m[15] = 0.0f;
75 * @brief Creates a perspective projection matrix.
79 * @param[out] result The perspective projection matrix.
80 * @param[in] fovy The vertical field of view.
81 * @param[in] aspect The aspect ratio.
82 * @param[in] nearPlane The distance to the near depth clipping plane.
83 * @param[in] farPlane The distance to the far depth clipping plane.
84 * @param[in] invertYAxis Whether to invert the 'Y' axis.
86 void Perspective(Matrix& result, float fovy, float aspect, float nearPlane, float farPlane, bool invertYAxis)
88 float frustumH = tanf(fovy * 0.5f) * nearPlane;
89 float frustumW = frustumH * aspect;
91 Frustum(result, -frustumW, frustumW, -frustumH, frustumH, nearPlane, farPlane, invertYAxis);
95 * @brief Creates an orthographic projection matrix.
97 * @param[out] result The orthographic projection matrix.
98 * @param[in] left The coordinate for the left vertical clipping plane.
99 * @param[in] right The coordinate for the right vertical clipping plane.
100 * @param[in] bottom The coordinate for the bottom horizontal clipping plane.
101 * @param[in] top The coordinate for the top horizontal clipping plane.
102 * @param[in] nearPlane The distance to the near depth clipping plane.
103 * @param[in] farPlane The distance to the far depth clipping plane.
104 * @param[in] invertYAxis Whether to invert the 'Y' axis.
106 void Orthographic(Matrix& result, float left, float right, float bottom, float top, float nearPlane, float farPlane, bool invertYAxis)
108 if(Equals(right, left) || Equals(top, bottom) || Equals(farPlane, nearPlane))
110 DALI_LOG_ERROR("Cannot create orthographic projection matrix with a zero dimension.\n");
111 DALI_ASSERT_DEBUG("Cannot create orthographic projection matrix with a zero dimension.");
115 float deltaX = right - left;
116 float deltaY = invertYAxis ? bottom - top : top - bottom;
117 float deltaZ = farPlane - nearPlane;
119 float* m = result.AsFloat();
120 m[0] = -2.0f / deltaX;
126 m[5] = -2.0f / deltaY;
132 m[10] = 2.0f / deltaZ;
134 m[12] = -(right + left) / deltaX;
135 m[13] = -(top + bottom) / deltaY;
136 m[14] = -(nearPlane + farPlane) / deltaZ;
142 ViewProjection CameraParameters::GetViewProjection() const
144 ViewProjection viewProjection;
145 // The projection matrix.
148 Perspective(viewProjection.GetProjection(),
149 Radian(Degree(yFov)),
157 Orthographic(viewProjection.GetProjection(),
168 const Quaternion viewQuaternion(ANGLE_180, Vector3::YAXIS);
170 Quaternion cameraOrientation;
172 matrix.GetTransformComponents(translation, cameraOrientation, scale);
173 cameraOrientation *= viewQuaternion;
175 viewProjection.GetView().SetInverseTransformComponents(scale,
179 viewProjection.Update();
180 return viewProjection;
183 void CameraParameters::CalculateTransformComponents(Vector3& position, Quaternion& orientation, Vector3& scale) const
185 matrix.GetTransformComponents(position, orientation, scale);
187 // The CameraActor is expected to look down the negative Z axis, towards the scene.
188 // Here we emulate the default direction of the camera in DALi.
189 Quaternion viewQuaternion(ANGLE_180, Vector3::YAXIS);
190 orientation *= viewQuaternion;
193 void CameraParameters::ConfigureCamera(CameraActor& camera) const
195 SetActorCentered(camera);
199 camera.SetProjectionMode(Camera::PERSPECTIVE_PROJECTION);
200 camera.SetNearClippingPlane(zNear);
201 camera.SetFarClippingPlane(zFar);
202 camera.SetFieldOfView(Radian(Degree(yFov)));
206 camera.SetProjectionMode(Camera::ORTHOGRAPHIC_PROJECTION);
207 camera.SetOrthographicProjection(orthographicSize.x,
216 Vector3 camTranslation;
218 Quaternion camOrientation;
219 CalculateTransformComponents(camTranslation, camOrientation, camScale);
221 camera.SetInvertYAxis(true);
222 camera.SetProperty(Actor::Property::POSITION, camTranslation);
223 camera.SetProperty(Actor::Property::ORIENTATION, camOrientation);
224 camera.SetProperty(Actor::Property::SCALE, camScale);
227 } // namespace Loader
228 } // namespace Scene3D