1 #ifndef DALI_INTERNAL_SCENE_GRAPH_CAMERA_H
2 #define DALI_INTERNAL_SCENE_GRAPH_CAMERA_H
5 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 #include <dali/devel-api/actors/camera-actor-devel.h>
23 #include <dali/internal/common/message.h>
24 #include <dali/internal/common/type-abstraction-enums.h>
25 #include <dali/internal/event/common/event-thread-services.h>
26 #include <dali/internal/update/common/animatable-property.h>
27 #include <dali/internal/update/common/double-buffered.h>
28 #include <dali/internal/update/common/inherited-property.h>
29 #include <dali/internal/update/nodes/node.h>
30 #include <dali/public-api/actors/camera-actor.h>
31 #include <dali/public-api/math/rect.h>
37 // value types used by messages
39 struct ParameterType<Dali::Camera::Type>
40 : public BasicType<Dali::Camera::Type>
44 struct ParameterType<Dali::Camera::ProjectionMode>
45 : public BasicType<Dali::Camera::ProjectionMode>
51 class SceneController;
54 * Scene-graph camera object
56 class Camera : public Node
59 static const Dali::Camera::Type DEFAULT_TYPE;
60 static const Dali::Camera::ProjectionMode DEFAULT_MODE;
61 static const Dali::DevelCameraActor::ProjectionDirection DEFAULT_PROJECTION_DIRECTION;
62 static const bool DEFAULT_INVERT_Y_AXIS;
63 static const float DEFAULT_FIELD_OF_VIEW;
64 static const float DEFAULT_ORTHOGRAPHIC_SIZE;
65 static const float DEFAULT_ASPECT_RATIO;
66 static const float DEFAULT_LEFT_CLIPPING_PLANE;
67 static const float DEFAULT_RIGHT_CLIPPING_PLANE;
68 static const float DEFAULT_TOP_CLIPPING_PLANE;
69 static const float DEFAULT_BOTTOM_CLIPPING_PLANE;
70 static const float DEFAULT_NEAR_CLIPPING_PLANE;
71 static const float DEFAULT_FAR_CLIPPING_PLANE;
72 static const Vector2 DEFAULT_STEREO_BIAS;
73 static const Vector3 DEFAULT_TARGET_POSITION;
76 * Plane equation container for a plane of the view frustum
85 * @brief Container for six planes in a view frustum
94 * Construct a new Camera.
95 * @return a new camera.
105 * Overriden delete operator
106 * Deletes the camera from its global memory pool
108 void operator delete(void* ptr);
111 * @copydoc Dali::Internal::CameraActor::SetType
113 void SetType(Dali::Camera::Type type);
116 * @copydoc Dali::Internal::CameraActor::SetInvertYAxis
118 void SetInvertYAxis(bool invertYAxis);
121 * Returns whether the Y axis is inverted.
122 * @return True if the Y axis is inverted, false otherwise.
124 bool IsYAxisInverted() const
130 * @copydoc Dali::Internal::CameraActor::SetProjectionMode
132 void SetProjectionMode(Dali::Camera::ProjectionMode projectionMode);
135 * @copydoc Dali::Internal::CameraActor::SetProjectionDirection
137 void SetProjectionDirection(Dali::DevelCameraActor::ProjectionDirection direction);
140 * @copydoc Dali::Internal::CameraActor::SetLeftClippingPlane
142 void SetLeftClippingPlane(float leftClippingPlane);
145 * @copydoc Dali::Internal::CameraActor::SetRightClippingPlane
147 void SetRightClippingPlane(float rightClippingPlane);
150 * @copydoc Dali::Internal::CameraActor::SetTopClippingPlane
152 void SetTopClippingPlane(float topClippingPlane);
155 * @copydoc Dali::Internal::CameraActor::SetBottomClippingPlane
157 void SetBottomClippingPlane(float bottomClippingPlane);
160 * @copydoc Dali::Internal::CameraActor::SetNearClippingPlane
162 void SetNearClippingPlane(float nearClippingPlane);
165 * @copydoc Dali::Internal::CameraActor::SetFarClippingPlane
167 void SetFarClippingPlane(float farClippingPlane);
170 * @copydoc Dali::Internal::CameraActor::RotateProjection
172 void RotateProjection(int rotationAngle);
175 * @copydoc Dali::Internal::CameraActor::SetTarget
177 void SetTargetPosition(const Vector3& targetPosition);
180 * @brief Bakes the field of view.
181 * @param[in] updateBufferIndex The current update buffer index.
182 * @param[in] fieldOfView The field of view.
184 void BakeFieldOfView(BufferIndex updateBufferIndex, float fieldOfView);
187 * @brief Retrieve the field of view.
188 * @param[in] bufferIndex The buffer to read from.
189 * @return The field of view.
191 float GetFieldOfView(BufferIndex bufferIndex) const
193 return mFieldOfView[bufferIndex];
197 * @brief Bakes the orthographic size.
198 * @param[in] updateBufferIndex The current update buffer index.
199 * @param[in] orthographicSize The orthographic size.
201 void BakeOrthographicSize(BufferIndex updateBufferIndex, float orthographicSize);
204 * @brief Retrieve the orthographic size.
205 * @param[in] bufferIndex The buffer to read from.
206 * @return The orthographic size.
208 float GetOrthographicSize(BufferIndex bufferIndex) const
210 return mOrthographicSize[bufferIndex];
214 * @brief Bakes the aspect ratio.
215 * @param[in] updateBufferIndex The current update buffer index.
216 * @param[in] aspectRatio The aspect ratio.
218 void BakeAspectRatio(BufferIndex updateBufferIndex, float aspectRatio);
221 * @brief Retrieve the aspect ratio.
222 * @param[in] bufferIndex The buffer to read from.
223 * @return The aspect ratio.
225 float GetAspectRatio(BufferIndex bufferIndex) const
227 return mAspectRatio[bufferIndex];
231 * Sets the reflection plane
232 * @param[in] plane reflection plane
234 void SetReflectByPlane(const Vector4& plane);
237 * Tests whether reflection is used
238 * @return True if used, False otherwise
240 bool GetReflectionUsed() const
242 return mUseReflection;
246 * Retrieve the view-matrix; this is double buffered for input handling.
247 * @param[in] bufferIndex The buffer to read from.
248 * @return The view-matrix.
250 const Matrix& GetViewMatrix(BufferIndex bufferIndex) const;
253 * @brief Check to see if a sphere lies within the view frustum.
255 * @param bufferIndex The buffer to read from.
256 * @param origin The world position center of the sphere to check.
257 * @param radius The length of the sphere radius in world scale.
259 * @return false if the sphere lies outside of the frustum.
261 bool CheckSphereInFrustum(BufferIndex bufferIndex, const Vector3& origin, float radius) const;
264 * @brief Check to see if a bounding box lies within the view frustum.
266 * @param bufferIndex The buffer to read from.
267 * @param origin the world position center of the cubeoid to check.
268 * @param halfExtents The half length of the cubeoid in world co-ordinates in each axis.
270 * @return false if the cubeoid lies completely outside of the frustum, true otherwise
272 bool CheckAABBInFrustum(BufferIndex bufferIndex, const Vector3& origin, const Vector3& halfExtents) const;
275 * @brief Calculate orthographic clipping box by this camera's orthographic size.
277 Dali::Rect<int32_t> GetOrthographicClippingBox(BufferIndex bufferIndex) const;
280 * Retrieve the projection-matrix; this is double buffered for input handling.
281 * @param[in] bufferIndex The buffer to read from.
282 * @return The projection-matrix.
284 const Matrix& GetProjectionMatrix(BufferIndex bufferIndex) const;
287 * Retrieve the inverted view-projection-matrix; this is double buffered for input handling.
288 * @param[in] bufferIndex The buffer to read from.
289 * @return The inverse view-projection-matrix.
291 const Matrix& GetInverseViewProjectionMatrix(BufferIndex bufferIndex) const;
294 * Retrieve the final projection-matrix; this is double buffered for input handling.
295 * @param[in] bufferIndex The buffer to read from.
296 * @return The projection-matrix that should be used to render.
298 const Matrix& GetFinalProjectionMatrix(BufferIndex bufferIndex) const;
301 * Retrieve the field of view property querying interface.
302 * @pre The camera is on-stage.
303 * @return The field of view property querying interface.
305 const PropertyBase* GetFieldOfView() const;
308 * Retrieve the orthographic size property querying interface.
309 * @pre The camera is on-stage.
310 * @return The orthographic size property querying interface.
312 const PropertyBase* GetOrthographicSize() const;
315 * Retrieve the aspect ratio property querying interface.
316 * @pre The camera is on-stage.
317 * @return The aspect ratio property querying interface.
319 const PropertyBase* GetAspectRatio() const;
322 * Retrieve the projection-matrix property querying interface.
323 * @pre The camera is on-stage.
324 * @return The projection-matrix property querying interface.
326 const PropertyInputImpl* GetProjectionMatrix() const;
329 * Retrieve the viewMatrix property querying interface.
330 * @pre The camera is on-stage.
331 * @return The viewMatrix property querying interface.
333 const PropertyInputImpl* GetViewMatrix() const;
336 * Updates view and projection matrices.
337 * Called by the render task using the camera
338 * @param[in] updateBufferIndex The buffer to read from.
340 void Update(BufferIndex updateBufferIndex);
343 * @return true if the view matrix of camera is updated this or the previous frame
345 bool ViewMatrixUpdated() const;
348 * @return true if the projection matrix projection matrix relative properties are animated this or the previous frame
350 bool IsProjectionMatrixAnimated() const;
358 // Delete copy and move
359 Camera(const Camera&) = delete;
360 Camera(Camera&&) = delete;
361 Camera& operator=(const Camera& rhs) = delete;
362 Camera& operator=(Camera&& rhs) = delete;
365 * Recalculates the view matrix.
366 * @param[in] bufferIndex The current update buffer index.
367 * @return count how many frames ago the matrix was changed.
369 uint32_t UpdateViewMatrix(BufferIndex updateBufferIndex);
372 * Recalculates the projection matrix.
373 * @param[in] bufferIndex The current update buffer index.
374 * @return count how many frames ago the matrix was changed.
376 uint32_t UpdateProjection(BufferIndex updateBufferIndex);
380 * @brief Extracts the frustum planes.
382 * @param[in] bufferIndex The current update buffer index.
383 * @param[in] normalize will normalize plane equation coefficients by default.
385 void UpdateFrustum(BufferIndex updateBufferIndex, bool normalize = true);
388 * Adjust near plane for reflection
389 * @param perspective Perspective matrix
390 * @param clipPlane Clipping plane
392 void AdjustNearPlaneForPerspective(Matrix& perspective, const Vector4& clipPlane);
394 uint32_t mUpdateViewFlag; ///< This is non-zero if the view matrix requires an update
395 uint32_t mUpdateProjectionFlag; ///< This is non-zero if the projection matrix requires an update
396 int mProjectionRotation; ///< The rotaion angle of the projection
398 public: // PROPERTIES
399 Dali::Camera::Type mType; // Non-animatable
400 Dali::Camera::ProjectionMode mProjectionMode; // Non-animatable
401 Dali::DevelCameraActor::ProjectionDirection mProjectionDirection; // Non-animatable
402 bool mInvertYAxis; // Non-animatable
404 AnimatableProperty<float> mFieldOfView; // Animatable
405 AnimatableProperty<float> mOrthographicSize; // Animatable
406 AnimatableProperty<float> mAspectRatio; // Animatable
408 float mNearClippingPlane;
409 float mFarClippingPlane;
410 Vector3 mTargetPosition;
412 Dali::Matrix mReflectionMtx;
413 Dali::Vector4 mReflectionPlane;
414 Dali::Vector4 mReflectionEye;
415 bool mUseReflection{false};
416 bool mUseReflectionClip{false};
418 InheritedMatrix mViewMatrix; ///< The viewMatrix; this is double buffered for input handling.
419 InheritedMatrix mProjectionMatrix; ///< The projectionMatrix; this is double buffered for input handling.
421 DoubleBuffered<FrustumPlanes> mFrustum; ///< Clipping frustum; double buffered for input handling
422 DoubleBuffered<Matrix> mInverseViewProjection; ///< Inverted viewprojection; double buffered for input handling
423 DoubleBuffered<Matrix> mFinalProjection; ///< Final projection matrix; double buffered for input handling
426 // Messages for Camera
428 inline void SetTypeMessage(EventThreadServices& eventThreadServices, const Camera& camera, Dali::Camera::Type parameter)
430 using LocalType = MessageValue1<Camera, Dali::Camera::Type>;
432 // Reserve some memory inside the message queue
433 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
435 // Construct message in the message queue memory; note that delete should not be called on the return value
436 new(slot) LocalType(&camera, &Camera::SetType, parameter);
439 inline void SetProjectionModeMessage(EventThreadServices& eventThreadServices, const Camera& camera, Dali::Camera::ProjectionMode parameter)
441 using LocalProjectionMode = MessageValue1<Camera, Dali::Camera::ProjectionMode>;
443 // Reserve some memory inside the message queue
444 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalProjectionMode));
446 // Construct message in the message queue memory; note that delete should not be called on the return value
447 new(slot) LocalProjectionMode(&camera, &Camera::SetProjectionMode, parameter);
450 inline void SetProjectionDirectionMessage(EventThreadServices& eventThreadServices, const Camera& camera, Dali::DevelCameraActor::ProjectionDirection parameter)
452 using LocalProjectionDirection = MessageValue1<Camera, Dali::DevelCameraActor::ProjectionDirection>;
454 // Reserve some memory inside the message queue
455 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalProjectionDirection));
457 // Construct message in the message queue memory; note that delete should not be called on the return value
458 new(slot) LocalProjectionDirection(&camera, &Camera::SetProjectionDirection, parameter);
461 inline void BakeFieldOfViewMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
463 using LocalType = MessageDoubleBuffered1<Camera, float>;
465 // Reserve some memory inside the message queue
466 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
468 // Construct message in the message queue memory; note that delete should not be called on the return value
469 new(slot) LocalType(&camera, &Camera::BakeFieldOfView, parameter);
472 inline void BakeOrthographicSizeMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
474 using LocalType = MessageDoubleBuffered1<Camera, float>;
476 // Reserve some memory inside the message queue
477 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
479 // Construct message in the message queue memory; note that delete should not be called on the return value
480 new(slot) LocalType(&camera, &Camera::BakeOrthographicSize, parameter);
483 inline void BakeAspectRatioMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
485 using LocalType = MessageDoubleBuffered1<Camera, float>;
487 // Reserve some memory inside the message queue
488 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
490 // Construct message in the message queue memory; note that delete should not be called on the return value
491 new(slot) LocalType(&camera, &Camera::BakeAspectRatio, parameter);
494 inline void SetNearClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
496 using LocalType = MessageValue1<Camera, float>;
498 // Reserve some memory inside the message queue
499 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
501 // Construct message in the message queue memory; note that delete should not be called on the return value
502 new(slot) LocalType(&camera, &Camera::SetNearClippingPlane, parameter);
505 inline void SetFarClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
507 using LocalType = MessageValue1<Camera, float>;
509 // Reserve some memory inside the message queue
510 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
512 // Construct message in the message queue memory; note that delete should not be called on the return value
513 new(slot) LocalType(&camera, &Camera::SetFarClippingPlane, parameter);
516 inline void SetReflectByPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, const Vector4& plane)
518 using LocalType = MessageValue1<Camera, Vector4>;
520 // Reserve some memory inside the message queue
521 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
523 // Construct message in the message queue memory; note that delete should not be called on the return value
524 new(slot) LocalType(&camera, &Camera::SetReflectByPlane, plane);
527 inline void SetTargetPositionMessage(EventThreadServices& eventThreadServices, const Camera& camera, const Vector3& parameter)
529 using LocalType = MessageValue1<Camera, Vector3>;
531 // Reserve some memory inside the message queue
532 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
534 // Construct message in the message queue memory; note that delete should not be called on the return value
535 new(slot) LocalType(&camera, &Camera::SetTargetPosition, parameter);
538 inline void SetInvertYAxisMessage(EventThreadServices& eventThreadServices, const Camera& camera, bool parameter)
540 using LocalType = MessageValue1<Camera, bool>;
542 // Reserve some memory inside the message queue
543 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
545 // Construct message in the message queue memory; note that delete should not be called on the return value
546 new(slot) LocalType(&camera, &Camera::SetInvertYAxis, parameter);
549 inline void RotateProjectionMessage(EventThreadServices& eventThreadServices, const Camera& camera, int parameter)
551 typedef MessageValue1<Camera, int> LocalType;
553 // Reserve some memory inside the message queue
554 unsigned int* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
556 // Construct message in the message queue memory; note that delete should not be called on the return value
557 new(slot) LocalType(&camera, &Camera::RotateProjection, parameter);
560 } // namespace SceneGraph
562 } // namespace Internal
566 #endif // DALI_INTERNAL_SCENE_GRAPH_CAMERA_H