[Tizen] Revert "Optimize some matrix multiply for projection matrix + Orthographic...
[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_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;
74
75   /**
76    * Plane equation container for a plane of the view frustum
77    */
78   struct Plane
79   {
80     Vector3 mNormal;
81     float   mDistance;
82   };
83
84   /**
85    * @brief Container for six planes in a view frustum
86    */
87   struct FrustumPlanes
88   {
89     Plane   mPlanes[6];
90     Vector3 mSign[6];
91   };
92
93   /**
94    * Construct a new Camera.
95    * @return a new camera.
96    */
97   static Camera* New();
98
99   /**
100    * Virtual destructor
101    */
102   ~Camera() override;
103
104   /**
105    * Overriden delete operator
106    * Deletes the camera from its global memory pool
107    */
108   void operator delete(void* ptr);
109
110   /**
111    * @copydoc Dali::Internal::CameraActor::SetType
112    */
113   void SetType(Dali::Camera::Type type);
114
115   /**
116    * @copydoc Dali::Internal::CameraActor::SetInvertYAxis
117    */
118   void SetInvertYAxis(bool invertYAxis);
119
120   /**
121    * Returns whether the Y axis is inverted.
122    * @return True if the Y axis is inverted, false otherwise.
123    */
124   bool IsYAxisInverted() const
125   {
126     return mInvertYAxis;
127   }
128
129   /**
130    * @copydoc Dali::Internal::CameraActor::SetProjectionMode
131    */
132   void SetProjectionMode(Dali::Camera::ProjectionMode projectionMode);
133
134   /**
135    * @copydoc Dali::Internal::CameraActor::SetProjectionDirection
136    */
137   void SetProjectionDirection(Dali::DevelCameraActor::ProjectionDirection direction);
138
139   /**
140    * @copydoc Dali::Internal::CameraActor::SetLeftClippingPlane
141    */
142   void SetLeftClippingPlane(float leftClippingPlane);
143
144   /**
145    * @copydoc Dali::Internal::CameraActor::SetRightClippingPlane
146    */
147   void SetRightClippingPlane(float rightClippingPlane);
148
149   /**
150    * @copydoc Dali::Internal::CameraActor::SetTopClippingPlane
151    */
152   void SetTopClippingPlane(float topClippingPlane);
153
154   /**
155    * @copydoc Dali::Internal::CameraActor::SetBottomClippingPlane
156    */
157   void SetBottomClippingPlane(float bottomClippingPlane);
158
159   /**
160    * @copydoc Dali::Internal::CameraActor::SetNearClippingPlane
161    */
162   void SetNearClippingPlane(float nearClippingPlane);
163
164   /**
165    * @copydoc Dali::Internal::CameraActor::SetFarClippingPlane
166    */
167   void SetFarClippingPlane(float farClippingPlane);
168
169   /**
170    * @copydoc Dali::Internal::CameraActor::RotateProjection
171    */
172   void RotateProjection(int rotationAngle);
173
174   /**
175    * @copydoc Dali::Internal::CameraActor::SetTarget
176    */
177   void SetTargetPosition(const Vector3& targetPosition);
178
179   /**
180    * @brief Bakes the field of view.
181    * @param[in] updateBufferIndex The current update buffer index.
182    * @param[in] fieldOfView The field of view.
183    */
184   void BakeFieldOfView(BufferIndex updateBufferIndex, float fieldOfView);
185
186   /**
187    * @brief Retrieve the field of view.
188    * @param[in] bufferIndex The buffer to read from.
189    * @return The field of view.
190    */
191   float GetFieldOfView(BufferIndex bufferIndex) const
192   {
193     return mFieldOfView[bufferIndex];
194   }
195
196   /**
197    * @brief Bakes the orthographic size.
198    * @param[in] updateBufferIndex The current update buffer index.
199    * @param[in] orthographicSize The orthographic size.
200    */
201   void BakeOrthographicSize(BufferIndex updateBufferIndex, float orthographicSize);
202
203   /**
204    * @brief Retrieve the orthographic size.
205    * @param[in] bufferIndex The buffer to read from.
206    * @return The orthographic size.
207    */
208   float GetOrthographicSize(BufferIndex bufferIndex) const
209   {
210     return mOrthographicSize[bufferIndex];
211   }
212
213   /**
214    * @brief Bakes the aspect ratio.
215    * @param[in] updateBufferIndex The current update buffer index.
216    * @param[in] aspectRatio The aspect ratio.
217    */
218   void BakeAspectRatio(BufferIndex updateBufferIndex, float aspectRatio);
219
220   /**
221    * @brief Retrieve the aspect ratio.
222    * @param[in] bufferIndex The buffer to read from.
223    * @return The aspect ratio.
224    */
225   float GetAspectRatio(BufferIndex bufferIndex) const
226   {
227     return mAspectRatio[bufferIndex];
228   }
229
230   /**
231    * Sets the reflection plane
232    * @param[in] plane reflection plane
233    */
234   void SetReflectByPlane(const Vector4& plane);
235
236   /**
237    * Tests whether reflection is used
238    * @return True if used, False otherwise
239    */
240   bool GetReflectionUsed() const
241   {
242     return mUseReflection;
243   }
244
245   /**
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.
249    */
250   const Matrix& GetViewMatrix(BufferIndex bufferIndex) const;
251
252   /**
253    * @brief Check to see if a sphere lies within the view frustum.
254    *
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.
258    *
259    * @return false if the sphere lies outside of the frustum.
260    */
261   bool CheckSphereInFrustum(BufferIndex bufferIndex, const Vector3& origin, float radius) const;
262
263   /**
264    * @brief Check to see if a bounding box lies within the view frustum.
265    *
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.
269    *
270    * @return false if the cubeoid lies completely outside of the frustum, true otherwise
271    */
272   bool CheckAABBInFrustum(BufferIndex bufferIndex, const Vector3& origin, const Vector3& halfExtents) const;
273
274   /**
275    * @brief Calculate orthographic clipping box by this camera's orthographic size.
276    */
277   Dali::Rect<int32_t> GetOrthographicClippingBox(BufferIndex bufferIndex) const;
278
279   /**
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.
283    */
284   const Matrix& GetProjectionMatrix(BufferIndex bufferIndex) const;
285
286   /**
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.
290    */
291   const Matrix& GetInverseViewProjectionMatrix(BufferIndex bufferIndex) const;
292
293   /**
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.
297    */
298   const Matrix& GetFinalProjectionMatrix(BufferIndex bufferIndex) const;
299
300   /**
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.
304    */
305   const PropertyBase* GetFieldOfView() const;
306
307   /**
308    * Retrieve the orthographic size property querying interface.
309    * @pre The camera is on-stage.
310    * @return The orthographic size property querying interface.
311    */
312   const PropertyBase* GetOrthographicSize() const;
313
314   /**
315    * Retrieve the aspect ratio property querying interface.
316    * @pre The camera is on-stage.
317    * @return The aspect ratio property querying interface.
318    */
319   const PropertyBase* GetAspectRatio() const;
320
321   /**
322    * Retrieve the projection-matrix property querying interface.
323    * @pre The camera is on-stage.
324    * @return The projection-matrix property querying interface.
325    */
326   const PropertyInputImpl* GetProjectionMatrix() const;
327
328   /**
329    * Retrieve the viewMatrix property querying interface.
330    * @pre The camera is on-stage.
331    * @return The viewMatrix property querying interface.
332    */
333   const PropertyInputImpl* GetViewMatrix() const;
334
335   /**
336    * Updates view and projection matrices.
337    * Called by the render task using the camera
338    * @param[in] updateBufferIndex The buffer to read from.
339    */
340   void Update(BufferIndex updateBufferIndex);
341
342   /**
343    * @return true if the view matrix of camera is updated this or the previous frame
344    */
345   bool ViewMatrixUpdated() const;
346
347   /**
348    * @return true if the projection matrix projection matrix relative properties are animated this or the previous frame
349    */
350   bool IsProjectionMatrixAnimated() const;
351
352 private:
353   /**
354    * Constructor
355    */
356   Camera();
357
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;
363
364   /**
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.
368    */
369   uint32_t UpdateViewMatrix(BufferIndex updateBufferIndex);
370
371   /**
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.
375    */
376   uint32_t UpdateProjection(BufferIndex updateBufferIndex);
377
378 private:
379   /**
380    * @brief Extracts the frustum planes.
381    *
382    * @param[in] bufferIndex The current update buffer index.
383    * @param[in] normalize will normalize plane equation coefficients by default.
384    */
385   void UpdateFrustum(BufferIndex updateBufferIndex, bool normalize = true);
386
387   /**
388    * Adjust near plane for reflection
389    * @param perspective Perspective matrix
390    * @param clipPlane Clipping plane
391    */
392   void AdjustNearPlaneForPerspective(Matrix& perspective, const Vector4& clipPlane);
393
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
397
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
403
404   AnimatableProperty<float> mFieldOfView;      // Animatable
405   AnimatableProperty<float> mOrthographicSize; // Animatable
406   AnimatableProperty<float> mAspectRatio;      // Animatable
407
408   float   mNearClippingPlane;
409   float   mFarClippingPlane;
410   Vector3 mTargetPosition;
411
412   Dali::Matrix  mReflectionMtx;
413   Dali::Vector4 mReflectionPlane;
414   Dali::Vector4 mReflectionEye;
415   bool          mUseReflection{false};
416   bool          mUseReflectionClip{false};
417
418   InheritedMatrix mViewMatrix;       ///< The viewMatrix; this is double buffered for input handling.
419   InheritedMatrix mProjectionMatrix; ///< The projectionMatrix; this is double buffered for input handling.
420
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
424 };
425
426 // Messages for Camera
427
428 inline void SetTypeMessage(EventThreadServices& eventThreadServices, const Camera& camera, Dali::Camera::Type parameter)
429 {
430   using LocalType = MessageValue1<Camera, Dali::Camera::Type>;
431
432   // Reserve some memory inside the message queue
433   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
434
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);
437 }
438
439 inline void SetProjectionModeMessage(EventThreadServices& eventThreadServices, const Camera& camera, Dali::Camera::ProjectionMode parameter)
440 {
441   using LocalProjectionMode = MessageValue1<Camera, Dali::Camera::ProjectionMode>;
442
443   // Reserve some memory inside the message queue
444   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalProjectionMode));
445
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);
448 }
449
450 inline void SetProjectionDirectionMessage(EventThreadServices& eventThreadServices, const Camera& camera, Dali::DevelCameraActor::ProjectionDirection parameter)
451 {
452   using LocalProjectionDirection = MessageValue1<Camera, Dali::DevelCameraActor::ProjectionDirection>;
453
454   // Reserve some memory inside the message queue
455   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalProjectionDirection));
456
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);
459 }
460
461 inline void BakeFieldOfViewMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
462 {
463   using LocalType = MessageDoubleBuffered1<Camera, float>;
464
465   // Reserve some memory inside the message queue
466   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
467
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);
470 }
471
472 inline void BakeOrthographicSizeMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
473 {
474   using LocalType = MessageDoubleBuffered1<Camera, float>;
475
476   // Reserve some memory inside the message queue
477   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
478
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);
481 }
482
483 inline void BakeAspectRatioMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
484 {
485   using LocalType = MessageDoubleBuffered1<Camera, float>;
486
487   // Reserve some memory inside the message queue
488   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
489
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);
492 }
493
494 inline void SetNearClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
495 {
496   using LocalType = MessageValue1<Camera, float>;
497
498   // Reserve some memory inside the message queue
499   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
500
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);
503 }
504
505 inline void SetFarClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
506 {
507   using LocalType = MessageValue1<Camera, float>;
508
509   // Reserve some memory inside the message queue
510   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
511
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);
514 }
515
516 inline void SetReflectByPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, const Vector4& plane)
517 {
518   using LocalType = MessageValue1<Camera, Vector4>;
519
520   // Reserve some memory inside the message queue
521   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
522
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);
525 }
526
527 inline void SetTargetPositionMessage(EventThreadServices& eventThreadServices, const Camera& camera, const Vector3& parameter)
528 {
529   using LocalType = MessageValue1<Camera, Vector3>;
530
531   // Reserve some memory inside the message queue
532   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
533
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);
536 }
537
538 inline void SetInvertYAxisMessage(EventThreadServices& eventThreadServices, const Camera& camera, bool parameter)
539 {
540   using LocalType = MessageValue1<Camera, bool>;
541
542   // Reserve some memory inside the message queue
543   uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
544
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);
547 }
548
549 inline void RotateProjectionMessage(EventThreadServices& eventThreadServices, const Camera& camera, int parameter)
550 {
551   typedef MessageValue1<Camera, int> LocalType;
552
553   // Reserve some memory inside the message queue
554   unsigned int* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
555
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);
558 }
559
560 } // namespace SceneGraph
561
562 } // namespace Internal
563
564 } // namespace Dali
565
566 #endif // DALI_INTERNAL_SCENE_GRAPH_CAMERA_H