Apply fittingMode lazy when resource is not ready
[platform/core/uifw/dali-toolkit.git] / dali-physics / internal / physics-world-impl.h
1 #ifndef DALI_TOOLKIT_PHYSICS_INTERNAL_PHYSICS_WORLD_H
2 #define DALI_TOOLKIT_PHYSICS_INTERNAL_PHYSICS_WORLD_H
3
4 /*
5  * Copyright (c) 2023 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 #include <dali/dali.h>
21 #include <dali/devel-api/threading/mutex.h>
22 #include <dali/devel-api/update/frame-callback-interface.h>
23 #include <dali/devel-api/update/update-proxy.h>
24
25 #include <dali-physics/public-api/physics-adaptor.h>
26
27 #include <functional>
28 #include <queue>
29
30 namespace Dali::Toolkit::Physics::Internal
31 {
32 class PhysicsWorld;
33 class FrameCallback;
34
35 /**
36  * Abstract class that handles the update frame callback, queuing and calling
37  * functions before the integration step ; calling the integration step,
38  * and owning the mutex for the update callback.
39  *
40  * Implementing classes should also hold the physics world.
41  */
42 class PhysicsWorld
43 {
44 public:
45   /**
46    * Create a new physics world.
47    */
48   static std::unique_ptr<PhysicsWorld> New(Dali::Actor rootActor, Dali::CallbackBase* updateCallback);
49
50   /**
51    * Constructor which takes the root actor and a callback from the PhysicsAdaptor
52    * @param[in] rootActor The root actor that physics actors will be added to
53    * @param[in] updateCallback A callback from the PhysicsAdaptor which updates the physics actors after the integration step
54    */
55   PhysicsWorld(Dali::Actor rootActor, Dali::CallbackBase* updateCallback);
56
57   /**
58    * Virtual destructor.
59    * Note, removes the frame callback.
60    */
61   virtual ~PhysicsWorld();
62
63   /**
64    * Initialize derived classes and creates the frame callback
65    */
66   void Initialize();
67
68   /**
69    * Initialize the derived class
70    */
71   virtual void OnInitialize() = 0;
72
73   /**
74    * Get the native physics world / space.
75    * @return A pointer to the physics world / space
76    */
77   virtual Dali::Any GetNative() = 0;
78
79   /**
80    * Set how long the integration should take.
81    * @param[in] timestep The length of time that the physics integration should take.
82    */
83   void SetTimestep(float timestep);
84
85   /**
86    * Get the current physics integration timestep
87    * @return the current physics integration timestep
88    */
89   float GetTimestep();
90
91   /**
92    * Queue a function for execution in the update thread, prior to the physics integration.
93    * Enables syncronization of DALi properties and physics controlled properties.
94    */
95   void Queue(std::function<void(void)> function);
96
97   /**
98    * Create a sync point for queued functions.
99    *
100    * Ensures that any queued functions are processed after this sync
101    * point is seen in the Update::FrameCallback, which will be in the
102    * same frame as any other DALi properties set during this event
103    * handler invocation.
104    *
105    * @param[in] None
106    */
107   void CreateSyncPoint();
108
109   /**
110    * Hit test the physics world and return the nearest body.
111    *
112    * @param[in] rayFromWorld The origin in physics world space
113    * @param[in] rayToWorld A point along the direction on the far side of the physics world
114    * @param[out] localPivot The hit point local to the body
115    * @param[out] distanceFromCamera The distance of the pick point from the camera
116    * @return Empty value if no dynamic body found, otherwise a valid ptr to the hit body.
117    */
118   virtual Dali::Any HitTest(Dali::Vector3 rayFromWorld, Dali::Vector3 rayToWorld, Dali::Vector3& localPivot, float& distanceFromCamera) = 0;
119
120   /**
121    * @copydoc Dali::Toolkit::Physics::PhysicsAdaptor::SetIntegrationState
122    */
123   void SetIntegrationState(Physics::PhysicsAdaptor::IntegrationState state);
124
125   /**
126    * @copydoc Dali::Toolkit::Physics::PhysicsAdaptor::GetIntegrationState
127    */
128   Physics::PhysicsAdaptor::IntegrationState GetIntegrationState();
129
130   /**
131    * @copydoc Dali::Toolkit::Physics::PhysicsAdaptor::SetDebugState
132    */
133   void SetDebugState(Physics::PhysicsAdaptor::DebugState state);
134
135   /**
136    * @copydoc Dali::Toolkit::Physics::PhysicsAdaptor::GetDebugState
137    */
138   Physics::PhysicsAdaptor::DebugState GetDebugState();
139
140 public:
141   Dali::Mutex& GetMutex(); // Only for use by adaptor in creating scoped accessor
142
143   bool OnUpdate(Dali::UpdateProxy& updateProxy, float elapsedSeconds);
144
145 protected:
146   virtual void Integrate(float timestep) = 0;
147
148 protected:
149   Dali::Mutex                           mMutex;
150   std::queue<std::function<void(void)>> commandQueue;
151   Dali::UpdateProxy::NotifySyncPoint    mNotifySyncPoint{Dali::UpdateProxy::INVALID_SYNC};
152   Dali::CallbackBase*                   mUpdateCallback{nullptr};
153   std::unique_ptr<FrameCallback>        mFrameCallback;
154   Dali::Actor                           mRootActor;
155
156   float                                     mPhysicsTimeStep{1.0 / 180.0};
157   Physics::PhysicsAdaptor::IntegrationState mPhysicsIntegrateState{Physics::PhysicsAdaptor::IntegrationState::ON};
158   Physics::PhysicsAdaptor::DebugState       mPhysicsDebugState{Physics::PhysicsAdaptor::DebugState::OFF};
159 };
160
161 } // namespace Dali::Toolkit::Physics::Internal
162
163 #endif //DALI_TOOLKIT_PHYSICS_INTERNAL_PHYSICS_WORLD_H