From a947c894c2379b9f8c1fe8abf0fdf741d39392af Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 23 Jan 2019 17:23:36 -0700 Subject: [PATCH] Suggested changes --- interface/src/avatar/AvatarManager.cpp | 59 ++++++++----------- interface/src/avatar/AvatarManager.h | 10 ++-- .../src/avatar/MyCharacterController.cpp | 11 +++- interface/src/avatar/MyCharacterController.h | 4 +- interface/src/avatar/OtherAvatar.cpp | 5 +- interface/src/raypick/RayPick.cpp | 2 +- libraries/physics/src/MultiSphereShape.cpp | 29 ++++----- libraries/physics/src/ShapeFactory.cpp | 4 +- libraries/shared/src/ShapeInfo.cpp | 4 +- libraries/shared/src/ShapeInfo.h | 2 +- 10 files changed, 68 insertions(+), 62 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 2c6f51cd4a..99ac922bc6 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -411,11 +411,8 @@ void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transact auto& detailedMotionStates = avatar->getDetailedMotionStates(); for (auto& mState : detailedMotionStates) { - if (mState) { - transaction.objectsToRemove.push_back(mState); - } + transaction.objectsToRemove.push_back(mState); } - qDebug() << "Removing " << detailedMotionStates.size() << " detailed motion states from " << avatar->getSessionUUID(); avatar->resetDetailedMotionStates(); } else { @@ -430,15 +427,12 @@ void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transact } else { failedShapeBuilds.insert(avatar); } - if (avatar->getDetailedMotionStates().size() == 0) { avatar->createDetailedMotionStates(avatar); for (auto dMotionState : avatar->getDetailedMotionStates()) { transaction.objectsToAdd.push_back(dMotionState); } } - - qDebug() << "Adding " << avatar->getDetailedMotionStates().size() << " detailed motion states from " << avatar->getSessionUUID(); } } else if (isInPhysics) { transaction.objectsToChange.push_back(avatar->_motionState); @@ -642,19 +636,17 @@ AvatarSharedPointer AvatarManager::getAvatarBySessionID(const QUuid& sessionID) RayToAvatarIntersectionResult AvatarManager::findRayIntersection(const PickRay& ray, const QScriptValue& avatarIdsToInclude, const QScriptValue& avatarIdsToDiscard, - const QScriptValue& jointIndicesToFilter, + const QStringList& jointIndicesToFilter, bool pickAgainstMesh) { QVector avatarsToInclude = qVectorEntityItemIDFromScriptValue(avatarIdsToInclude); QVector avatarsToDiscard = qVectorEntityItemIDFromScriptValue(avatarIdsToDiscard); - QVector jointsToFilter; - qVectorIntFromScriptValue(jointIndicesToFilter, jointsToFilter); - return findRayIntersectionVector(ray, avatarsToInclude, avatarsToDiscard, jointsToFilter, pickAgainstMesh); + return findRayIntersectionVector(ray, avatarsToInclude, avatarsToDiscard, jointIndicesToFilter, pickAgainstMesh); } RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const PickRay& ray, const QVector& avatarsToInclude, const QVector& avatarsToDiscard, - const QVector& jointIndicesToFilter, + const QStringList& jointIndicesToFilter, bool pickAgainstMesh) { RayToAvatarIntersectionResult result; if (QThread::currentThread() != thread()) { @@ -663,14 +655,10 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic Q_ARG(const PickRay&, ray), Q_ARG(const QVector&, avatarsToInclude), Q_ARG(const QVector&, avatarsToDiscard), - Q_ARG(const QVector&, jointIndicesToFilter), + Q_ARG(const QStringList&, jointIndicesToFilter), Q_ARG(bool, pickAgainstMesh)); return result; } - - glm::vec3 rayDirectionInv = { ray.direction.x != 0 ? 1.0f / ray.direction.x : INFINITY, - ray.direction.y != 0 ? 1.0f / ray.direction.y : INFINITY, - ray.direction.z != 0 ? 1.0f / ray.direction.z : INFINITY }; float distance = (float)INT_MAX; // with FLT_MAX bullet rayTest does not return results BoxFace face = BoxFace::UNKNOWN_FACE; @@ -681,13 +669,18 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic glm::vec3 transformedRayDirection; if (physicsResults.size() > 0) { + glm::vec3 rayDirectionInv = { ray.direction.x != 0 ? 1.0f / ray.direction.x : INFINITY, + ray.direction.y != 0.0f ? 1.0f / ray.direction.y : INFINITY, + ray.direction.z != 0.0f ? 1.0f / ray.direction.z : INFINITY }; + MyCharacterController::RayAvatarResult rayAvatarResult; AvatarPointer avatar = nullptr; for (auto &hit : physicsResults) { auto avatarID = hit._intersectWithAvatar; - bool skipThisAvatar = ((avatarsToInclude.size() > 0 && !avatarsToInclude.contains(avatarID)) || - (avatarsToDiscard.size() > 0 && avatarsToDiscard.contains(avatarID))) && jointIndicesToFilter.size() == 0; - if (skipThisAvatar) { + bool avatarIsIncluded = avatarsToInclude.contains(avatarID); + bool avatarIsDiscarded = avatarsToDiscard.contains(avatarID); + if (jointIndicesToFilter.size() == 0 && ((avatarsToInclude.size() > 0 && !avatarIsIncluded) || + (avatarsToDiscard.size() > 0 && avatarIsDiscarded))) { continue; } if (!(_myAvatar->getSessionUUID() == avatarID)) { @@ -701,16 +694,16 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic } QVector jointsToDiscard; if (avatar && jointIndicesToFilter.size() > 0) { - int jointCount = avatar->getJointCount(); - if (avatarsToInclude.size() > 0 && avatarsToInclude.contains(avatarID)) { - for (int i = 0; i < jointCount; i++) { - if (!jointIndicesToFilter.contains(i)) { + auto names = avatar->getJointNames(); + if (avatarIsIncluded) { + for (int i = 0; i < names.size(); i++) { + if (!jointIndicesToFilter.contains(names[i])) { jointsToDiscard.push_back(i); } } - } else if (avatarsToDiscard.size() > 0 && avatarsToDiscard.contains(avatarID)) { - for (int i = 0; i < jointCount; i++) { - if (jointIndicesToFilter.contains(i)) { + } else if (avatarIsDiscarded) { + for (int i = 0; i < names.size(); i++) { + if (jointIndicesToFilter.contains(names[i])) { jointsToDiscard.push_back(i); } } @@ -719,7 +712,6 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic if (!hit._isBound) { if (!jointsToDiscard.contains(hit._intersectWithJoint)) { rayAvatarResult = hit; - break; } } else if (avatar) { auto &multiSpheres = avatar->getMultiSphereShapes(); @@ -753,13 +745,9 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic }); } rayAvatarResult = boxHits[0]; - break; } } } - } - - if (rayAvatarResult._intersect) { if (pickAgainstMesh) { glm::vec3 localRayOrigin = avatar->worldToJointPoint(ray.origin, rayAvatarResult._intersectWithJoint); glm::vec3 localRayPoint = avatar->worldToJointPoint(ray.origin + ray.direction, rayAvatarResult._intersectWithJoint); @@ -769,7 +757,7 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic auto jointOrientation = avatarOrientation * avatar->getAbsoluteDefaultJointRotationInObjectFrame(rayAvatarResult._intersectWithJoint); auto jointPosition = avatarPosition + (avatarOrientation * avatar->getAbsoluteDefaultJointTranslationInObjectFrame(rayAvatarResult._intersectWithJoint)); - + auto defaultFrameRayOrigin = jointPosition + jointOrientation * localRayOrigin; auto defaultFrameRayPoint = jointPosition + jointOrientation * localRayPoint; auto defaultFrameRayDirection = defaultFrameRayPoint - defaultFrameRayOrigin; @@ -780,9 +768,14 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic rayAvatarResult._intersectionPoint = ray.origin + newDistance * glm::normalize(ray.direction); rayAvatarResult._intersectionNormal = surfaceNormal; extraInfo["worldIntersectionPoint"] = vec3toVariant(rayAvatarResult._intersectionPoint); + break; } + } else { + break; } + } + if (rayAvatarResult._intersect) { result.intersects = true; result.avatarID = rayAvatarResult._intersectWithAvatar; result.distance = rayAvatarResult._distance; diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 5bc31d74b3..4c3b06d1af 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -138,26 +138,26 @@ public: * @param {PickRay} ray * @param {Uuid[]} [avatarsToInclude=[]] * @param {Uuid[]} [avatarsToDiscard=[]] - * @param {uint[]} [jointIndicesToFilter=[] - If included/discarded avatars are provided only this joints corresponding to those avatars would be included/discarded. ] + * @param {string[]} [jointIndicesToFilter=[] - If included/discarded avatars are provided only this joints corresponding to those avatars would be included/discarded. ] * @returns {RayToAvatarIntersectionResult} */ Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersection(const PickRay& ray, const QScriptValue& avatarIdsToInclude = QScriptValue(), const QScriptValue& avatarIdsToDiscard = QScriptValue(), - const QScriptValue& jointIndicesToFilter = QScriptValue(), - bool pickAgainstMesh = false); + const QStringList& jointIndicesToFilter = QStringList(), + bool pickAgainstMesh = true); /**jsdoc * @function AvatarManager.findRayIntersectionVector * @param {PickRay} ray * @param {Uuid[]} avatarsToInclude * @param {Uuid[]} avatarsToDiscard - * @param {uint[]} [jointIndicesToFilter=[] - If included/discarded avatars are provided only this joints corresponding to those avatars would be included/discarded. ] + * @param {string[]} [jointIndicesToFilter=[] - If included/discarded avatars are provided only this joints corresponding to those avatars would be included/discarded. ] * @returns {RayToAvatarIntersectionResult} */ Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersectionVector(const PickRay& ray, const QVector& avatarsToInclude, const QVector& avatarsToDiscard, - const QVector& jointIndicesToFilter, + const QStringList& jointIndicesToFilter, bool pickAgainstMesh); /**jsdoc diff --git a/interface/src/avatar/MyCharacterController.cpp b/interface/src/avatar/MyCharacterController.cpp index f1eb59d808..7ff3a1e0ee 100755 --- a/interface/src/avatar/MyCharacterController.cpp +++ b/interface/src/avatar/MyCharacterController.cpp @@ -47,7 +47,6 @@ void MyCharacterController::updateShapeIfNecessary() { if (_pendingFlags & PENDING_FLAG_UPDATE_SHAPE) { _pendingFlags &= ~PENDING_FLAG_UPDATE_SHAPE; if (_radius > 0.0f) { - // _pendingFlags |= PENDING_FLAG_RESET_DETAILED_SHAPES; // create RigidBody if it doesn't exist if (!_rigidBody) { btCollisionShape* shape = computeShape(); @@ -378,6 +377,12 @@ DetailedMotionState* MyCharacterController::createDetailedMotionStateForJoint(in return nullptr; } +void MyCharacterController::clearDetailedMotionStates() { + _pendingFlags |= PENDING_FLAG_REMOVE_DETAILED_FROM_SIMULATION; + // We make sure we don't add them again + _pendingFlags &= ~PENDING_FLAG_ADD_DETAILED_TO_SIMULATION; +} + void MyCharacterController::resetDetailedMotionStates() { for (size_t i = 0; i < _detailedMotionStates.size(); i++) { _detailedMotionStates[i] = nullptr; @@ -455,6 +460,10 @@ std::vector MyCharacterController::rayTe result._distance = length * rayCallback.m_hitFractions[i]; result._intersectWithJoint = detailedMotionState->getJointIndex(); result._isBound = detailedMotionState->getIsBound(result._boundJoints); + btVector3 center; + btScalar radius; + detailedMotionState->getShape()->getBoundingSphere(center, radius); + result._maxDistance = (float)radius; foundAvatars.push_back(result); } } diff --git a/interface/src/avatar/MyCharacterController.h b/interface/src/avatar/MyCharacterController.h index 3c727d017c..d3a811cf8f 100644 --- a/interface/src/avatar/MyCharacterController.h +++ b/interface/src/avatar/MyCharacterController.h @@ -47,7 +47,7 @@ public: btCollisionShape* createDetailedCollisionShapeForJoint(int jointIndex); DetailedMotionState* createDetailedMotionStateForJoint(int jointIndex); std::vector& getDetailedMotionStates() { return _detailedMotionStates; } - void clearDetailedMotionStates() { _pendingFlags |= PENDING_FLAG_REMOVE_DETAILED_FROM_SIMULATION; } + void clearDetailedMotionStates(); void resetDetailedMotionStates(); void buildPhysicsTransaction(PhysicsEngine::Transaction& transaction); @@ -60,6 +60,8 @@ public: QUuid _intersectWithAvatar; int _intersectWithJoint { -1 }; float _distance { 0.0f }; + float _maxDistance { 0.0f }; + QVariantMap _extraInfo; glm::vec3 _intersectionPoint; glm::vec3 _intersectionNormal; std::vector _boundJoints; diff --git a/interface/src/avatar/OtherAvatar.cpp b/interface/src/avatar/OtherAvatar.cpp index 6447d8d8b5..a0c0aa7ae1 100644 --- a/interface/src/avatar/OtherAvatar.cpp +++ b/interface/src/avatar/OtherAvatar.cpp @@ -210,7 +210,7 @@ void OtherAvatar::setWorkloadRegion(uint8_t region) { } else { printRegion = "invalid"; } - qDebug() << "Setting workload region to " << printRegion; + qCDebug(avatars) << "Setting workload region to " << printRegion; computeShapeLOD(); } @@ -235,7 +235,7 @@ void OtherAvatar::computeShapeLOD() { if (newLOD != _bodyLOD) { _bodyLOD = newLOD; if (isInPhysicsSimulation()) { - qDebug() << "Changing to body LOD " << newLOD; + qCDebug(avatars) << "Changing to body LOD " << newLOD; _needsReinsertion = true; } } @@ -280,6 +280,7 @@ void OtherAvatar::updateCollisionGroup(bool myAvatarCollide) { } void OtherAvatar::createDetailedMotionStates(const std::shared_ptr& avatar) { + assert(detailedMotionStates.empty()); auto& detailedMotionStates = getDetailedMotionStates(); if (_bodyLOD == BodyLOD::Sphere) { auto dMotionState = createMotionState(avatar, -1); diff --git a/interface/src/raypick/RayPick.cpp b/interface/src/raypick/RayPick.cpp index 7d6c0b6eef..b9028b3a60 100644 --- a/interface/src/raypick/RayPick.cpp +++ b/interface/src/raypick/RayPick.cpp @@ -56,7 +56,7 @@ PickResultPointer RayPick::getOverlayIntersection(const PickRay& pick) { } PickResultPointer RayPick::getAvatarIntersection(const PickRay& pick) { - RayToAvatarIntersectionResult avatarRes = DependencyManager::get()->findRayIntersectionVector(pick, getIncludeItemsAs(), getIgnoreItemsAs(), QVector(), false); + RayToAvatarIntersectionResult avatarRes = DependencyManager::get()->findRayIntersectionVector(pick, getIncludeItemsAs(), getIgnoreItemsAs(), QStringList(), true); if (avatarRes.intersects) { return std::make_shared(IntersectionType::AVATAR, avatarRes.avatarID, avatarRes.distance, avatarRes.intersection, pick, avatarRes.surfaceNormal, avatarRes.extraInfo); } else { diff --git a/libraries/physics/src/MultiSphereShape.cpp b/libraries/physics/src/MultiSphereShape.cpp index 30fd4b25ea..639c8c8e90 100644 --- a/libraries/physics/src/MultiSphereShape.cpp +++ b/libraries/physics/src/MultiSphereShape.cpp @@ -25,7 +25,7 @@ void SphereRegion::dump(std::vector>& outLines) void SphereRegion::insertUnique(const glm::vec3& point, std::vector& pointSet) { auto hit = std::find_if(pointSet.begin(), pointSet.end(), [point](const glm::vec3& pointFromSet) -> bool { - return (pointFromSet == point); + return (glm::length(pointFromSet-point) < FLT_EPSILON); }); if (hit == pointSet.end()) { pointSet.push_back(point); @@ -107,7 +107,6 @@ CollisionShapeExtractionMode MultiSphereShape::getExtractionModeByName(const QSt } else if (isSim || isFlow || isEye || isToe) { mode = CollisionShapeExtractionMode::None; - //qDebug() << "Trying to add " << (int)positions.size() << " spheres for " << jointName << " length: " << maxLength; } return mode; } @@ -116,9 +115,9 @@ void MultiSphereShape::filterUniquePoints(const std::vector& kdop, st for (size_t j = 0; j < kdop.size(); j++) { btVector3 btPoint = kdop[j]; auto hit = std::find_if(uniquePoints.begin(), uniquePoints.end(), [btPoint](const glm::vec3& point) -> bool { - return (btPoint.getX() == point.x - && btPoint.getY() == point.y - && btPoint.getZ() == point.z); + return (glm::length(btPoint.getX() - point.x) < FLT_EPSILON + && glm::length(btPoint.getY() - point.y) < FLT_EPSILON + && glm::length(btPoint.getZ() - point.z) < FLT_EPSILON); }); if (hit == uniquePoints.end()) { uniquePoints.push_back(bulletToGLM(btPoint)); @@ -287,9 +286,11 @@ void MultiSphereShape::spheresFromAxes(const std::vector& points, con maxRadius = radius > maxRadius ? radius : maxRadius; } } - averageRadius /= (int)points.size(); - maxAverageRadius = averageRadius > maxAverageRadius ? averageRadius : maxAverageRadius; - minAverageRadius = averageRadius < minAverageRadius ? averageRadius : minAverageRadius; + if (points.size() > 0) { + averageRadius /= (int)points.size(); + } + maxAverageRadius = glm::max(averageRadius, maxAverageRadius); + minAverageRadius = glm::min(averageRadius, minAverageRadius); spheres[j]._radius = averageRadius; } float radiusRatio = maxRadius / maxAverageRadius; @@ -331,17 +332,17 @@ void MultiSphereShape::connectSpheres(int index1, int index2, bool onlyEdges) { auto axis = sphere1._position - sphere2._position; float angleOffset = glm::asin((sphere1._radius - sphere2._radius) / distance); - float percent1 = ((0.5f * PI) + angleOffset) / PI; - float percent2 = ((0.5f * PI) - angleOffset) / PI; + float ratio1 = ((0.5f * PI) + angleOffset) / PI; + float ratio2 = ((0.5f * PI) - angleOffset) / PI; std::vector edge1, edge2; if (onlyEdges) { std::vector> debugLines; - calculateSphereLines(debugLines, sphere1._position, sphere1._radius, DEFAULT_SPHERE_SUBDIVISIONS, glm::normalize(axis), percent1, &edge1); - calculateSphereLines(debugLines, sphere2._position, sphere2._radius, DEFAULT_SPHERE_SUBDIVISIONS, glm::normalize(-axis), percent2, &edge2); + calculateSphereLines(debugLines, sphere1._position, sphere1._radius, DEFAULT_SPHERE_SUBDIVISIONS, glm::normalize(axis), ratio1, &edge1); + calculateSphereLines(debugLines, sphere2._position, sphere2._radius, DEFAULT_SPHERE_SUBDIVISIONS, glm::normalize(-axis), ratio2, &edge2); } else { - calculateSphereLines(_debugLines, sphere1._position, sphere1._radius, DEFAULT_SPHERE_SUBDIVISIONS, glm::normalize(axis), percent1, &edge1); - calculateSphereLines(_debugLines, sphere2._position, sphere2._radius, DEFAULT_SPHERE_SUBDIVISIONS, glm::normalize(-axis), percent2, &edge2); + calculateSphereLines(_debugLines, sphere1._position, sphere1._radius, DEFAULT_SPHERE_SUBDIVISIONS, glm::normalize(axis), ratio1, &edge1); + calculateSphereLines(_debugLines, sphere2._position, sphere2._radius, DEFAULT_SPHERE_SUBDIVISIONS, glm::normalize(-axis), ratio2, &edge2); } connectEdges(_debugLines, edge1, edge2); } diff --git a/libraries/physics/src/ShapeFactory.cpp b/libraries/physics/src/ShapeFactory.cpp index e86b1da496..5808a539d6 100644 --- a/libraries/physics/src/ShapeFactory.cpp +++ b/libraries/physics/src/ShapeFactory.cpp @@ -289,8 +289,8 @@ const btCollisionShape* ShapeFactory::createShapeFromInfo(const ShapeInfo& info) std::vector radiuses; auto sphereCollection = info.getSphereCollection(); for (auto &sphereData : sphereCollection) { - positions.push_back(glmToBullet(sphereData.first)); - radiuses.push_back(sphereData.second); + positions.push_back(glmToBullet(glm::vec3(sphereData))); + radiuses.push_back(sphereData.w); } shape = new btMultiSphereShape(positions.data(), radiuses.data(), (int)positions.size()); } diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index 775849ccdc..564d79bfda 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -276,8 +276,8 @@ const HashKey& ShapeInfo::getHash() const { _hashKey.hashUint64((uint64_t)_type); if (_type == SHAPE_TYPE_MULTISPHERE) { for (auto &sphereData : _sphereCollection) { - _hashKey.hashVec3(sphereData.first); - _hashKey.hashFloat(sphereData.second); + _hashKey.hashVec3(glm::vec3(sphereData)); + _hashKey.hashFloat(sphereData.w); } } else if (_type != SHAPE_TYPE_SIMPLE_HULL) { _hashKey.hashVec3(_halfExtents); diff --git a/libraries/shared/src/ShapeInfo.h b/libraries/shared/src/ShapeInfo.h index 3bed7ef85e..d838d7b214 100644 --- a/libraries/shared/src/ShapeInfo.h +++ b/libraries/shared/src/ShapeInfo.h @@ -58,7 +58,7 @@ public: using PointList = QVector; using PointCollection = QVector; using TriangleIndices = QVector; - using SphereData = QPair; + using SphereData = glm::vec4; using SphereCollection = QVector; static QString getNameForShapeType(ShapeType type);