e1bac63abf31598e79e7e7e3bb640aadb2d68338
[platform/core/uifw/dali-core.git] / dali / internal / update / render-tasks / scene-graph-camera.h
1 #ifndef DALI_INTERNAL_SCENE_GRAPH_CAMERA_H
2 #define DALI_INTERNAL_SCENE_GRAPH_CAMERA_H
3
4 /*
5  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
6  *
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
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  */
20
21 // INTERNAL INCLUDES
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>
32
33 namespace Dali
34 {
35 namespace Internal
36 {
37 // value types used by messages
38 template<>
39 struct ParameterType<Dali::Camera::Type>
40 : public BasicType<Dali::Camera::Type>
41 {
42 };
43 template<>
44 struct ParameterType<Dali::Camera::ProjectionMode>
45 : public BasicType<Dali::Camera::ProjectionMode>
46 {
47 };
48
49 namespace SceneGraph
50 {
51 class SceneController;
52
53 /**
54  * Scene-graph camera object
55  */
56 class Camera : public Node
57 {
58 public:
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;
73
74   /**
75    * Plane equation container for a plane of the view frustum
76    */
77   struct Plane
78   {
79     Vector3 mNormal;
80     float   mDistance;
81   };
82
83   /**
84    * @brief Container for six planes in a view frustum
85    */
86   struct FrustumPlanes
87   {
88     Plane   mPlanes[6];
89     Vector3 mSign[6];
90   };
91
92   /**
93    * Construct a new Camera.
94    * @return a new camera.
95    */
96   static Camera* New();
97
98   /**
99    * Virtual destructor
100    */
101   ~Camera() override;
102
103   /**
104    * Overriden delete operator
105    * Deletes the camera from its global memory pool
106    */
107   void operator delete(void* ptr);
108
109   /**
110    * @copydoc Dali::Internal::CameraActor::SetType
111    */
112   void SetType(Dali::Camera::Type type);
113
114   /**
115    * @copydoc Dali::Internal::CameraActor::SetInvertYAxis
116    */
117   void SetInvertYAxis(bool invertYAxis);
118
119   /**
120    * Returns whether the Y axis is inverted.
121    * @return True if the Y axis is inverted, false otherwise.
122    */
123   bool IsYAxisInverted() const
124   {
125     return mInvertYAxis;
126   }
127
128   /**
129    * @copydoc Dali::Internal::CameraActor::SetProjectionMode
130    */
131   void SetProjectionMode(Dali::Camera::ProjectionMode projectionMode);
132
133   /**
134    * @copydoc Dali::Internal::CameraActor::SetProjectionDirection
135    */
136   void SetProjectionDirection(Dali::DevelCameraActor::ProjectionDirection direction);
137
138   /**
139    * @copydoc Dali::Internal::CameraActor::SetAspectRatio
140    */
141   void SetAspectRatio(float aspectRatio);
142
143   /**
144    * @copydoc Dali::Internal::CameraActor::SetLeftClippingPlane
145    */
146   void SetLeftClippingPlane(float leftClippingPlane);
147
148   /**
149    * @copydoc Dali::Internal::CameraActor::SetRightClippingPlane
150    */
151   void SetRightClippingPlane(float rightClippingPlane);
152
153   /**
154    * @copydoc Dali::Internal::CameraActor::SetTopClippingPlane
155    */
156   void SetTopClippingPlane(float topClippingPlane);
157
158   /**
159    * @copydoc Dali::Internal::CameraActor::SetBottomClippingPlane
160    */
161   void SetBottomClippingPlane(float bottomClippingPlane);
162
163   /**
164    * @copydoc Dali::Internal::CameraActor::SetNearClippingPlane
165    */
166   void SetNearClippingPlane(float nearClippingPlane);
167
168   /**
169    * @copydoc Dali::Internal::CameraActor::SetFarClippingPlane
170    */
171   void SetFarClippingPlane(float farClippingPlane);
172
173   /**
174    * @copydoc Dali::Internal::CameraActor::RotateProjection
175    */
176   void RotateProjection(int rotationAngle);
177
178   /**
179    * @copydoc Dali::Internal::CameraActor::SetTarget
180    */
181   void SetTargetPosition(const Vector3& targetPosition);
182
183   /**
184    * @brief Bakes the field of view.
185    * @param[in] updateBufferIndex The current update buffer index.
186    * @param[in] opacity The field of view.
187    */
188   void BakeFieldOfView(BufferIndex updateBufferIndex, float fieldOfView);
189
190   /**
191    * @brief Retrieve the field of view.
192    * @param[in] bufferIndex The buffer to read from.
193    * @return The field of view.
194    */
195   float GetFieldOfView(BufferIndex bufferIndex) const
196   {
197     return mFieldOfView[bufferIndex];
198   }
199
200   /**
201    * Sets the reflection plane
202    * @param[in] plane reflection plane
203    */
204   void SetReflectByPlane(const Vector4& plane);
205
206   /**
207    * Tests whether reflection is used
208    * @return True if used, False otherwise
209    */
210   bool GetReflectionUsed() const
211   {
212     return mUseReflection;
213   }
214
215   /**
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.
219    */
220   const Matrix& GetViewMatrix(BufferIndex bufferIndex) const;
221
222   /**
223    * @brief Check to see if a sphere lies within the view frustum.
224    *
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.
228    *
229    * @return false if the sphere lies outside of the frustum.
230    */
231   bool CheckSphereInFrustum(BufferIndex bufferIndex, const Vector3& origin, float radius) const;
232
233   /**
234    * @brief Check to see if a bounding box lies within the view frustum.
235    *
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.
239    *
240    * @return false if the cubeoid lies completely outside of the frustum, true otherwise
241    */
242   bool CheckAABBInFrustum(BufferIndex bufferIndex, const Vector3& origin, const Vector3& halfExtents) const;
243
244   /**
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.
248    */
249   const Matrix& GetProjectionMatrix(BufferIndex bufferIndex) const;
250
251   /**
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.
255    */
256   const Matrix& GetInverseViewProjectionMatrix(BufferIndex bufferIndex) const;
257
258   /**
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.
262    */
263   const Matrix& GetFinalProjectionMatrix(BufferIndex bufferIndex) const;
264
265   /**
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.
269    */
270   const PropertyBase* GetFieldOfView() const;
271
272   /**
273    * Retrieve the projection-matrix property querying interface.
274    * @pre The camera is on-stage.
275    * @return The projection-matrix property querying interface.
276    */
277   const PropertyInputImpl* GetProjectionMatrix() const;
278
279   /**
280    * Retrieve the viewMatrix property querying interface.
281    * @pre The camera is on-stage.
282    * @return The viewMatrix property querying interface.
283    */
284   const PropertyInputImpl* GetViewMatrix() const;
285
286   /**
287    * Updates view and projection matrices.
288    * Called by the render task using the camera
289    * @param[in] updateBufferIndex The buffer to read from.
290    */
291   void Update(BufferIndex updateBufferIndex);
292
293   /**
294    * @return true if the view matrix of camera is updated this or the previous frame
295    */
296   bool ViewMatrixUpdated() const;
297
298   /**
299    * @return true if the projection matrix projection matrix relative properties are animated this or the previous frame
300    */
301   bool IsProjectionMatrixAnimated() const;
302
303 private:
304   /**
305    * Constructor
306    */
307   Camera();
308
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;
314
315   /**
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.
319    */
320   uint32_t UpdateViewMatrix(BufferIndex updateBufferIndex);
321
322   /**
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.
326    */
327   uint32_t UpdateProjection(BufferIndex updateBufferIndex);
328
329 private:
330   /**
331    * @brief Extracts the frustum planes.
332    *
333    * @param[in] bufferIndex The current update buffer index.
334    * @param[in] normalize will normalize plane equation coefficients by default.
335    */
336   void UpdateFrustum(BufferIndex updateBufferIndex, bool normalize = true);
337
338   /**
339    * Adjust near plane for reflection
340    * @param perspective Perspective matrix
341    * @param clipPlane Clipping plane
342    */
343   void AdjustNearPlaneForPerspective(Matrix& perspective, const Vector4& clipPlane);
344
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
348
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
354
355   AnimatableProperty<float> mFieldOfView; // Animatable
356
357   float   mAspectRatio;
358   float   mLeftClippingPlane;
359   float   mRightClippingPlane;
360   float   mTopClippingPlane;
361   float   mBottomClippingPlane;
362   float   mNearClippingPlane;
363   float   mFarClippingPlane;
364   Vector3 mTargetPosition;
365
366   Dali::Matrix  mReflectionMtx;
367   Dali::Vector4 mReflectionPlane;
368   Dali::Vector4 mReflectionEye;
369   bool          mUseReflection{false};
370   bool          mUseReflectionClip{false};
371
372   InheritedMatrix mViewMatrix;       ///< The viewMatrix; this is double buffered for input handling.
373   InheritedMatrix mProjectionMatrix; ///< The projectionMatrix; this is double buffered for input handling.
374
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
378 };
379
380 // Messages for Camera
381
382 inline void SetTypeMessage(EventThreadServices& eventThreadServices, const Camera& camera, Dali::Camera::Type parameter)
383 {
384   using LocalType = MessageValue1<Camera, Dali::Camera::Type>;
385
386   // Reserve some memory inside the message queue
387   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
388
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);
391 }
392
393 inline void SetProjectionModeMessage(EventThreadServices& eventThreadServices, const Camera& camera, Dali::Camera::ProjectionMode parameter)
394 {
395   using LocalProjectionMode = MessageValue1<Camera, Dali::Camera::ProjectionMode>;
396
397   // Reserve some memory inside the message queue
398   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalProjectionMode));
399
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);
402 }
403
404 inline void SetProjectionDirectionMessage(EventThreadServices& eventThreadServices, const Camera& camera, Dali::DevelCameraActor::ProjectionDirection parameter)
405 {
406   using LocalProjectionDirection = MessageValue1<Camera, Dali::DevelCameraActor::ProjectionDirection>;
407
408   // Reserve some memory inside the message queue
409   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalProjectionDirection));
410
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);
413 }
414
415 inline void BakeFieldOfViewMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
416 {
417   using LocalType = MessageDoubleBuffered1<Camera, float>;
418
419   // Reserve some memory inside the message queue
420   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
421
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);
424 }
425
426 inline void SetAspectRatioMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
427 {
428   using LocalType = MessageValue1<Camera, float>;
429
430   // Reserve some memory inside the message queue
431   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
432
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);
435 }
436
437 inline void SetLeftClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
438 {
439   using LocalType = MessageValue1<Camera, float>;
440
441   // Reserve some memory inside the message queue
442   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
443
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);
446 }
447
448 inline void SetRightClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
449 {
450   using LocalType = MessageValue1<Camera, float>;
451
452   // Reserve some memory inside the message queue
453   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
454
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);
457 }
458
459 inline void SetTopClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
460 {
461   using LocalType = MessageValue1<Camera, float>;
462
463   // Reserve some memory inside the message queue
464   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
465
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);
468 }
469
470 inline void SetBottomClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
471 {
472   using LocalType = MessageValue1<Camera, float>;
473
474   // Reserve some memory inside the message queue
475   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
476
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);
479 }
480
481 inline void SetNearClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
482 {
483   using LocalType = MessageValue1<Camera, float>;
484
485   // Reserve some memory inside the message queue
486   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
487
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);
490 }
491
492 inline void SetFarClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
493 {
494   using LocalType = MessageValue1<Camera, float>;
495
496   // Reserve some memory inside the message queue
497   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
498
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);
501 }
502
503 inline void SetReflectByPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, const Vector4& plane)
504 {
505   using LocalType = MessageValue1<Camera, Vector4>;
506
507   // Reserve some memory inside the message queue
508   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
509
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);
512 }
513
514 inline void SetTargetPositionMessage(EventThreadServices& eventThreadServices, const Camera& camera, const Vector3& parameter)
515 {
516   using LocalType = MessageValue1<Camera, Vector3>;
517
518   // Reserve some memory inside the message queue
519   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
520
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);
523 }
524
525 inline void SetInvertYAxisMessage(EventThreadServices& eventThreadServices, const Camera& camera, bool parameter)
526 {
527   using LocalType = MessageValue1<Camera, bool>;
528
529   // Reserve some memory inside the message queue
530   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
531
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);
534 }
535
536 inline void RotateProjectionMessage(EventThreadServices& eventThreadServices, const Camera& camera, int parameter)
537 {
538   typedef MessageValue1<Camera, int> LocalType;
539
540   // Reserve some memory inside the message queue
541   unsigned int* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
542
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);
545 }
546
547 } // namespace SceneGraph
548
549 } // namespace Internal
550
551 } // namespace Dali
552
553 #endif // DALI_INTERNAL_SCENE_GRAPH_CAMERA_H