diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 9211be3b4f..ecf904c7f4 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -5381,7 +5381,7 @@ void MyAvatar::useFlow(bool isActive, bool isCollidable, const QVariantMap& phys } auto collisionJoints = collisionsConfig.keys(); if (collisionJoints.size() > 0) { - collisionSystem.resetCollisions(); + collisionSystem.clearSelfCollisions(); for (auto &jointName : collisionJoints) { int jointIndex = getJointIndex(jointName); FlowCollisionSettings collisionsSettings; @@ -5396,6 +5396,7 @@ void MyAvatar::useFlow(bool isActive, bool isCollidable, const QVariantMap& phys collisionSystem.addCollisionSphere(jointIndex, collisionsSettings); } } + flow.updateScale(); } } diff --git a/libraries/animation/src/Flow.cpp b/libraries/animation/src/Flow.cpp index 5bc2021e5e..1f9e72bf28 100644 --- a/libraries/animation/src/Flow.cpp +++ b/libraries/animation/src/Flow.cpp @@ -67,17 +67,23 @@ void FlowCollisionSystem::addCollisionSphere(int jointIndex, const FlowCollision auto collision = FlowCollisionSphere(jointIndex, settings, isTouch); collision.setPosition(position); if (isSelfCollision) { - _selfCollisions.push_back(collision); + if (!isTouch) { + _selfCollisions.push_back(collision); + } else { + _selfTouchCollisions.push_back(collision); + } } else { _othersCollisions.push_back(collision); } - }; + void FlowCollisionSystem::resetCollisions() { _allCollisions.clear(); _othersCollisions.clear(); + _selfTouchCollisions.clear(); _selfCollisions.clear(); } + FlowCollisionResult FlowCollisionSystem::computeCollision(const std::vector collisions) { FlowCollisionResult result; if (collisions.size() > 1) { @@ -106,6 +112,10 @@ void FlowCollisionSystem::setScale(float scale) { _selfCollisions[j]._radius = _selfCollisions[j]._initialRadius * scale; _selfCollisions[j]._offset = _selfCollisions[j]._initialOffset * scale; } + for (size_t j = 0; j < _selfTouchCollisions.size(); j++) { + _selfTouchCollisions[j]._radius = _selfTouchCollisions[j]._initialRadius * scale; + _selfTouchCollisions[j]._offset = _selfTouchCollisions[j]._initialOffset * scale; + } }; std::vector FlowCollisionSystem::checkFlowThreadCollisions(FlowThread* flowThread) { @@ -178,9 +188,9 @@ void FlowCollisionSystem::setCollisionSettingsByJoint(int jointIndex, const Flow } void FlowCollisionSystem::prepareCollisions() { _allCollisions.clear(); - _allCollisions.resize(_selfCollisions.size() + _othersCollisions.size()); - std::copy(_selfCollisions.begin(), _selfCollisions.begin() + _selfCollisions.size(), _allCollisions.begin()); - std::copy(_othersCollisions.begin(), _othersCollisions.begin() + _othersCollisions.size(), _allCollisions.begin() + _selfCollisions.size()); + _allCollisions.insert(_allCollisions.end(), _selfCollisions.begin(), _selfCollisions.end()); + _allCollisions.insert(_allCollisions.end(), _othersCollisions.begin(), _othersCollisions.end()); + _allCollisions.insert(_allCollisions.end(), _selfTouchCollisions.begin(), _selfTouchCollisions.end()); _othersCollisions.clear(); } @@ -273,18 +283,20 @@ void FlowJoint::setRecoveryPosition(const glm::vec3& recoveryPosition) { } void FlowJoint::update(float deltaTime) { - glm::vec3 accelerationOffset = glm::vec3(0.0f); - if (_settings._stiffness > 0.0f) { - glm::vec3 recoveryVector = _recoveryPosition - _currentPosition; - float recoveryFactor = powf(_settings._stiffness, 3.0f); - accelerationOffset = recoveryVector * recoveryFactor; - } - FlowNode::update(deltaTime, accelerationOffset); - if (_anchored) { - if (!_isHelper) { - _currentPosition = _updatedPosition; - } else { - _currentPosition = _parentPosition; + if (_settings._active) { + glm::vec3 accelerationOffset = glm::vec3(0.0f); + if (_settings._stiffness > 0.0f) { + glm::vec3 recoveryVector = _recoveryPosition - _currentPosition; + float recoveryFactor = powf(_settings._stiffness, 3.0f); + accelerationOffset = recoveryVector * recoveryFactor; + } + FlowNode::update(deltaTime, accelerationOffset); + if (_anchored) { + if (!_isHelper) { + _currentPosition = _updatedPosition; + } else { + _currentPosition = _parentPosition; + } } } }; @@ -674,6 +686,14 @@ bool Flow::updateRootFramePositions(const AnimPoseVec& absolutePoses, size_t thr return true; } +void Flow::updateCollisionJoint(FlowCollisionSphere& collision, AnimPoseVec& absolutePoses) { + glm::quat jointRotation; + getJointPositionInWorldFrame(absolutePoses, collision._jointIndex, collision._position, _entityPosition, _entityRotation); + getJointRotationInWorldFrame(absolutePoses, collision._jointIndex, jointRotation, _entityRotation); + glm::vec3 worldOffset = jointRotation * collision._offset; + collision._position = collision._position + worldOffset; +} + void Flow::updateJoints(AnimPoseVec& relativePoses, AnimPoseVec& absolutePoses) { updateAbsolutePoses(relativePoses, absolutePoses); for (auto &jointData : _flowJointData) { @@ -695,11 +715,11 @@ void Flow::updateJoints(AnimPoseVec& relativePoses, AnimPoseVec& absolutePoses) } auto &selfCollisions = _collisionSystem.getSelfCollisions(); for (auto &collision : selfCollisions) { - glm::quat jointRotation; - getJointPositionInWorldFrame(absolutePoses, collision._jointIndex, collision._position, _entityPosition, _entityRotation); - getJointRotationInWorldFrame(absolutePoses, collision._jointIndex, jointRotation, _entityRotation); - glm::vec3 worldOffset = jointRotation * collision._offset; - collision._position = collision._position + worldOffset; + updateCollisionJoint(collision, absolutePoses); + } + auto &selfTouchCollisions = _collisionSystem.getSelfTouchCollisions(); + for (auto &collision : selfTouchCollisions) { + updateCollisionJoint(collision, absolutePoses); } _collisionSystem.prepareCollisions(); } @@ -710,7 +730,7 @@ void Flow::setJoints(AnimPoseVec& relativePoses, const std::vector& overri for (int jointIndex : joints) { auto &joint = _flowJointData[jointIndex]; if (jointIndex >= 0 && jointIndex < (int)relativePoses.size() && !overrideFlags[jointIndex]) { - relativePoses[jointIndex].rot() = joint.getCurrentRotation(); + relativePoses[jointIndex].rot() = joint.getSettings()._active ? joint.getCurrentRotation() : joint.getInitialRotation(); } } } diff --git a/libraries/animation/src/Flow.h b/libraries/animation/src/Flow.h index ad81c2be77..5dc1a3ba3e 100644 --- a/libraries/animation/src/Flow.h +++ b/libraries/animation/src/Flow.h @@ -140,6 +140,7 @@ public: std::vector checkFlowThreadCollisions(FlowThread* flowThread); std::vector& getSelfCollisions() { return _selfCollisions; }; + std::vector& getSelfTouchCollisions() { return _selfTouchCollisions; }; void setOthersCollisions(const std::vector& othersCollisions) { _othersCollisions = othersCollisions; } void prepareCollisions(); void resetCollisions(); @@ -150,9 +151,11 @@ public: void setActive(bool active) { _active = active; } bool getActive() const { return _active; } const std::vector& getCollisions() const { return _selfCollisions; } + void clearSelfCollisions() { _selfCollisions.clear(); } protected: std::vector _selfCollisions; std::vector _othersCollisions; + std::vector _selfTouchCollisions; std::vector _allCollisions; float _scale { 1.0f }; bool _active { false }; @@ -210,7 +213,7 @@ public: bool isHelper() const { return _isHelper; } const FlowPhysicsSettings& getSettings() { return _settings; } - void setSettings(const FlowPhysicsSettings& settings) { _settings = settings; } + void setSettings(const FlowPhysicsSettings& settings) { _settings = settings; _initialRadius = _settings._radius; } const glm::vec3& getCurrentPosition() const { return _currentPosition; } int getIndex() const { return _index; } @@ -222,6 +225,7 @@ public: const glm::quat& getCurrentRotation() const { return _currentRotation; } const glm::vec3& getCurrentTranslation() const { return _initialTranslation; } const glm::vec3& getInitialPosition() const { return _initialPosition; } + const glm::quat& getInitialRotation() const { return _initialRotation; } bool isColliding() const { return _colliding; } protected: @@ -297,6 +301,7 @@ public: void setPhysicsSettingsForGroup(const QString& group, const FlowPhysicsSettings& settings); const std::map& getGroupSettings() const { return _groupSettings; } void cleanUp(); + void updateScale() { setScale(_scale); } signals: void onCleanup(); @@ -311,6 +316,7 @@ private: void setJoints(AnimPoseVec& relativePoses, const std::vector& overrideFlags); void updateJoints(AnimPoseVec& relativePoses, AnimPoseVec& absolutePoses); + void updateCollisionJoint(FlowCollisionSphere& collision, AnimPoseVec& absolutePoses); bool updateRootFramePositions(const AnimPoseVec& absolutePoses, size_t threadIndex); void updateGroupSettings(const QString& group, const FlowPhysicsSettings& settings); void setScale(float scale);