16 #include <glm/glm.hpp>
17 #include <glm/gtx/quaternion.hpp>
26 const float HAPTIC_TOUCH_STRENGTH = 0.25f;
27 const float HAPTIC_TOUCH_DURATION = 10.0f;
28 const float HAPTIC_SLOPE = 0.18f;
29 const float HAPTIC_THRESHOLD = 40.0f;
31 const QString FLOW_JOINT_PREFIX =
"flow";
32 const QString SIM_JOINT_PREFIX =
"sim";
34 const std::vector<QString> HAND_COLLISION_JOINTS = {
"RightHandMiddle1",
"RightHandThumb3",
"LeftHandMiddle1",
"LeftHandThumb3",
"RightHandMiddle3",
"LeftHandMiddle3" };
36 const float HAND_COLLISION_RADIUS = 0.03f;
37 const float HELPER_JOINT_LENGTH = 0.05f;
39 const float DEFAULT_STIFFNESS = 0.0f;
40 const float DEFAULT_GRAVITY = -0.0096f;
41 const float DEFAULT_DAMPING = 0.85f;
42 const float DEFAULT_INERTIA = 0.8f;
43 const float DEFAULT_DELTA = 0.55f;
44 const float DEFAULT_RADIUS = 0.01f;
46 const uint64_t MAX_UPDATE_FLOW_TIME_BUDGET = 2000;
48 struct FlowPhysicsSettings {
49 FlowPhysicsSettings() {};
50 FlowPhysicsSettings(
bool active,
float stiffness,
float gravity,
float damping,
float inertia,
float delta,
float radius) {
52 _stiffness = stiffness;
60 float _stiffness{ DEFAULT_STIFFNESS };
61 float _gravity{ DEFAULT_GRAVITY };
62 float _damping{ DEFAULT_DAMPING };
63 float _inertia{ DEFAULT_INERTIA };
64 float _delta{ DEFAULT_DELTA };
65 float _radius{ DEFAULT_RADIUS };
68 enum FlowCollisionType {
72 struct FlowCollisionSettings {
73 FlowCollisionSettings() {};
74 FlowCollisionSettings(
const QUuid&
id,
const FlowCollisionType& type,
const glm::vec3& offset,
float radius) {
81 FlowCollisionType _type { FlowCollisionType::CollisionSphere };
82 float _radius { 0.05f };
86 const FlowPhysicsSettings DEFAULT_JOINT_SETTINGS;
88 struct FlowJointInfo {
90 FlowJointInfo(
int index,
int parentIndex,
int childIndex,
const QString& name) {
92 _parentIndex = parentIndex;
93 _childIndex = childIndex;
98 int _parentIndex { -1 };
99 int _childIndex { -1 };
102 struct FlowCollisionResult {
104 float _offset { 0.0f };
106 float _radius { 0.0f };
108 float _distance { 0.0f };
111 class FlowCollisionSphere {
113 FlowCollisionSphere() {};
114 FlowCollisionSphere(
const int& jointIndex,
const FlowCollisionSettings& settings,
bool isTouch =
false);
115 void setPosition(
const glm::vec3& position) { _position = position; }
116 FlowCollisionResult computeSphereCollision(
const glm::vec3& point,
float radius)
const;
117 FlowCollisionResult checkSegmentCollision(
const glm::vec3& point1,
const glm::vec3& point2,
const FlowCollisionResult& collisionResult1,
const FlowCollisionResult& collisionResult2);
122 glm::vec3 _initialOffset;
125 bool _isTouch {
false };
126 int _jointIndex { -1 };
127 int collisionIndex { -1 };
128 float _radius { 0.0f };
129 float _initialRadius{ 0.0f };
134 class FlowCollisionSystem {
136 FlowCollisionSystem() {};
137 void addCollisionSphere(
int jointIndex,
const FlowCollisionSettings& settings,
const glm::vec3& position = { 0.0f, 0.0f, 0.0f },
bool isSelfCollision =
true,
bool isTouch =
false);
138 FlowCollisionResult computeCollision(
const std::vector<FlowCollisionResult> collisions);
140 std::vector<FlowCollisionResult> checkFlowThreadCollisions(FlowThread* flowThread);
142 std::vector<FlowCollisionSphere>& getSelfCollisions() {
return _selfCollisions; };
143 std::vector<FlowCollisionSphere>& getSelfTouchCollisions() {
return _selfTouchCollisions; };
144 void setOthersCollisions(
const std::vector<FlowCollisionSphere>& othersCollisions) { _othersCollisions = othersCollisions; }
145 void prepareCollisions();
146 void resetCollisions();
147 void resetOthersCollisions() { _othersCollisions.clear(); }
148 void setScale(
float scale);
149 FlowCollisionSettings getCollisionSettingsByJoint(
int jointIndex);
150 void setCollisionSettingsByJoint(
int jointIndex,
const FlowCollisionSettings& settings);
151 void setActive(
bool active) { _active = active; }
152 bool getActive()
const {
return _active; }
153 const std::vector<FlowCollisionSphere>& getCollisions()
const {
return _selfCollisions; }
154 void clearSelfCollisions() { _selfCollisions.clear(); }
156 std::vector<FlowCollisionSphere> _selfCollisions;
157 std::vector<FlowCollisionSphere> _othersCollisions;
158 std::vector<FlowCollisionSphere> _selfTouchCollisions;
159 std::vector<FlowCollisionSphere> _allCollisions;
160 float _scale { 1.0f };
161 bool _active {
false };
167 FlowNode(
const glm::vec3& initialPosition, FlowPhysicsSettings settings);
169 void update(
float deltaTime,
const glm::vec3& accelerationOffset);
170 void solve(
const glm::vec3& constrainPoint,
float maxDistance,
const FlowCollisionResult& collision);
171 void solveConstraints(
const glm::vec3& constrainPoint,
float maxDistance);
172 void solveCollisions(
const FlowCollisionResult& collision);
176 FlowPhysicsSettings _settings;
177 glm::vec3 _initialPosition;
178 glm::vec3 _previousPosition;
179 glm::vec3 _currentPosition;
181 glm::vec3 _currentVelocity;
182 glm::vec3 _previousVelocity;
183 glm::vec3 _acceleration;
185 FlowCollisionResult _collision;
186 FlowCollisionResult _previousCollision;
188 float _initialRadius { 0.0f };
190 bool _anchored {
false };
191 bool _colliding {
false };
192 bool _active {
true };
194 float _scale{ 1.0f };
197 class FlowJoint :
public FlowNode {
199 friend class FlowThread;
201 FlowJoint(): FlowNode() {};
202 FlowJoint(
int jointIndex,
int parentIndex,
int childIndex,
const QString& name,
const QString& group,
const FlowPhysicsSettings& settings);
203 void toHelperJoint(
const glm::vec3& initialPosition,
float length);
204 void setInitialData(
const glm::vec3& initialPosition,
const glm::vec3& initialTranslation,
const glm::quat& initialRotation,
const glm::vec3& parentPosition);
205 void setUpdatedData(
const glm::vec3& updatedPosition,
const glm::vec3& updatedTranslation,
const glm::quat& updatedRotation,
const glm::vec3& parentPosition,
const glm::quat& parentWorldRotation);
206 void setRecoveryPosition(
const glm::vec3& recoveryPosition);
207 void update(
float deltaTime);
208 void solve(
const FlowCollisionResult& collision);
210 void setScale(
float scale,
bool initScale);
211 bool isAnchored()
const {
return _anchored; }
212 void setAnchored(
bool anchored) { _anchored = anchored; }
213 bool isHelper()
const {
return _isHelper; }
215 const FlowPhysicsSettings& getSettings() {
return _settings; }
216 void setSettings(
const FlowPhysicsSettings& settings) { _settings = settings; _initialRadius = _settings._radius; }
218 const glm::vec3& getCurrentPosition()
const {
return _currentPosition; }
219 int getIndex()
const {
return _index; }
220 int getParentIndex()
const {
return _parentIndex; }
221 void setChildIndex(
int index) { _childIndex = index; }
222 const glm::vec3& getUpdatedPosition()
const {
return _updatedPosition; }
223 const QString& getGroup()
const {
return _group; }
224 const QString& getName()
const {
return _name; }
225 const glm::quat& getCurrentRotation()
const {
return _currentRotation; }
226 const glm::vec3& getCurrentTranslation()
const {
return _initialTranslation; }
227 const glm::vec3& getInitialPosition()
const {
return _initialPosition; }
228 const glm::quat& getInitialRotation()
const {
return _initialRotation; }
229 bool isColliding()
const {
return _colliding; }
234 int _parentIndex{ -1 };
235 int _childIndex{ -1 };
239 bool _isHelper{
false };
241 glm::vec3 _initialTranslation;
242 glm::quat _initialRotation;
244 glm::vec3 _updatedPosition;
245 glm::vec3 _updatedTranslation;
246 glm::quat _updatedRotation;
248 glm::quat _currentRotation;
249 glm::vec3 _recoveryPosition;
251 glm::vec3 _parentPosition;
252 glm::quat _parentWorldRotation;
253 glm::vec3 _translationDirection;
255 float _length { 0.0f };
256 float _initialLength { 0.0f };
258 bool _applyRecovery {
false };
264 FlowThread& operator=(
const FlowThread& otherFlowThread);
266 FlowThread(
int rootIndex, std::map<int, FlowJoint>* joints,
float rigScale);
269 void computeFlowThread(
int rootIndex);
270 void computeRecovery();
271 void update(
float deltaTime);
272 void solve(FlowCollisionSystem& collisionSystem);
273 void computeJointRotations();
274 void setRootFramePositions(
const std::vector<glm::vec3>& rootFramePositions) { _rootFramePositions = rootFramePositions; }
275 void setScale(
float scale,
bool initScale =
false);
277 std::vector<int> _joints;
278 std::vector<glm::vec3> _positions;
279 float _radius{ 0.0f };
280 float _length{ 0.0f };
282 float _rigScale { 100.0f };
283 std::map<int, FlowJoint>* _jointsPointer;
284 std::vector<glm::vec3> _rootFramePositions;
287 class Flow :
public QObject{
290 Flow(Rig *rig) : _rig (rig) {};
291 Flow& operator=(
const Flow& otherFlow);
292 bool getActive()
const {
return _active; }
293 void setActive(
bool active) { _active = active; }
294 bool isInitialized()
const {
return _initialized; }
295 float getScale()
const {
return _scale; }
296 void calculateConstraints(
const std::shared_ptr<AnimSkeleton>& skeleton, AnimPoseVec& relativePoses, AnimPoseVec& absolutePoses);
297 void update(
float deltaTime, AnimPoseVec& relativePoses, AnimPoseVec& absolutePoses,
const std::vector<bool>& overrideFlags);
298 void setTransform(
float scale,
const glm::vec3& position,
const glm::quat& rotation);
299 const std::map<int, FlowJoint>& getJoints()
const {
return _flowJointData; }
300 const std::vector<FlowThread>& getThreads()
const {
return _jointThreads; }
301 void setOthersCollision(
const QUuid& otherId,
int jointIndex,
const glm::vec3& position);
302 FlowCollisionSystem& getCollisionSystem() {
return _collisionSystem; }
303 void setPhysicsSettingsForGroup(
const QString& group,
const FlowPhysicsSettings& settings);
304 const std::map<QString, FlowPhysicsSettings>& getGroupSettings()
const {
return _groupSettings; }
306 void updateScale() { setScale(_scale); }
312 void updateAbsolutePoses(
const AnimPoseVec& relativePoses, AnimPoseVec& absolutePoses);
313 bool getJointPositionInWorldFrame(
const AnimPoseVec& absolutePoses,
int jointIndex, glm::vec3& position, glm::vec3 translation, glm::quat rotation)
const;
314 bool getJointRotationInWorldFrame(
const AnimPoseVec& absolutePoses,
int jointIndex, glm::quat& result,
const glm::quat& rotation)
const;
315 bool getJointRotation(
const AnimPoseVec& relativePoses,
int jointIndex, glm::quat& rotation)
const;
316 bool getJointTranslation(
const AnimPoseVec& relativePoses,
int jointIndex, glm::vec3& translation)
const;
317 bool worldToJointPoint(
const AnimPoseVec& absolutePoses,
const glm::vec3& position,
const int jointIndex, glm::vec3& jointSpacePosition)
const;
319 void setJoints(AnimPoseVec& relativePoses,
const std::vector<bool>& overrideFlags);
320 void updateJoints(AnimPoseVec& relativePoses, AnimPoseVec& absolutePoses);
321 void updateCollisionJoint(FlowCollisionSphere& collision, AnimPoseVec& absolutePoses);
322 bool updateRootFramePositions(
const AnimPoseVec& absolutePoses,
size_t threadIndex);
323 void updateGroupSettings(
const QString& group,
const FlowPhysicsSettings& settings);
324 void setScale(
float scale);
326 float _scale { 1.0f };
327 float _lastScale{ 1.0f };
329 Rig *_rig {
nullptr };
330 glm::vec3 _entityPosition;
331 glm::quat _entityRotation;
332 std::map<int, FlowJoint> _flowJointData;
333 std::map<QString, FlowPhysicsSettings> _groupSettings;
334 std::vector<FlowThread> _jointThreads;
335 std::vector<QString> _flowJointKeywords;
336 FlowCollisionSystem _collisionSystem;
337 bool _initialized {
false };
338 bool _active {
false };
339 bool _isScaleSet {
false };
340 bool _invertThreadLoop {
false };