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/double-buffered.h>
27 #include <dali/internal/update/common/inherited-property.h>
28 #include <dali/public-api/actors/camera-actor.h>
29 #include <dali/public-api/math/rect.h>
35 // value types used by messages
37 struct ParameterType<Dali::Camera::Type>
38 : public BasicType<Dali::Camera::Type>
42 struct ParameterType<Dali::Camera::ProjectionMode>
43 : public BasicType<Dali::Camera::ProjectionMode>
50 class SceneController;
53 * Scene-graph camera object
58 static const Dali::Camera::Type DEFAULT_TYPE;
59 static const Dali::Camera::ProjectionMode DEFAULT_MODE;
60 static const Dali::DevelCameraActor::ProjectionDirection DEFAULT_PROJECTION_DIRECTION;
61 static const bool DEFAULT_INVERT_Y_AXIS;
62 static const float DEFAULT_FIELD_OF_VIEW;
63 static const float DEFAULT_ASPECT_RATIO;
64 static const float DEFAULT_LEFT_CLIPPING_PLANE;
65 static const float DEFAULT_RIGHT_CLIPPING_PLANE;
66 static const float DEFAULT_TOP_CLIPPING_PLANE;
67 static const float DEFAULT_BOTTOM_CLIPPING_PLANE;
68 static const float DEFAULT_NEAR_CLIPPING_PLANE;
69 static const float DEFAULT_FAR_CLIPPING_PLANE;
70 static const Vector2 DEFAULT_STEREO_BIAS;
71 static const Vector3 DEFAULT_TARGET_POSITION;
74 * Plane equation container for a plane of the view frustum
83 * @brief Container for six planes in a view frustum
92 * Construct a new Camera.
93 * @return a new camera.
103 * Set the node this scene graph camera belongs to.
104 * @param[in] node The owning node.
106 void SetNode(const Node* node);
109 * Get the node this scene graph camera belongs to.
110 * @return node The owning node.
112 const Node* GetNode() const;
115 * @copydoc Dali::Internal::CameraActor::SetType
117 void SetType(Dali::Camera::Type type);
120 * @copydoc Dali::Internal::CameraActor::SetInvertYAxis
122 void SetInvertYAxis(bool invertYAxis);
125 * Returns whether the Y axis is inverted.
126 * @return True if the Y axis is inverted, false otherwise.
128 bool IsYAxisInverted() const
134 * @copydoc Dali::Internal::CameraActor::SetProjectionMode
136 void SetProjectionMode(Dali::Camera::ProjectionMode projectionMode);
139 * @copydoc Dali::Internal::CameraActor::SetProjectionDirection
141 void SetProjectionDirection(Dali::DevelCameraActor::ProjectionDirection direction);
144 * @copydoc Dali::Internal::CameraActor::SetFieldOfView
146 void SetFieldOfView(float fieldOfView);
149 * @copydoc Dali::Internal::CameraActor::SetAspectRatio
151 void SetAspectRatio(float aspectRatio);
154 * @copydoc Dali::Internal::CameraActor::SetLeftClippingPlane
156 void SetLeftClippingPlane(float leftClippingPlane);
159 * @copydoc Dali::Internal::CameraActor::SetRightClippingPlane
161 void SetRightClippingPlane(float rightClippingPlane);
164 * @copydoc Dali::Internal::CameraActor::SetTopClippingPlane
166 void SetTopClippingPlane(float topClippingPlane);
169 * @copydoc Dali::Internal::CameraActor::SetBottomClippingPlane
171 void SetBottomClippingPlane(float bottomClippingPlane);
174 * @copydoc Dali::Internal::CameraActor::SetNearClippingPlane
176 void SetNearClippingPlane(float nearClippingPlane);
179 * @copydoc Dali::Internal::CameraActor::SetFarClippingPlane
181 void SetFarClippingPlane(float farClippingPlane);
184 * @copydoc Dali::Internal::CameraActor::RotateProjection
186 void RotateProjection(int rotationAngle);
189 * @copydoc Dali::Internal::CameraActor::SetTarget
191 void SetTargetPosition(const Vector3& targetPosition);
194 * Sets the reflection plane
195 * @param[in] plane reflection plane
197 void SetReflectByPlane(const Vector4& plane);
200 * Tests whether reflection is used
201 * @return True if used, False otherwise
203 bool GetReflectionUsed() const
205 return mUseReflection;
209 * Retrieve the view-matrix; this is double buffered for input handling.
210 * @param[in] bufferIndex The buffer to read from.
211 * @return The view-matrix.
213 const Matrix& GetViewMatrix(BufferIndex bufferIndex) const;
216 * @brief Check to see if a sphere lies within the view frustum.
218 * @param bufferIndex The buffer to read from.
219 * @param origin The world position center of the sphere to check.
220 * @param radius The length of the sphere radius in world scale.
222 * @return false if the sphere lies outside of the frustum.
224 bool CheckSphereInFrustum(BufferIndex bufferIndex, const Vector3& origin, float radius);
227 * @brief Check to see if a bounding box lies within the view frustum.
229 * @param bufferIndex The buffer to read from.
230 * @param origin the world position center of the cubeoid to check.
231 * @param halfExtents The half length of the cubeoid in world co-ordinates in each axis.
233 * @return false if the cubeoid lies completely outside of the frustum, true otherwise
235 bool CheckAABBInFrustum(BufferIndex bufferIndex, const Vector3& origin, const Vector3& halfExtents);
238 * Retrieve the projection-matrix; this is double buffered for input handling.
239 * @param[in] bufferIndex The buffer to read from.
240 * @return The projection-matrix.
242 const Matrix& GetProjectionMatrix(BufferIndex bufferIndex) const;
245 * Retrieve the inverted view-projection-matrix; this is double buffered for input handling.
246 * @param[in] bufferIndex The buffer to read from.
247 * @return The inverse view-projection-matrix.
249 const Matrix& GetInverseViewProjectionMatrix(BufferIndex bufferIndex) const;
252 * Retrieve the final projection-matrix; this is double buffered for input handling.
253 * @param[in] bufferIndex The buffer to read from.
254 * @return The projection-matrix that should be used to render.
256 const Matrix& GetFinalProjectionMatrix(BufferIndex bufferIndex) const;
259 * Retrieve the projection-matrix property querying interface.
260 * @pre The camera is on-stage.
261 * @return The projection-matrix property querying interface.
263 const PropertyInputImpl* GetProjectionMatrix() const;
266 * Retrieve the viewMatrix property querying interface.
267 * @pre The camera is on-stage.
268 * @return The viewMatrix property querying interface.
270 const PropertyInputImpl* GetViewMatrix() const;
273 * Updates view and projection matrices.
274 * Called by the render task using the camera
275 * @param[in] updateBufferIndex The buffer to read from.
277 void Update(BufferIndex updateBufferIndex);
280 * @return true if the view matrix of camera is updated this or the previous frame
282 bool ViewMatrixUpdated();
292 Camera(const Camera&);
294 Camera& operator=(const Camera& rhs);
297 * Recalculates the view matrix.
298 * @param[in] bufferIndex The current update buffer index.
299 * @return count how many frames ago the matrix was changed.
301 uint32_t UpdateViewMatrix(BufferIndex updateBufferIndex);
304 * Recalculates the projection matrix.
305 * @param[in] bufferIndex The current update buffer index.
306 * @return count how many frames ago the matrix was changed.
308 uint32_t UpdateProjection(BufferIndex updateBufferIndex);
312 * @brief Extracts the frustum planes.
314 * @param[in] bufferIndex The current update buffer index.
315 * @param[in] normalize will normalize plane equation coefficients by default.
317 void UpdateFrustum(BufferIndex updateBufferIndex, bool normalize = true);
320 * Adjust near plane for reflection
321 * @param perspective Perspective matrix
322 * @param clipPlane Clipping plane
324 void AdjustNearPlaneForPerspective(Matrix& perspective, const Vector4& clipPlane);
326 uint32_t mUpdateViewFlag; ///< This is non-zero if the view matrix requires an update
327 uint32_t mUpdateProjectionFlag; ///< This is non-zero if the projection matrix requires an update
328 int mProjectionRotation; ///< The rotaion angle of the projection
329 const Node* mNode; ///< The node this scene graph camera belongs to
331 public: // PROPERTIES
332 Dali::Camera::Type mType; // Non-animatable
333 Dali::Camera::ProjectionMode mProjectionMode; // Non-animatable
334 Dali::DevelCameraActor::ProjectionDirection mProjectionDirection; // Non-animatable
335 bool mInvertYAxis; // Non-animatable
339 float mLeftClippingPlane;
340 float mRightClippingPlane;
341 float mTopClippingPlane;
342 float mBottomClippingPlane;
343 float mNearClippingPlane;
344 float mFarClippingPlane;
345 Vector3 mTargetPosition;
347 Dali::Matrix mReflectionMtx;
348 Dali::Vector4 mReflectionPlane;
349 Dali::Vector4 mReflectionEye;
350 bool mUseReflection{false};
351 bool mUseReflectionClip{false};
353 InheritedMatrix mViewMatrix; ///< The viewMatrix; this is double buffered for input handling.
354 InheritedMatrix mProjectionMatrix; ///< The projectionMatrix; this is double buffered for input handling.
356 DoubleBuffered<FrustumPlanes> mFrustum; ///< Clipping frustum; double buffered for input handling
357 DoubleBuffered<Matrix> mInverseViewProjection; ///< Inverted viewprojection; double buffered for input handling
358 DoubleBuffered<Matrix> mFinalProjection; ///< Final projection matrix; double buffered for input handling
361 // Messages for Camera
363 inline void SetTypeMessage(EventThreadServices& eventThreadServices, const Camera& camera, Dali::Camera::Type parameter)
365 using LocalType = MessageValue1<Camera, Dali::Camera::Type>;
367 // Reserve some memory inside the message queue
368 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
370 // Construct message in the message queue memory; note that delete should not be called on the return value
371 new(slot) LocalType(&camera, &Camera::SetType, parameter);
374 inline void SetProjectionModeMessage(EventThreadServices& eventThreadServices, const Camera& camera, Dali::Camera::ProjectionMode parameter)
376 using LocalProjectionMode = MessageValue1<Camera, Dali::Camera::ProjectionMode>;
378 // Reserve some memory inside the message queue
379 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalProjectionMode));
381 // Construct message in the message queue memory; note that delete should not be called on the return value
382 new(slot) LocalProjectionMode(&camera, &Camera::SetProjectionMode, parameter);
385 inline void SetProjectionDirectionMessage(EventThreadServices& eventThreadServices, const Camera& camera, Dali::DevelCameraActor::ProjectionDirection parameter)
387 using LocalProjectionDirection = MessageValue1<Camera, Dali::DevelCameraActor::ProjectionDirection>;
389 // Reserve some memory inside the message queue
390 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalProjectionDirection));
392 // Construct message in the message queue memory; note that delete should not be called on the return value
393 new(slot) LocalProjectionDirection(&camera, &Camera::SetProjectionDirection, parameter);
396 inline void SetFieldOfViewMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
398 using LocalType = MessageValue1<Camera, float>;
400 // Reserve some memory inside the message queue
401 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
403 // Construct message in the message queue memory; note that delete should not be called on the return value
404 new(slot) LocalType(&camera, &Camera::SetFieldOfView, parameter);
407 inline void SetAspectRatioMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
409 using LocalType = MessageValue1<Camera, float>;
411 // Reserve some memory inside the message queue
412 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
414 // Construct message in the message queue memory; note that delete should not be called on the return value
415 new(slot) LocalType(&camera, &Camera::SetAspectRatio, parameter);
418 inline void SetLeftClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
420 using LocalType = MessageValue1<Camera, float>;
422 // Reserve some memory inside the message queue
423 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
425 // Construct message in the message queue memory; note that delete should not be called on the return value
426 new(slot) LocalType(&camera, &Camera::SetLeftClippingPlane, parameter);
429 inline void SetRightClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
431 using LocalType = MessageValue1<Camera, float>;
433 // Reserve some memory inside the message queue
434 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
436 // Construct message in the message queue memory; note that delete should not be called on the return value
437 new(slot) LocalType(&camera, &Camera::SetRightClippingPlane, parameter);
440 inline void SetTopClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
442 using LocalType = MessageValue1<Camera, float>;
444 // Reserve some memory inside the message queue
445 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
447 // Construct message in the message queue memory; note that delete should not be called on the return value
448 new(slot) LocalType(&camera, &Camera::SetTopClippingPlane, parameter);
451 inline void SetBottomClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
453 using LocalType = MessageValue1<Camera, float>;
455 // Reserve some memory inside the message queue
456 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
458 // Construct message in the message queue memory; note that delete should not be called on the return value
459 new(slot) LocalType(&camera, &Camera::SetBottomClippingPlane, parameter);
462 inline void SetNearClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
464 using LocalType = MessageValue1<Camera, float>;
466 // Reserve some memory inside the message queue
467 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
469 // Construct message in the message queue memory; note that delete should not be called on the return value
470 new(slot) LocalType(&camera, &Camera::SetNearClippingPlane, parameter);
473 inline void SetFarClippingPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, float parameter)
475 using LocalType = MessageValue1<Camera, float>;
477 // Reserve some memory inside the message queue
478 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
480 // Construct message in the message queue memory; note that delete should not be called on the return value
481 new(slot) LocalType(&camera, &Camera::SetFarClippingPlane, parameter);
484 inline void SetReflectByPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, const Vector4& plane)
486 using LocalType = MessageValue1<Camera, Vector4>;
488 // Reserve some memory inside the message queue
489 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
491 // Construct message in the message queue memory; note that delete should not be called on the return value
492 new(slot) LocalType(&camera, &Camera::SetReflectByPlane, plane);
495 inline void SetTargetPositionMessage(EventThreadServices& eventThreadServices, const Camera& camera, const Vector3& parameter)
497 using LocalType = MessageValue1<Camera, Vector3>;
499 // Reserve some memory inside the message queue
500 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
502 // Construct message in the message queue memory; note that delete should not be called on the return value
503 new(slot) LocalType(&camera, &Camera::SetTargetPosition, parameter);
506 inline void SetInvertYAxisMessage(EventThreadServices& eventThreadServices, const Camera& camera, bool parameter)
508 using LocalType = MessageValue1<Camera, bool>;
510 // Reserve some memory inside the message queue
511 uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
513 // Construct message in the message queue memory; note that delete should not be called on the return value
514 new(slot) LocalType(&camera, &Camera::SetInvertYAxis, parameter);
517 inline void RotateProjectionMessage(EventThreadServices& eventThreadServices, const Camera& camera, int parameter)
519 typedef MessageValue1<Camera, int> LocalType;
521 // Reserve some memory inside the message queue
522 unsigned int* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
524 // Construct message in the message queue memory; note that delete should not be called on the return value
525 new(slot) LocalType(&camera, &Camera::RotateProjection, parameter);
528 } // namespace SceneGraph
530 } // namespace Internal
534 #endif // DALI_INTERNAL_SCENE_GRAPH_CAMERA_H