2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2013 Erwin Coumans http://bulletphysics.org
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
15 ///original version written by Erwin Coumans, October 2013
20 #include "LinearMath/btQuickprof.h"
21 #include "LinearMath/btAlignedObjectArray.h"
24 //#define BT_DEBUG_OSTREAM
25 #ifdef BT_DEBUG_OSTREAM
27 #include <iomanip> // std::setw
28 #endif //BT_DEBUG_OSTREAM
30 class btIntSortPredicate
33 bool operator()(const int& a, const int& b) const
42 btAlignedObjectArray<T> m_storage;
47 btVectorX(int numRows)
49 m_storage.resize(numRows);
54 m_storage.resize(rows);
62 return m_storage.size();
78 norm = btFabs((*this)[0]);
85 /* The following loop is equivalent to this call to the LAPACK
86 auxiliary routine: CALL SLASSQ( N, X, INCX, SCALE, SSQ ) */
88 for (int ix = 0; ix < nn; ix++)
90 if ((*this)[ix] != 0.0)
92 T absxi = btFabs((*this)[ix]);
97 ssq = ssq * (temp * temp) + BT_ONE;
103 temp = absxi / scale;
108 norm = scale * sqrt(ssq);
115 if (m_storage.size())
117 // for (int i=0;i<m_storage.size();i++)
119 //memset(&m_storage[0],0,sizeof(T)*m_storage.size());
120 btSetZero(&m_storage[0], m_storage.size());
123 const T& operator[](int index) const
125 return m_storage[index];
128 T& operator[](int index)
130 return m_storage[index];
133 T* getBufferPointerWritable()
135 return m_storage.size() ? &m_storage[0] : 0;
138 const T* getBufferPointer() const
140 return m_storage.size() ? &m_storage[0] : 0;
144 template <typename T>
145 void setElem(btMatrixX<T>& mat, int row, int col, T val)
147 mat.setElem(row,col,val);
151 template <typename T>
157 int m_resizeOperations;
158 int m_setElemOperations;
160 btAlignedObjectArray<T> m_storage;
161 mutable btAlignedObjectArray<btAlignedObjectArray<int> > m_rowNonZeroElements1;
163 T* getBufferPointerWritable()
165 return m_storage.size() ? &m_storage[0] : 0;
168 const T* getBufferPointer() const
170 return m_storage.size() ? &m_storage[0] : 0;
176 m_resizeOperations(0),
177 m_setElemOperations(0)
180 btMatrixX(int rows, int cols)
184 m_resizeOperations(0),
185 m_setElemOperations(0)
189 void resize(int rows, int cols)
191 m_resizeOperations++;
195 BT_PROFILE("m_storage.resize");
196 m_storage.resize(rows * cols);
207 ///we don't want this read/write operator(), because we cannot keep track of non-zero elements, use setElem instead
208 /*T& operator() (int row,int col)
210 return m_storage[col*m_rows+row];
214 void addElem(int row, int col, T val)
218 if (m_storage[col + row * m_cols] == 0.f)
220 setElem(row, col, val);
224 m_storage[row * m_cols + col] += val;
229 void setElem(int row, int col, T val)
231 m_setElemOperations++;
232 m_storage[row * m_cols + col] = val;
235 void mulElem(int row, int col, T val)
237 m_setElemOperations++;
238 //mul doesn't change sparsity info
240 m_storage[row * m_cols + col] *= val;
243 void copyLowerToUpperTriangle()
246 for (int row = 0; row < rows(); row++)
248 for (int col = 0; col < row; col++)
250 setElem(col, row, (*this)(row, col));
254 //printf("copyLowerToUpperTriangle copied %d elements out of %dx%d=%d\n", count,rows(),cols(),cols()*rows());
257 const T& operator()(int row, int col) const
259 return m_storage[col + row * m_cols];
265 BT_PROFILE("storage=0");
266 if (m_storage.size())
268 btSetZero(&m_storage[0], m_storage.size());
270 //memset(&m_storage[0],0,sizeof(T)*m_storage.size());
271 //for (int i=0;i<m_storage.size();i++)
278 btAssert(rows() == cols());
281 for (int row = 0; row < rows(); row++)
283 setElem(row, row, 1);
287 void printMatrix(const char* msg) const
289 printf("%s ---------------------\n", msg);
290 for (int i = 0; i < rows(); i++)
293 for (int j = 0; j < cols(); j++)
295 printf("%2.1f\t", (*this)(i, j));
298 printf("\n---------------------\n");
301 void rowComputeNonZeroElements() const
303 m_rowNonZeroElements1.resize(rows());
304 for (int i = 0; i < rows(); i++)
306 m_rowNonZeroElements1[i].resize(0);
307 for (int j = 0; j < cols(); j++)
309 if ((*this)(i, j) != 0.f)
311 m_rowNonZeroElements1[i].push_back(j);
316 btMatrixX transpose() const
318 //transpose is optimized for sparse matrices
319 btMatrixX tr(m_cols, m_rows);
321 for (int i = 0; i < m_cols; i++)
322 for (int j = 0; j < m_rows; j++)
333 btMatrixX operator*(const btMatrixX& other)
335 //btMatrixX*btMatrixX implementation, brute force
336 btAssert(cols() == other.rows());
338 btMatrixX res(rows(), other.cols());
340 // BT_PROFILE("btMatrixX mul");
341 for (int i = 0; i < rows(); ++i)
344 for (int j = 0; j < other.cols(); ++j)
351 for (int k = 0; k < c; k++)
354 if (other(k, j) != 0.f)
356 dotProd += w * other(k, j);
362 res.setElem(i, j, dotProd);
369 // this assumes the 4th and 8th rows of B and C are zero.
370 void multiplyAdd2_p8r(const btScalar* B, const btScalar* C, int numRows, int numRowsOther, int row, int col)
372 const btScalar* bb = B;
373 for (int i = 0; i < numRows; i++)
375 const btScalar* cc = C;
376 for (int j = 0; j < numRowsOther; j++)
380 sum += bb[1] * cc[1];
381 sum += bb[2] * cc[2];
382 sum += bb[4] * cc[4];
383 sum += bb[5] * cc[5];
384 sum += bb[6] * cc[6];
385 addElem(row + i, col + j, sum);
392 void multiply2_p8r(const btScalar* B, const btScalar* C, int numRows, int numRowsOther, int row, int col)
394 btAssert(numRows > 0 && numRowsOther > 0 && B && C);
395 const btScalar* bb = B;
396 for (int i = 0; i < numRows; i++)
398 const btScalar* cc = C;
399 for (int j = 0; j < numRowsOther; j++)
403 sum += bb[1] * cc[1];
404 sum += bb[2] * cc[2];
405 sum += bb[4] * cc[4];
406 sum += bb[5] * cc[5];
407 sum += bb[6] * cc[6];
408 setElem(row + i, col + j, sum);
415 void setSubMatrix(int rowstart, int colstart, int rowend, int colend, const T value)
417 int numRows = rowend + 1 - rowstart;
418 int numCols = colend + 1 - colstart;
420 for (int row = 0; row < numRows; row++)
422 for (int col = 0; col < numCols; col++)
424 setElem(rowstart + row, colstart + col, value);
429 void setSubMatrix(int rowstart, int colstart, int rowend, int colend, const btMatrixX& block)
431 btAssert(rowend + 1 - rowstart == block.rows());
432 btAssert(colend + 1 - colstart == block.cols());
433 for (int row = 0; row < block.rows(); row++)
435 for (int col = 0; col < block.cols(); col++)
437 setElem(rowstart + row, colstart + col, block(row, col));
441 void setSubMatrix(int rowstart, int colstart, int rowend, int colend, const btVectorX<T>& block)
443 btAssert(rowend + 1 - rowstart == block.rows());
444 btAssert(colend + 1 - colstart == block.cols());
445 for (int row = 0; row < block.rows(); row++)
447 for (int col = 0; col < block.cols(); col++)
449 setElem(rowstart + row, colstart + col, block[row]);
456 btMatrixX neg(rows(), cols());
457 for (int i = 0; i < rows(); i++)
458 for (int j = 0; j < cols(); j++)
461 neg.setElem(i, j, -v);
467 typedef btMatrixX<float> btMatrixXf;
468 typedef btVectorX<float> btVectorXf;
470 typedef btMatrixX<double> btMatrixXd;
471 typedef btVectorX<double> btVectorXd;
473 #ifdef BT_DEBUG_OSTREAM
474 template <typename T>
475 std::ostream& operator<<(std::ostream& os, const btMatrixX<T>& mat)
478 //printf("%s ---------------------\n",msg);
479 for (int i = 0; i < mat.rows(); i++)
481 for (int j = 0; j < mat.cols(); j++)
483 os << std::setw(12) << mat(i, j);
485 if (i != mat.rows() - 1)
490 //printf("\n---------------------\n");
494 template <typename T>
495 std::ostream& operator<<(std::ostream& os, const btVectorX<T>& mat)
498 //printf("%s ---------------------\n",msg);
499 for (int i = 0; i < mat.rows(); i++)
501 os << std::setw(12) << mat[i];
502 if (i != mat.rows() - 1)
507 //printf("\n---------------------\n");
512 #endif //BT_DEBUG_OSTREAM
514 inline void setElem(btMatrixXd& mat, int row, int col, double val)
516 mat.setElem(row, col, val);
519 inline void setElem(btMatrixXf& mat, int row, int col, float val)
521 mat.setElem(row, col, val);
524 #ifdef BT_USE_DOUBLE_PRECISION
525 #define btVectorXu btVectorXd
526 #define btMatrixXu btMatrixXd
528 #define btVectorXu btVectorXf
529 #define btMatrixXu btMatrixXf
530 #endif //BT_USE_DOUBLE_PRECISION
532 #endif //BT_MATRIX_H_H