4b37ce4197e2da47eac5f61cbdaa1087fed50885
[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) 2021 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/internal/common/message.h>
23 #include <dali/internal/event/common/event-thread-services.h>
24 #include <dali/internal/update/common/double-buffered.h>
25 #include <dali/internal/update/common/inherited-property.h>
26 #include <dali/public-api/actors/camera-actor.h>
27 #include <dali/public-api/math/rect.h>
28
29 namespace Dali
30 {
31 namespace Internal
32 {
33 // value types used by messages
34 template<>
35 struct ParameterType<Dali::Camera::Type>
36 : public BasicType<Dali::Camera::Type>
37 {
38 };
39 template<>
40 struct ParameterType<Dali::Camera::ProjectionMode>
41 : public BasicType<Dali::Camera::ProjectionMode>
42 {
43 };
44
45 namespace SceneGraph
46 {
47 class Node;
48 class SceneController;
49
50 /**
51  * Scene-graph camera object
52  */
53 class Camera
54 {
55 public:
56   static const Dali::Camera::Type           DEFAULT_TYPE;
57   static const Dali::Camera::ProjectionMode DEFAULT_MODE;
58   static const bool                         DEFAULT_INVERT_Y_AXIS;
59   static const float                        DEFAULT_FIELD_OF_VIEW;
60   static const float                        DEFAULT_ASPECT_RATIO;
61   static const float                        DEFAULT_LEFT_CLIPPING_PLANE;
62   static const float                        DEFAULT_RIGHT_CLIPPING_PLANE;
63   static const float                        DEFAULT_TOP_CLIPPING_PLANE;
64   static const float                        DEFAULT_BOTTOM_CLIPPING_PLANE;
65   static const float                        DEFAULT_NEAR_CLIPPING_PLANE;
66   static const float                        DEFAULT_FAR_CLIPPING_PLANE;
67   static const Vector2                      DEFAULT_STEREO_BIAS;
68   static const Vector3                      DEFAULT_TARGET_POSITION;
69
70   /**
71    * Plane equation container for a plane of the view frustum
72    */
73   struct Plane
74   {
75     Vector3 mNormal;
76     float   mDistance;
77   };
78
79   /**
80    * @brief Container for six planes in a view frustum
81    */
82   struct FrustumPlanes
83   {
84     Plane   mPlanes[6];
85     Vector3 mSign[6];
86   };
87
88   /**
89    * Construct a new Camera.
90    * @return a new camera.
91    */
92   static Camera* New();
93
94   /**
95    * Destructor
96    */
97   ~Camera();
98
99   /**
100    * Set the node this scene graph camera belongs to.
101    * @param[in] node The owning node.
102    */
103   void SetNode(const Node* node);
104
105   /**
106    * Get the node this scene graph camera belongs to.
107    * @return node The owning node.
108    */
109   const Node* GetNode() const;
110
111   /**
112    * @copydoc Dali::Internal::CameraActor::SetType
113    */
114   void SetType(Dali::Camera::Type type);
115
116   /**
117    * @copydoc Dali::Internal::CameraActor::SetInvertYAxis
118    */
119   void SetInvertYAxis(bool invertYAxis);
120
121   /**
122    * Returns whether the Y axis is inverted.
123    * @return True if the Y axis is inverted, false otherwise.
124    */
125   bool IsYAxisInverted() const
126   {
127     return mInvertYAxis;
128   }
129
130   /**
131    * @copydoc Dali::Internal::CameraActor::SetProjectionMode
132    */
133   void SetProjectionMode(Dali::Camera::ProjectionMode projectionMode);
134
135   /**
136    * @copydoc Dali::Internal::CameraActor::SetFieldOfView
137    */
138   void SetFieldOfView(float fieldOfView);
139
140   /**
141    * @copydoc Dali::Internal::CameraActor::SetAspectRatio
142    */
143   void SetAspectRatio(float aspectRatio);
144
145   /**
146    * @copydoc Dali::Internal::CameraActor::SetLeftClippingPlane
147    */
148   void SetLeftClippingPlane(float leftClippingPlane);
149
150   /**
151    * @copydoc Dali::Internal::CameraActor::SetRightClippingPlane
152    */
153   void SetRightClippingPlane(float rightClippingPlane);
154
155   /**
156    * @copydoc Dali::Internal::CameraActor::SetTopClippingPlane
157    */
158   void SetTopClippingPlane(float topClippingPlane);
159
160   /**
161    * @copydoc Dali::Internal::CameraActor::SetBottomClippingPlane
162    */
163   void SetBottomClippingPlane(float bottomClippingPlane);
164
165   /**
166    * @copydoc Dali::Internal::CameraActor::SetNearClippingPlane
167    */
168   void SetNearClippingPlane(float nearClippingPlane);
169
170   /**
171    * @copydoc Dali::Internal::CameraActor::SetFarClippingPlane
172    */
173   void SetFarClippingPlane(float farClippingPlane);
174
175   /**
176    * @copydoc Dali::Internal::CameraActor::RotateProjection
177    */
178   void RotateProjection(int rotationAngle);
179
180   /**
181    * @copydoc Dali::Internal::CameraActor::SetTarget
182    */
183   void SetTargetPosition(const Vector3& targetPosition);
184
185   /**
186    * Sets the reflection plane
187    * @param[in] plane reflection plane
188    */
189   void SetReflectByPlane(const Vector4& plane);
190
191   /**
192    * Tests whether reflection is used
193    * @return True if used, False otherwise
194    */
195   bool GetReflectionUsed() const
196   {
197     return mUseReflection;
198   }
199
200   /**
201    * Retrieve the view-matrix; this is double buffered for input handling.
202    * @param[in] bufferIndex The buffer to read from.
203    * @return The view-matrix.
204    */
205   const Matrix& GetViewMatrix(BufferIndex bufferIndex) const;
206
207   /**
208    * @brief Check to see if a sphere lies within the view frustum.
209    *
210    * @param bufferIndex The buffer to read from.
211    * @param origin The world position center of the sphere to check.
212    * @param radius The length of the sphere radius in world scale.
213    *
214    * @return false if the sphere lies outside of the frustum.
215    */
216   bool CheckSphereInFrustum(BufferIndex bufferIndex, const Vector3& origin, float radius);
217
218   /**
219    * @brief Check to see if a bounding box lies within the view frustum.
220    *
221    * @param bufferIndex The buffer to read from.
222    * @param origin the world position center of the cubeoid to check.
223    * @param halfExtents The half length of the cubeoid in world co-ordinates in each axis.
224    *
225    * @return false if the cubeoid lies completely outside of the frustum, true otherwise
226    */
227   bool CheckAABBInFrustum(BufferIndex bufferIndex, const Vector3& origin, const Vector3& halfExtents);
228
229   /**
230    * Retrieve the projection-matrix; this is double buffered for input handling.
231    * @param[in] bufferIndex The buffer to read from.
232    * @return The projection-matrix.
233    */
234   const Matrix& GetProjectionMatrix(BufferIndex bufferIndex) const;
235
236   /**
237    * Retrieve the inverted view-projection-matrix; this is double buffered for input handling.
238    * @param[in] bufferIndex The buffer to read from.
239    * @return The inverse view-projection-matrix.
240    */
241   const Matrix& GetInverseViewProjectionMatrix(BufferIndex bufferIndex) const;
242
243   /**
244    * Retrieve the final projection-matrix; this is double buffered for input handling.
245    * @param[in] bufferIndex The buffer to read from.
246    * @return The projection-matrix that should be used to render.
247    */
248   const Matrix& GetFinalProjectionMatrix(BufferIndex bufferIndex) const;
249
250   /**
251    * Retrieve the projection-matrix property querying interface.
252    * @pre The camera is on-stage.
253    * @return The projection-matrix property querying interface.
254    */
255   const PropertyInputImpl* GetProjectionMatrix() const;
256
257   /**
258    * Retrieve the viewMatrix property querying interface.
259    * @pre The camera is on-stage.
260    * @return The viewMatrix property querying interface.
261    */
262   const PropertyInputImpl* GetViewMatrix() const;
263
264   /**
265    * Updates view and projection matrices.
266    * Called by the render task using the camera
267    * @param[in] updateBufferIndex The buffer to read from.
268    */
269   void Update(BufferIndex updateBufferIndex);
270
271   /**
272    * @return true if the view matrix of camera is updated this or the previous frame
273    */
274   bool ViewMatrixUpdated();
275
276 private:
277   /**
278    * Constructor
279    */
280   Camera();
281
282   // Non copyable
283   // Undefined
284   Camera(const Camera&);
285   // Undefined
286   Camera& operator=(const Camera& rhs);
287
288   /**
289    * Recalculates the view matrix.
290    * @param[in] bufferIndex The current update buffer index.
291    * @return count how many frames ago the matrix was changed.
292    */
293   uint32_t UpdateViewMatrix(BufferIndex updateBufferIndex);
294
295   /**
296    * Recalculates the projection matrix.
297    * @param[in] bufferIndex The current update buffer index.
298    * @return count how many frames ago the matrix was changed.
299    */
300   uint32_t UpdateProjection(BufferIndex updateBufferIndex);
301
302 private:
303   /**
304    * @brief Extracts the frustum planes.
305    *
306    * @param[in] bufferIndex The current update buffer index.
307    * @param[in] normalize will normalize plane equation coefficients by default.
308    */
309   void UpdateFrustum(BufferIndex updateBufferIndex, bool normalize = true);
310
311   /**
312    * Adjust near plane for reflection
313    * @param perspective Perspective matrix
314    * @param clipPlane Clipping plane
315    */
316   void AdjustNearPlaneForPerspective(Matrix& perspective, const Vector4& clipPlane);
317
318   uint32_t    mUpdateViewFlag;       ///< This is non-zero if the view matrix requires an update
319   uint32_t    mUpdateProjectionFlag; ///< This is non-zero if the projection matrix requires an update
320   int         mProjectionRotation;   ///< The rotaion angle of the projection
321   const Node* mNode;                 ///< The node this scene graph camera belongs to
322
323 public:                                         // PROPERTIES
324   Dali::Camera::Type           mType;           // Non-animatable
325   Dali::Camera::ProjectionMode mProjectionMode; // Non-animatable
326   bool                         mInvertYAxis;    // Non-animatable
327
328   float   mFieldOfView;
329   float   mAspectRatio;
330   float   mLeftClippingPlane;
331   float   mRightClippingPlane;
332   float   mTopClippingPlane;
333   float   mBottomClippingPlane;
334   float   mNearClippingPlane;
335   float   mFarClippingPlane;
336   Vector3 mTargetPosition;
337
338   Dali::Matrix  mReflectionMtx;
339   Dali::Vector4 mReflectionPlane;
340   Dali::Vector4 mReflectionEye;
341   bool          mUseReflection{false};
342   bool          mUseReflectionClip{false};
343
344   InheritedMatrix mViewMatrix;       ///< The viewMatrix; this is double buffered for input handling.
345   InheritedMatrix mProjectionMatrix; ///< The projectionMatrix; this is double buffered for input handling.
346
347   DoubleBuffered<FrustumPlanes> mFrustum;               ///< Clipping frustum; double buffered for input handling
348   DoubleBuffered<Matrix>        mInverseViewProjection; ///< Inverted viewprojection; double buffered for input handling
349   DoubleBuffered<Matrix>        mFinalProjection;       ///< Final projection matrix; double buffered for input handling
350 };
351
352 // Messages for Camera
353
354 inline void SetTypeMessage(EventThreadServices& eventThreadServices, const Camera& camera, Dali::Camera::Type parameter)
355 {
356   using LocalType = MessageValue1<Camera, Dali::Camera::Type>;
357
358   // Reserve some memory inside the message queue
359   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
360
361   // Construct message in the message queue memory; note that delete should not be called on the return value
362   new(slot) LocalType(&camera, &Camera::SetType, parameter);
363 }
364
365 inline void SetProjectionModeMessage(EventThreadServices& eventThreadServices, const Camera& camera, Dali::Camera::ProjectionMode parameter)
366 {
367   using LocalProjectionMode = MessageValue1<Camera, Dali::Camera::ProjectionMode>;
368
369   // Reserve some memory inside the message queue
370   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalProjectionMode));
371
372   // Construct message in the message queue memory; note that delete should not be called on the return value
373   new(slot) LocalProjectionMode(&camera, &Camera::SetProjectionMode, parameter);
374 }
375
376 inline void SetFieldOfViewMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
377 {
378   using LocalType = MessageValue1<Camera, float>;
379
380   // Reserve some memory inside the message queue
381   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
382
383   // Construct message in the message queue memory; note that delete should not be called on the return value
384   new(slot) LocalType(&camera, &Camera::SetFieldOfView, parameter);
385 }
386
387 inline void SetAspectRatioMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
388 {
389   using LocalType = MessageValue1<Camera, float>;
390
391   // Reserve some memory inside the message queue
392   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
393
394   // Construct message in the message queue memory; note that delete should not be called on the return value
395   new(slot) LocalType(&camera, &Camera::SetAspectRatio, parameter);
396 }
397
398 inline void SetLeftClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
399 {
400   using LocalType = MessageValue1<Camera, float>;
401
402   // Reserve some memory inside the message queue
403   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
404
405   // Construct message in the message queue memory; note that delete should not be called on the return value
406   new(slot) LocalType(&camera, &Camera::SetLeftClippingPlane, parameter);
407 }
408
409 inline void SetRightClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
410 {
411   using LocalType = MessageValue1<Camera, float>;
412
413   // Reserve some memory inside the message queue
414   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
415
416   // Construct message in the message queue memory; note that delete should not be called on the return value
417   new(slot) LocalType(&camera, &Camera::SetRightClippingPlane, parameter);
418 }
419
420 inline void SetTopClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
421 {
422   using LocalType = MessageValue1<Camera, float>;
423
424   // Reserve some memory inside the message queue
425   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
426
427   // Construct message in the message queue memory; note that delete should not be called on the return value
428   new(slot) LocalType(&camera, &Camera::SetTopClippingPlane, parameter);
429 }
430
431 inline void SetBottomClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
432 {
433   using LocalType = MessageValue1<Camera, float>;
434
435   // Reserve some memory inside the message queue
436   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
437
438   // Construct message in the message queue memory; note that delete should not be called on the return value
439   new(slot) LocalType(&camera, &Camera::SetBottomClippingPlane, parameter);
440 }
441
442 inline void SetNearClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
443 {
444   using LocalType = MessageValue1<Camera, float>;
445
446   // Reserve some memory inside the message queue
447   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
448
449   // Construct message in the message queue memory; note that delete should not be called on the return value
450   new(slot) LocalType(&camera, &Camera::SetNearClippingPlane, parameter);
451 }
452
453 inline void SetFarClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
454 {
455   using LocalType = MessageValue1<Camera, float>;
456
457   // Reserve some memory inside the message queue
458   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
459
460   // Construct message in the message queue memory; note that delete should not be called on the return value
461   new(slot) LocalType(&camera, &Camera::SetFarClippingPlane, parameter);
462 }
463
464 inline void SetTargetPositionMessage(EventThreadServices& eventThreadServices, const Camera& camera, const Vector3& parameter)
465 {
466   using LocalType = MessageValue1<Camera, Vector3>;
467
468   // Reserve some memory inside the message queue
469   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
470
471   // Construct message in the message queue memory; note that delete should not be called on the return value
472   new(slot) LocalType(&camera, &Camera::SetTargetPosition, parameter);
473 }
474
475 inline void SetInvertYAxisMessage(EventThreadServices& eventThreadServices, const Camera& camera, bool parameter)
476 {
477   using LocalType = MessageValue1<Camera, bool>;
478
479   // Reserve some memory inside the message queue
480   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
481
482   // Construct message in the message queue memory; note that delete should not be called on the return value
483   new(slot) LocalType(&camera, &Camera::SetInvertYAxis, parameter);
484 }
485
486 inline void RotateProjectionMessage(EventThreadServices& eventThreadServices, const Camera& camera, int parameter)
487 {
488   typedef MessageValue1<Camera, int> LocalType;
489
490   // Reserve some memory inside the message queue
491   unsigned int* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
492
493   // Construct message in the message queue memory; note that delete should not be called on the return value
494   new(slot) LocalType(&camera, &Camera::RotateProjection, parameter);
495 }
496
497 } // namespace SceneGraph
498
499 } // namespace Internal
500
501 } // namespace Dali
502
503 #endif // DALI_INTERNAL_SCENE_GRAPH_CAMERA_H