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_ASPECT_RATIO;
65 static const float DEFAULT_LEFT_CLIPPING_PLANE;
66 static const float DEFAULT_RIGHT_CLIPPING_PLANE;
67 static const float DEFAULT_TOP_CLIPPING_PLANE;
68 static const float DEFAULT_BOTTOM_CLIPPING_PLANE;
69 static const float DEFAULT_NEAR_CLIPPING_PLANE;
70 static const float DEFAULT_FAR_CLIPPING_PLANE;
71 static const Vector2 DEFAULT_STEREO_BIAS;
72 static const Vector3 DEFAULT_TARGET_POSITION;
75 * Plane equation container for a plane of the view frustum
84 * @brief Container for six planes in a view frustum
93 * Construct a new Camera.
94 * @return a new camera.
104 * Overriden delete operator
105 * Deletes the camera from its global memory pool
107 void operator delete(void* ptr);
110 * @copydoc Dali::Internal::CameraActor::SetType
112 void SetType(Dali::Camera::Type type);
115 * @copydoc Dali::Internal::CameraActor::SetInvertYAxis
117 void SetInvertYAxis(bool invertYAxis);
120 * Returns whether the Y axis is inverted.
121 * @return True if the Y axis is inverted, false otherwise.
123 bool IsYAxisInverted() const
129 * @copydoc Dali::Internal::CameraActor::SetProjectionMode
131 void SetProjectionMode(Dali::Camera::ProjectionMode projectionMode);
134 * @copydoc Dali::Internal::CameraActor::SetProjectionDirection
136 void SetProjectionDirection(Dali::DevelCameraActor::ProjectionDirection direction);
139 * @copydoc Dali::Internal::CameraActor::SetAspectRatio
141 void SetAspectRatio(float aspectRatio);
144 * @copydoc Dali::Internal::CameraActor::SetLeftClippingPlane
146 void SetLeftClippingPlane(float leftClippingPlane);
149 * @copydoc Dali::Internal::CameraActor::SetRightClippingPlane
151 void SetRightClippingPlane(float rightClippingPlane);
154 * @copydoc Dali::Internal::CameraActor::SetTopClippingPlane
156 void SetTopClippingPlane(float topClippingPlane);
159 * @copydoc Dali::Internal::CameraActor::SetBottomClippingPlane
161 void SetBottomClippingPlane(float bottomClippingPlane);
164 * @copydoc Dali::Internal::CameraActor::SetNearClippingPlane
166 void SetNearClippingPlane(float nearClippingPlane);
169 * @copydoc Dali::Internal::CameraActor::SetFarClippingPlane
171 void SetFarClippingPlane(float farClippingPlane);
174 * @copydoc Dali::Internal::CameraActor::RotateProjection
176 void RotateProjection(int rotationAngle);
179 * @copydoc Dali::Internal::CameraActor::SetTarget
181 void SetTargetPosition(const Vector3& targetPosition);
184 * @brief Bakes the field of view.
185 * @param[in] updateBufferIndex The current update buffer index.
186 * @param[in] opacity The field of view.
188 void BakeFieldOfView(BufferIndex updateBufferIndex, float fieldOfView);
191 * @brief Retrieve the field of view.
192 * @param[in] bufferIndex The buffer to read from.
193 * @return The field of view.
195 float GetFieldOfView(BufferIndex bufferIndex) const
197 return mFieldOfView[bufferIndex];
201 * Sets the reflection plane
202 * @param[in] plane reflection plane
204 void SetReflectByPlane(const Vector4& plane);
207 * Tests whether reflection is used
208 * @return True if used, False otherwise
210 bool GetReflectionUsed() const
212 return mUseReflection;
216 * Retrieve the view-matrix; this is double buffered for input handling.
217 * @param[in] bufferIndex The buffer to read from.
218 * @return The view-matrix.
220 const Matrix& GetViewMatrix(BufferIndex bufferIndex) const;
223 * @brief Check to see if a sphere lies within the view frustum.
225 * @param bufferIndex The buffer to read from.
226 * @param origin The world position center of the sphere to check.
227 * @param radius The length of the sphere radius in world scale.
229 * @return false if the sphere lies outside of the frustum.
231 bool CheckSphereInFrustum(BufferIndex bufferIndex, const Vector3& origin, float radius) const;
234 * @brief Check to see if a bounding box lies within the view frustum.
236 * @param bufferIndex The buffer to read from.
237 * @param origin the world position center of the cubeoid to check.
238 * @param halfExtents The half length of the cubeoid in world co-ordinates in each axis.
240 * @return false if the cubeoid lies completely outside of the frustum, true otherwise
242 bool CheckAABBInFrustum(BufferIndex bufferIndex, const Vector3& origin, const Vector3& halfExtents) const;
245 * Retrieve the projection-matrix; this is double buffered for input handling.
246 * @param[in] bufferIndex The buffer to read from.
247 * @return The projection-matrix.
249 const Matrix& GetProjectionMatrix(BufferIndex bufferIndex) const;
252 * Retrieve the inverted view-projection-matrix; this is double buffered for input handling.
253 * @param[in] bufferIndex The buffer to read from.
254 * @return The inverse view-projection-matrix.
256 const Matrix& GetInverseViewProjectionMatrix(BufferIndex bufferIndex) const;
259 * Retrieve the final projection-matrix; this is double buffered for input handling.
260 * @param[in] bufferIndex The buffer to read from.
261 * @return The projection-matrix that should be used to render.
263 const Matrix& GetFinalProjectionMatrix(BufferIndex bufferIndex) const;
266 * Retrieve the field of view property querying interface.
267 * @pre The camera is on-stage.
268 * @return The field of view property querying interface.
270 const PropertyBase* GetFieldOfView() const;
273 * Retrieve the projection-matrix property querying interface.
274 * @pre The camera is on-stage.
275 * @return The projection-matrix property querying interface.
277 const PropertyInputImpl* GetProjectionMatrix() const;
280 * Retrieve the viewMatrix property querying interface.
281 * @pre The camera is on-stage.
282 * @return The viewMatrix property querying interface.
284 const PropertyInputImpl* GetViewMatrix() const;
287 * Updates view and projection matrices.
288 * Called by the render task using the camera
289 * @param[in] updateBufferIndex The buffer to read from.
291 void Update(BufferIndex updateBufferIndex);
294 * @return true if the view matrix of camera is updated this or the previous frame
296 bool ViewMatrixUpdated() const;
299 * @return true if the projection matrix projection matrix relative properties are animated this or the previous frame
301 bool IsProjectionMatrixAnimated() const;
309 // Delete copy and move
310 Camera(const Camera&) = delete;
311 Camera(Camera&&) = delete;
312 Camera& operator=(const Camera& rhs) = delete;
313 Camera& operator=(Camera&& rhs) = delete;
316 * Recalculates the view matrix.
317 * @param[in] bufferIndex The current update buffer index.
318 * @return count how many frames ago the matrix was changed.
320 uint32_t UpdateViewMatrix(BufferIndex updateBufferIndex);
323 * Recalculates the projection matrix.
324 * @param[in] bufferIndex The current update buffer index.
325 * @return count how many frames ago the matrix was changed.
327 uint32_t UpdateProjection(BufferIndex updateBufferIndex);
331 * @brief Extracts the frustum planes.
333 * @param[in] bufferIndex The current update buffer index.
334 * @param[in] normalize will normalize plane equation coefficients by default.
336 void UpdateFrustum(BufferIndex updateBufferIndex, bool normalize = true);
339 * Adjust near plane for reflection
340 * @param perspective Perspective matrix
341 * @param clipPlane Clipping plane
343 void AdjustNearPlaneForPerspective(Matrix& perspective, const Vector4& clipPlane);
345 uint32_t mUpdateViewFlag; ///< This is non-zero if the view matrix requires an update
346 uint32_t mUpdateProjectionFlag; ///< This is non-zero if the projection matrix requires an update
347 int mProjectionRotation; ///< The rotaion angle of the projection
349 public: // PROPERTIES
350 Dali::Camera::Type mType; // Non-animatable
351 Dali::Camera::ProjectionMode mProjectionMode; // Non-animatable
352 Dali::DevelCameraActor::ProjectionDirection mProjectionDirection; // Non-animatable
353 bool mInvertYAxis; // Non-animatable
355 AnimatableProperty<float> mFieldOfView; // Animatable
358 float mLeftClippingPlane;
359 float mRightClippingPlane;
360 float mTopClippingPlane;
361 float mBottomClippingPlane;
362 float mNearClippingPlane;
363 float mFarClippingPlane;
364 Vector3 mTargetPosition;
366 Dali::Matrix mReflectionMtx;
367 Dali::Vector4 mReflectionPlane;
368 Dali::Vector4 mReflectionEye;
369 bool mUseReflection{false};
370 bool mUseReflectionClip{false};
372 InheritedMatrix mViewMatrix; ///< The viewMatrix; this is double buffered for input handling.
373 InheritedMatrix mProjectionMatrix; ///< The projectionMatrix; this is double buffered for input handling.
375 DoubleBuffered<FrustumPlanes> mFrustum; ///< Clipping frustum; double buffered for input handling
376 DoubleBuffered<Matrix> mInverseViewProjection; ///< Inverted viewprojection; double buffered for input handling
377 DoubleBuffered<Matrix> mFinalProjection; ///< Final projection matrix; double buffered for input handling
380 // Messages for Camera
382 inline void SetTypeMessage(EventThreadServices& eventThreadServices, const Camera& camera, Dali::Camera::Type parameter)
384 using LocalType = MessageValue1<Camera, Dali::Camera::Type>;
386 // Reserve some memory inside the message queue
387 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
389 // Construct message in the message queue memory; note that delete should not be called on the return value
390 new(slot) LocalType(&camera, &Camera::SetType, parameter);
393 inline void SetProjectionModeMessage(EventThreadServices& eventThreadServices, const Camera& camera, Dali::Camera::ProjectionMode parameter)
395 using LocalProjectionMode = MessageValue1<Camera, Dali::Camera::ProjectionMode>;
397 // Reserve some memory inside the message queue
398 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalProjectionMode));
400 // Construct message in the message queue memory; note that delete should not be called on the return value
401 new(slot) LocalProjectionMode(&camera, &Camera::SetProjectionMode, parameter);
404 inline void SetProjectionDirectionMessage(EventThreadServices& eventThreadServices, const Camera& camera, Dali::DevelCameraActor::ProjectionDirection parameter)
406 using LocalProjectionDirection = MessageValue1<Camera, Dali::DevelCameraActor::ProjectionDirection>;
408 // Reserve some memory inside the message queue
409 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalProjectionDirection));
411 // Construct message in the message queue memory; note that delete should not be called on the return value
412 new(slot) LocalProjectionDirection(&camera, &Camera::SetProjectionDirection, parameter);
415 inline void BakeFieldOfViewMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
417 using LocalType = MessageDoubleBuffered1<Camera, float>;
419 // Reserve some memory inside the message queue
420 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
422 // Construct message in the message queue memory; note that delete should not be called on the return value
423 new(slot) LocalType(&camera, &Camera::BakeFieldOfView, parameter);
426 inline void SetAspectRatioMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
428 using LocalType = MessageValue1<Camera, float>;
430 // Reserve some memory inside the message queue
431 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
433 // Construct message in the message queue memory; note that delete should not be called on the return value
434 new(slot) LocalType(&camera, &Camera::SetAspectRatio, parameter);
437 inline void SetLeftClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
439 using LocalType = MessageValue1<Camera, float>;
441 // Reserve some memory inside the message queue
442 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
444 // Construct message in the message queue memory; note that delete should not be called on the return value
445 new(slot) LocalType(&camera, &Camera::SetLeftClippingPlane, parameter);
448 inline void SetRightClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
450 using LocalType = MessageValue1<Camera, float>;
452 // Reserve some memory inside the message queue
453 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
455 // Construct message in the message queue memory; note that delete should not be called on the return value
456 new(slot) LocalType(&camera, &Camera::SetRightClippingPlane, parameter);
459 inline void SetTopClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
461 using LocalType = MessageValue1<Camera, float>;
463 // Reserve some memory inside the message queue
464 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
466 // Construct message in the message queue memory; note that delete should not be called on the return value
467 new(slot) LocalType(&camera, &Camera::SetTopClippingPlane, parameter);
470 inline void SetBottomClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
472 using LocalType = MessageValue1<Camera, float>;
474 // Reserve some memory inside the message queue
475 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
477 // Construct message in the message queue memory; note that delete should not be called on the return value
478 new(slot) LocalType(&camera, &Camera::SetBottomClippingPlane, parameter);
481 inline void SetNearClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
483 using LocalType = MessageValue1<Camera, float>;
485 // Reserve some memory inside the message queue
486 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
488 // Construct message in the message queue memory; note that delete should not be called on the return value
489 new(slot) LocalType(&camera, &Camera::SetNearClippingPlane, parameter);
492 inline void SetFarClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
494 using LocalType = MessageValue1<Camera, float>;
496 // Reserve some memory inside the message queue
497 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
499 // Construct message in the message queue memory; note that delete should not be called on the return value
500 new(slot) LocalType(&camera, &Camera::SetFarClippingPlane, parameter);
503 inline void SetReflectByPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, const Vector4& plane)
505 using LocalType = MessageValue1<Camera, Vector4>;
507 // Reserve some memory inside the message queue
508 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
510 // Construct message in the message queue memory; note that delete should not be called on the return value
511 new(slot) LocalType(&camera, &Camera::SetReflectByPlane, plane);
514 inline void SetTargetPositionMessage(EventThreadServices& eventThreadServices, const Camera& camera, const Vector3& parameter)
516 using LocalType = MessageValue1<Camera, Vector3>;
518 // Reserve some memory inside the message queue
519 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
521 // Construct message in the message queue memory; note that delete should not be called on the return value
522 new(slot) LocalType(&camera, &Camera::SetTargetPosition, parameter);
525 inline void SetInvertYAxisMessage(EventThreadServices& eventThreadServices, const Camera& camera, bool parameter)
527 using LocalType = MessageValue1<Camera, bool>;
529 // Reserve some memory inside the message queue
530 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
532 // Construct message in the message queue memory; note that delete should not be called on the return value
533 new(slot) LocalType(&camera, &Camera::SetInvertYAxis, parameter);
536 inline void RotateProjectionMessage(EventThreadServices& eventThreadServices, const Camera& camera, int parameter)
538 typedef MessageValue1<Camera, int> LocalType;
540 // Reserve some memory inside the message queue
541 unsigned int* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
543 // Construct message in the message queue memory; note that delete should not be called on the return value
544 new(slot) LocalType(&camera, &Camera::RotateProjection, parameter);
547 } // namespace SceneGraph
549 } // namespace Internal
553 #endif // DALI_INTERNAL_SCENE_GRAPH_CAMERA_H