Overte C++ Documentation
MultiSphereShape.h
1 //
2 // MultiSphereShape.h
3 // libraries/physics/src
4 //
5 // Created by Luis Cuenca 5/11/2018
6 // Copyright 2018 High Fidelity, Inc.
7 //
8 // Distributed under the Apache License, Version 2.0.
9 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
10 //
11 
12 #ifndef hifi_MultiSphereShape_h
13 #define hifi_MultiSphereShape_h
14 
15 #include <stdint.h>
16 #include <btBulletDynamicsCommon.h>
17 #include <GLMHelpers.h>
18 #include <AABox.h>
19 #include "BulletUtil.h"
20 
21 
22 class SphereRegion {
23 public:
24  SphereRegion() {}
25  SphereRegion(const glm::vec3& direction) : _direction(direction) {}
26  void extractSphereRegion(std::vector<std::pair<glm::vec3, glm::vec3>>& outLines);
27  void extractEdges(bool reverseY = false);
28  void translate(const glm::vec3& translation);
29  void scale(float scale);
30  void dump(std::vector<std::pair<glm::vec3, glm::vec3>>& outLines);
31  const glm::vec3& getDirection() const { return _direction; }
32  const std::vector<glm::vec3>& getEdgesX() const { return _edgesX; }
33  const std::vector<glm::vec3>& getEdgesY() const { return _edgesY; }
34  const std::vector<glm::vec3>& getEdgesZ() const { return _edgesZ; }
35 private:
36  void insertUnique(const glm::vec3& point, std::vector<glm::vec3>& pointSet);
37 
38  std::vector<std::pair<glm::vec3, glm::vec3>> _lines;
39  std::vector<glm::vec3> _edgesX;
40  std::vector<glm::vec3> _edgesY;
41  std::vector<glm::vec3> _edgesZ;
42  glm::vec3 _direction;
43 };
44 
45 const int DEFAULT_SPHERE_SUBDIVISIONS = 16;
46 
47 const std::vector<glm::vec3> CORNER_SIGNS = {
48  glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(-1.0f, 1.0f, 1.0f),
49  glm::vec3(-1.0f, 1.0f, -1.0f), glm::vec3(1.0f, 1.0f, -1.0f),
50  glm::vec3(1.0f, -1.0f, 1.0f), glm::vec3(-1.0f, -1.0f, 1.0f),
51  glm::vec3(-1.0f, -1.0f, -1.0f), glm::vec3(1.0f, -1.0f, -1.0f) };
52 
53 class MultiSphereShape {
54 public:
55  enum ExtractionMode {
56  None = 0,
57  Automatic,
58  Box,
59  Sphere,
60  SphereCollapse,
61  SpheresX,
62  SpheresY,
63  SpheresZ,
64  SpheresXY,
65  SpheresYZ,
66  SpheresXZ,
67  SpheresXYZ
68  };
69 
70  using CollapsingMode = ExtractionMode;
71  const std::vector<QString> ExtractionModeNames = {
72  "None",
73  "Automatic",
74  "Box",
75  "Sphere",
76  "SphereCollapse",
77  "SpheresX",
78  "SpheresY",
79  "SpheresZ",
80  "SpheresXY",
81  "SpheresYZ",
82  "SpheresXZ",
83  "SpheresXYZ"
84  };
85 
86  struct SphereData {
87  glm::vec3 _position;
88  glm::vec3 _axis;
89  float _radius;
90  };
91 
92  struct KdopCoefficient {
93  float xy = 0.0f;
94  float yz = 0.0f;
95  float xz = 0.0f;
96  };
97 
98  struct KdopData {
99  std::vector<glm::vec3> _relativePoints;
100  bool _isValidShape{ true };
101  glm::vec3 _origin;
102  glm::vec3 _dimensions;
103  KdopCoefficient _epsilon;
104  KdopCoefficient _diff;
105  };
106 
107  MultiSphereShape() {};
108  bool computeMultiSphereShape(int jointIndex, const QString& name, const std::vector<btVector3>& points, float scale = 1.0f);
109  void calculateDebugLines();
110  const std::vector<SphereData>& getSpheresData() const { return _spheres; }
111  const std::vector<std::pair<glm::vec3, glm::vec3>>& getDebugLines() const { return _debugLines; }
112  void setScale(float scale);
113  AABox& updateBoundingBox(const glm::vec3& position, const glm::quat& rotation);
114  const AABox& getBoundingBox() const { return _boundingBox; }
115  int getJointIndex() const { return _jointIndex; }
116  QString getJointName() const { return _jointName; }
117  bool isValid() const { return _spheres.size() > 0; }
118 
119 private:
120  KdopData getKdopData(const std::vector<btVector3>& kdop);
121  CollapsingMode computeSpheres(ExtractionMode mode, const KdopData& kdopData);
122  ExtractionMode getExtractionModeByJointName(const QString& jointName);
123  CollapsingMode getNextCollapsingMode(ExtractionMode mode, const std::vector<SphereData>& spheres);
124  QString modeToString(CollapsingMode type) { return ExtractionModeNames[(int)type]; }
125  void filterUniquePoints(const std::vector<btVector3>& kdop, std::vector<glm::vec3>& uniquePoints);
126  CollapsingMode spheresFromAxes(const std::vector<glm::vec3>& points, const std::vector<glm::vec3>& axes,
127  std::vector<SphereData>& spheres);
128 
129  void calculateSphereLines(std::vector<std::pair<glm::vec3, glm::vec3>>& outLines, const glm::vec3& center, const float& radius,
130  const int& subdivisions = DEFAULT_SPHERE_SUBDIVISIONS, const glm::vec3& direction = Vectors::UNIT_Y,
131  const float& percentage = 1.0f, std::vector<glm::vec3>* edge = nullptr);
132  void calculateChamferBox(std::vector<std::pair<glm::vec3, glm::vec3>>& outLines, const std::vector<float>& radiuses, const std::vector<glm::vec3>& axes, const glm::vec3& translation);
133  void connectEdges(std::vector<std::pair<glm::vec3, glm::vec3>>& outLines, const std::vector<glm::vec3>& edge1,
134  const std::vector<glm::vec3>& edge2, bool reverse = false);
135  void connectSpheres(int index1, int index2, bool onlyEdges = false);
136 
137  int _jointIndex { -1 };
138  QString _jointName;
139  std::vector<SphereData> _spheres;
140  std::vector<std::pair<glm::vec3, glm::vec3>> _debugLines;
141  ExtractionMode _mode { ExtractionMode::None };
142  glm::vec3 _midPoint;
143  float _scale { 1.0f };
144  AABox _boundingBox;
145 };
146 
147 #endif // hifi_MultiSphereShape_h