5 // Created by Xuchen Han on 4/4/20.
7 #ifndef btReducedVectors_h
8 #define btReducedVectors_h
10 #include "btMatrix3x3.h"
11 #include "btAlignedObjectArray.h"
19 inline bool operator<(const TwoInts& A, const TwoInts& B)
25 // A helper vector type used for CG projections
29 btAlignedObjectArray<int> m_indices;
30 btAlignedObjectArray<btVector3> m_vecs;
31 int m_sz; // all m_indices value < m_sz
33 btReducedVector():m_sz(0)
41 btReducedVector(int sz): m_sz(sz)
49 btReducedVector(int sz, const btAlignedObjectArray<int>& indices, const btAlignedObjectArray<btVector3>& vecs): m_sz(sz), m_indices(indices), m_vecs(vecs)
55 btAlignedObjectArray<int> old_indices(m_indices);
56 btAlignedObjectArray<btVector3> old_vecs(m_vecs);
61 for (int i = 0; i < old_indices.size(); ++i)
63 if (old_vecs[i].length2() > SIMD_EPSILON)
65 m_indices.push_back(old_indices[i]);
66 m_vecs.push_back(old_vecs[i]);
71 btReducedVector operator+(const btReducedVector& other)
73 btReducedVector ret(m_sz);
75 while (i < m_indices.size() && j < other.m_indices.size())
77 if (m_indices[i] < other.m_indices[j])
79 ret.m_indices.push_back(m_indices[i]);
80 ret.m_vecs.push_back(m_vecs[i]);
83 else if (m_indices[i] > other.m_indices[j])
85 ret.m_indices.push_back(other.m_indices[j]);
86 ret.m_vecs.push_back(other.m_vecs[j]);
91 ret.m_indices.push_back(other.m_indices[j]);
92 ret.m_vecs.push_back(m_vecs[i] + other.m_vecs[j]);
96 while (i < m_indices.size())
98 ret.m_indices.push_back(m_indices[i]);
99 ret.m_vecs.push_back(m_vecs[i]);
102 while (j < other.m_indices.size())
104 ret.m_indices.push_back(other.m_indices[j]);
105 ret.m_vecs.push_back(other.m_vecs[j]);
112 btReducedVector operator-()
114 btReducedVector ret(m_sz);
115 for (int i = 0; i < m_indices.size(); ++i)
117 ret.m_indices.push_back(m_indices[i]);
118 ret.m_vecs.push_back(-m_vecs[i]);
124 btReducedVector operator-(const btReducedVector& other)
126 btReducedVector ret(m_sz);
128 while (i < m_indices.size() && j < other.m_indices.size())
130 if (m_indices[i] < other.m_indices[j])
132 ret.m_indices.push_back(m_indices[i]);
133 ret.m_vecs.push_back(m_vecs[i]);
136 else if (m_indices[i] > other.m_indices[j])
138 ret.m_indices.push_back(other.m_indices[j]);
139 ret.m_vecs.push_back(-other.m_vecs[j]);
144 ret.m_indices.push_back(other.m_indices[j]);
145 ret.m_vecs.push_back(m_vecs[i] - other.m_vecs[j]);
149 while (i < m_indices.size())
151 ret.m_indices.push_back(m_indices[i]);
152 ret.m_vecs.push_back(m_vecs[i]);
155 while (j < other.m_indices.size())
157 ret.m_indices.push_back(other.m_indices[j]);
158 ret.m_vecs.push_back(-other.m_vecs[j]);
165 bool operator==(const btReducedVector& other) const
167 if (m_sz != other.m_sz)
169 if (m_indices.size() != other.m_indices.size())
171 for (int i = 0; i < m_indices.size(); ++i)
173 if (m_indices[i] != other.m_indices[i] || m_vecs[i] != other.m_vecs[i])
181 bool operator!=(const btReducedVector& other) const
183 return !(*this == other);
186 btReducedVector& operator=(const btReducedVector& other)
193 m_indices.copyFromArray(other.m_indices);
194 m_vecs.copyFromArray(other.m_vecs);
198 btScalar dot(const btReducedVector& other) const
202 for (int i = 0; i < m_indices.size(); ++i)
204 while (j < other.m_indices.size() && other.m_indices[j] < m_indices[i])
208 if (j < other.m_indices.size() && other.m_indices[j] == m_indices[i])
210 ret += m_vecs[i].dot(other.m_vecs[j]);
217 btScalar dot(const btAlignedObjectArray<btVector3>& other) const
220 for (int i = 0; i < m_indices.size(); ++i)
222 ret += m_vecs[i].dot(other[m_indices[i]]);
227 btScalar length2() const
229 return this->dot(*this);
234 // returns the projection of this onto other
235 btReducedVector proj(const btReducedVector& other) const;
237 bool testAdd() const;
239 bool testMinus() const;
241 bool testDot() const;
243 bool testMultiply() const;
249 for (int i = 0; i < m_indices.size(); ++i)
251 printf("%d: (%f, %f, %f)/", m_indices[i], m_vecs[i][0],m_vecs[i][1],m_vecs[i][2]);
259 std::vector<TwoInts> tuples;
260 for (int i = 0; i < m_indices.size(); ++i)
265 tuples.push_back(ti);
267 std::sort(tuples.begin(), tuples.end());
268 btAlignedObjectArray<int> new_indices;
269 btAlignedObjectArray<btVector3> new_vecs;
270 for (size_t i = 0; i < tuples.size(); ++i)
272 new_indices.push_back(tuples[i].b);
273 new_vecs.push_back(m_vecs[tuples[i].a]);
275 m_indices = new_indices;
280 SIMD_FORCE_INLINE btReducedVector operator*(const btReducedVector& v, btScalar s)
282 btReducedVector ret(v.m_sz);
283 for (int i = 0; i < v.m_indices.size(); ++i)
285 ret.m_indices.push_back(v.m_indices[i]);
286 ret.m_vecs.push_back(s*v.m_vecs[i]);
292 SIMD_FORCE_INLINE btReducedVector operator*(btScalar s, const btReducedVector& v)
297 SIMD_FORCE_INLINE btReducedVector operator/(const btReducedVector& v, btScalar s)
302 SIMD_FORCE_INLINE btReducedVector& operator/=(btReducedVector& v, btScalar s)
308 SIMD_FORCE_INLINE btReducedVector& operator+=(btReducedVector& v1, const btReducedVector& v2)
314 SIMD_FORCE_INLINE btReducedVector& operator-=(btReducedVector& v1, const btReducedVector& v2)
320 #endif /* btReducedVectors_h */