btReducedVector.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. //
  2. // btReducedVectors.h
  3. // BulletLinearMath
  4. //
  5. // Created by Xuchen Han on 4/4/20.
  6. //
  7. #ifndef btReducedVectors_h
  8. #define btReducedVectors_h
  9. #include "btVector3.h"
  10. #include "btMatrix3x3.h"
  11. #include "btAlignedObjectArray.h"
  12. #include <stdio.h>
  13. #include <vector>
  14. #include <algorithm>
  15. struct TwoInts
  16. {
  17. int a,b;
  18. };
  19. inline bool operator<(const TwoInts& A, const TwoInts& B)
  20. {
  21. return A.b < B.b;
  22. }
  23. // A helper vector type used for CG projections
  24. class btReducedVector
  25. {
  26. public:
  27. btAlignedObjectArray<int> m_indices;
  28. btAlignedObjectArray<btVector3> m_vecs;
  29. int m_sz; // all m_indices value < m_sz
  30. public:
  31. btReducedVector():m_sz(0)
  32. {
  33. m_indices.resize(0);
  34. m_vecs.resize(0);
  35. m_indices.clear();
  36. m_vecs.clear();
  37. }
  38. btReducedVector(int sz): m_sz(sz)
  39. {
  40. m_indices.resize(0);
  41. m_vecs.resize(0);
  42. m_indices.clear();
  43. m_vecs.clear();
  44. }
  45. btReducedVector(int sz, const btAlignedObjectArray<int>& indices, const btAlignedObjectArray<btVector3>& vecs): m_sz(sz), m_indices(indices), m_vecs(vecs)
  46. {
  47. }
  48. void simplify()
  49. {
  50. btAlignedObjectArray<int> old_indices(m_indices);
  51. btAlignedObjectArray<btVector3> old_vecs(m_vecs);
  52. m_indices.resize(0);
  53. m_vecs.resize(0);
  54. m_indices.clear();
  55. m_vecs.clear();
  56. for (int i = 0; i < old_indices.size(); ++i)
  57. {
  58. if (old_vecs[i].length2() > SIMD_EPSILON)
  59. {
  60. m_indices.push_back(old_indices[i]);
  61. m_vecs.push_back(old_vecs[i]);
  62. }
  63. }
  64. }
  65. btReducedVector operator+(const btReducedVector& other)
  66. {
  67. btReducedVector ret(m_sz);
  68. int i=0, j=0;
  69. while (i < m_indices.size() && j < other.m_indices.size())
  70. {
  71. if (m_indices[i] < other.m_indices[j])
  72. {
  73. ret.m_indices.push_back(m_indices[i]);
  74. ret.m_vecs.push_back(m_vecs[i]);
  75. ++i;
  76. }
  77. else if (m_indices[i] > other.m_indices[j])
  78. {
  79. ret.m_indices.push_back(other.m_indices[j]);
  80. ret.m_vecs.push_back(other.m_vecs[j]);
  81. ++j;
  82. }
  83. else
  84. {
  85. ret.m_indices.push_back(other.m_indices[j]);
  86. ret.m_vecs.push_back(m_vecs[i] + other.m_vecs[j]);
  87. ++i; ++j;
  88. }
  89. }
  90. while (i < m_indices.size())
  91. {
  92. ret.m_indices.push_back(m_indices[i]);
  93. ret.m_vecs.push_back(m_vecs[i]);
  94. ++i;
  95. }
  96. while (j < other.m_indices.size())
  97. {
  98. ret.m_indices.push_back(other.m_indices[j]);
  99. ret.m_vecs.push_back(other.m_vecs[j]);
  100. ++j;
  101. }
  102. ret.simplify();
  103. return ret;
  104. }
  105. btReducedVector operator-()
  106. {
  107. btReducedVector ret(m_sz);
  108. for (int i = 0; i < m_indices.size(); ++i)
  109. {
  110. ret.m_indices.push_back(m_indices[i]);
  111. ret.m_vecs.push_back(-m_vecs[i]);
  112. }
  113. ret.simplify();
  114. return ret;
  115. }
  116. btReducedVector operator-(const btReducedVector& other)
  117. {
  118. btReducedVector ret(m_sz);
  119. int i=0, j=0;
  120. while (i < m_indices.size() && j < other.m_indices.size())
  121. {
  122. if (m_indices[i] < other.m_indices[j])
  123. {
  124. ret.m_indices.push_back(m_indices[i]);
  125. ret.m_vecs.push_back(m_vecs[i]);
  126. ++i;
  127. }
  128. else if (m_indices[i] > other.m_indices[j])
  129. {
  130. ret.m_indices.push_back(other.m_indices[j]);
  131. ret.m_vecs.push_back(-other.m_vecs[j]);
  132. ++j;
  133. }
  134. else
  135. {
  136. ret.m_indices.push_back(other.m_indices[j]);
  137. ret.m_vecs.push_back(m_vecs[i] - other.m_vecs[j]);
  138. ++i; ++j;
  139. }
  140. }
  141. while (i < m_indices.size())
  142. {
  143. ret.m_indices.push_back(m_indices[i]);
  144. ret.m_vecs.push_back(m_vecs[i]);
  145. ++i;
  146. }
  147. while (j < other.m_indices.size())
  148. {
  149. ret.m_indices.push_back(other.m_indices[j]);
  150. ret.m_vecs.push_back(-other.m_vecs[j]);
  151. ++j;
  152. }
  153. ret.simplify();
  154. return ret;
  155. }
  156. bool operator==(const btReducedVector& other) const
  157. {
  158. if (m_sz != other.m_sz)
  159. return false;
  160. if (m_indices.size() != other.m_indices.size())
  161. return false;
  162. for (int i = 0; i < m_indices.size(); ++i)
  163. {
  164. if (m_indices[i] != other.m_indices[i] || m_vecs[i] != other.m_vecs[i])
  165. {
  166. return false;
  167. }
  168. }
  169. return true;
  170. }
  171. bool operator!=(const btReducedVector& other) const
  172. {
  173. return !(*this == other);
  174. }
  175. btReducedVector& operator=(const btReducedVector& other)
  176. {
  177. if (this == &other)
  178. {
  179. return *this;
  180. }
  181. m_sz = other.m_sz;
  182. m_indices.copyFromArray(other.m_indices);
  183. m_vecs.copyFromArray(other.m_vecs);
  184. return *this;
  185. }
  186. btScalar dot(const btReducedVector& other) const
  187. {
  188. btScalar ret = 0;
  189. int j = 0;
  190. for (int i = 0; i < m_indices.size(); ++i)
  191. {
  192. while (j < other.m_indices.size() && other.m_indices[j] < m_indices[i])
  193. {
  194. ++j;
  195. }
  196. if (j < other.m_indices.size() && other.m_indices[j] == m_indices[i])
  197. {
  198. ret += m_vecs[i].dot(other.m_vecs[j]);
  199. // ++j;
  200. }
  201. }
  202. return ret;
  203. }
  204. btScalar dot(const btAlignedObjectArray<btVector3>& other) const
  205. {
  206. btScalar ret = 0;
  207. for (int i = 0; i < m_indices.size(); ++i)
  208. {
  209. ret += m_vecs[i].dot(other[m_indices[i]]);
  210. }
  211. return ret;
  212. }
  213. btScalar length2() const
  214. {
  215. return this->dot(*this);
  216. }
  217. void normalize();
  218. // returns the projection of this onto other
  219. btReducedVector proj(const btReducedVector& other) const;
  220. bool testAdd() const;
  221. bool testMinus() const;
  222. bool testDot() const;
  223. bool testMultiply() const;
  224. void test() const;
  225. void print() const
  226. {
  227. for (int i = 0; i < m_indices.size(); ++i)
  228. {
  229. printf("%d: (%f, %f, %f)/", m_indices[i], m_vecs[i][0],m_vecs[i][1],m_vecs[i][2]);
  230. }
  231. printf("\n");
  232. }
  233. void sort()
  234. {
  235. std::vector<TwoInts> tuples;
  236. for (int i = 0; i < m_indices.size(); ++i)
  237. {
  238. TwoInts ti;
  239. ti.a = i;
  240. ti.b = m_indices[i];
  241. tuples.push_back(ti);
  242. }
  243. std::sort(tuples.begin(), tuples.end());
  244. btAlignedObjectArray<int> new_indices;
  245. btAlignedObjectArray<btVector3> new_vecs;
  246. for (size_t i = 0; i < tuples.size(); ++i)
  247. {
  248. new_indices.push_back(tuples[i].b);
  249. new_vecs.push_back(m_vecs[tuples[i].a]);
  250. }
  251. m_indices = new_indices;
  252. m_vecs = new_vecs;
  253. }
  254. };
  255. SIMD_FORCE_INLINE btReducedVector operator*(const btReducedVector& v, btScalar s)
  256. {
  257. btReducedVector ret(v.m_sz);
  258. for (int i = 0; i < v.m_indices.size(); ++i)
  259. {
  260. ret.m_indices.push_back(v.m_indices[i]);
  261. ret.m_vecs.push_back(s*v.m_vecs[i]);
  262. }
  263. ret.simplify();
  264. return ret;
  265. }
  266. SIMD_FORCE_INLINE btReducedVector operator*(btScalar s, const btReducedVector& v)
  267. {
  268. return v*s;
  269. }
  270. SIMD_FORCE_INLINE btReducedVector operator/(const btReducedVector& v, btScalar s)
  271. {
  272. return v * (1.0/s);
  273. }
  274. SIMD_FORCE_INLINE btReducedVector& operator/=(btReducedVector& v, btScalar s)
  275. {
  276. v = v/s;
  277. return v;
  278. }
  279. SIMD_FORCE_INLINE btReducedVector& operator+=(btReducedVector& v1, const btReducedVector& v2)
  280. {
  281. v1 = v1+v2;
  282. return v1;
  283. }
  284. SIMD_FORCE_INLINE btReducedVector& operator-=(btReducedVector& v1, const btReducedVector& v2)
  285. {
  286. v1 = v1-v2;
  287. return v1;
  288. }
  289. #endif /* btReducedVectors_h */