// // MultiSphereShape.h // libraries/physics/src // // Created by Luis Cuenca 5/11/2018 // Copyright 2018 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #ifndef hifi_MultiSphereShape_h #define hifi_MultiSphereShape_h #include #include #include #include #include "BulletUtil.h" class SphereRegion { public: SphereRegion() {} SphereRegion(const glm::vec3& direction) : _direction(direction) {} void extractSphereRegion(std::vector>& outLines); void extractEdges(bool reverseY = false); void translate(const glm::vec3& translation); void scale(float scale); void dump(std::vector>& outLines); const glm::vec3& getDirection() const { return _direction; } const std::vector& getEdgesX() const { return _edgesX; } const std::vector& getEdgesY() const { return _edgesY; } const std::vector& getEdgesZ() const { return _edgesZ; } private: void insertUnique(const glm::vec3& point, std::vector& pointSet); std::vector> _lines; std::vector _edgesX; std::vector _edgesY; std::vector _edgesZ; glm::vec3 _direction; }; const int DEFAULT_SPHERE_SUBDIVISIONS = 16; const std::vector CORNER_SIGNS = { glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(-1.0f, 1.0f, 1.0f), glm::vec3(-1.0f, 1.0f, -1.0f), glm::vec3(1.0f, 1.0f, -1.0f), glm::vec3(1.0f, -1.0f, 1.0f), glm::vec3(-1.0f, -1.0f, 1.0f), glm::vec3(-1.0f, -1.0f, -1.0f), glm::vec3(1.0f, -1.0f, -1.0f) }; class MultiSphereShape { public: enum ExtractionMode { None = 0, Automatic, Box, Sphere, SphereCollapse, SpheresX, SpheresY, SpheresZ, SpheresXY, SpheresYZ, SpheresXZ, SpheresXYZ }; using CollapsingMode = ExtractionMode; const std::vector ExtractionModeNames = { "None", "Automatic", "Box", "Sphere", "SphereCollapse", "SpheresX", "SpheresY", "SpheresZ", "SpheresXY", "SpheresYZ", "SpheresXZ", "SpheresXYZ" }; struct SphereData { glm::vec3 _position; glm::vec3 _axis; float _radius; }; struct KdopCoefficient { float xy = 0.0f; float yz = 0.0f; float xz = 0.0f; }; struct KdopData { std::vector _relativePoints; bool _isValidShape{ true }; glm::vec3 _origin; glm::vec3 _dimensions; KdopCoefficient _epsilon; KdopCoefficient _diff; }; MultiSphereShape() {}; bool computeMultiSphereShape(int jointIndex, const QString& name, const std::vector& points, float scale = 1.0f); void calculateDebugLines(); const std::vector& getSpheresData() const { return _spheres; } const std::vector>& getDebugLines() const { return _debugLines; } void setScale(float scale); AABox& updateBoundingBox(const glm::vec3& position, const glm::quat& rotation); const AABox& getBoundingBox() const { return _boundingBox; } int getJointIndex() const { return _jointIndex; } QString getJointName() const { return _jointName; } bool isValid() const { return _spheres.size() > 0; } private: KdopData getKdopData(const std::vector& kdop); CollapsingMode computeSpheres(ExtractionMode mode, const KdopData& kdopData); ExtractionMode getExtractionModeByJointName(const QString& jointName); CollapsingMode getNextCollapsingMode(ExtractionMode mode, const std::vector& spheres); QString modeToString(CollapsingMode type) { return ExtractionModeNames[(int)type]; } void filterUniquePoints(const std::vector& kdop, std::vector& uniquePoints); CollapsingMode spheresFromAxes(const std::vector& points, const std::vector& axes, std::vector& spheres); void calculateSphereLines(std::vector>& outLines, const glm::vec3& center, const float& radius, const int& subdivisions = DEFAULT_SPHERE_SUBDIVISIONS, const glm::vec3& direction = Vectors::UNIT_Y, const float& percentage = 1.0f, std::vector* edge = nullptr); void calculateChamferBox(std::vector>& outLines, const std::vector& radiuses, const std::vector& axes, const glm::vec3& translation); void connectEdges(std::vector>& outLines, const std::vector& edge1, const std::vector& edge2, bool reverse = false); void connectSpheres(int index1, int index2, bool onlyEdges = false); int _jointIndex { -1 }; QString _jointName; std::vector _spheres; std::vector> _debugLines; ExtractionMode _mode { ExtractionMode::None }; glm::vec3 _midPoint; float _scale { 1.0f }; AABox _boundingBox; }; #endif // hifi_MultiSphereShape_h