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
43 btAlignedObjectArray
<T
> m_storage
;
48 btVectorX(int numRows
)
50 m_storage
.resize(numRows
);
55 m_storage
.resize(rows
);
63 return m_storage
.size();
79 norm
= btFabs((*this)[0]);
86 /* The following loop is equivalent to this call to the LAPACK
87 auxiliary routine: CALL SLASSQ( N, X, INCX, SCALE, SSQ ) */
89 for (int ix
=0;ix
<nn
;ix
++)
91 if ((*this)[ix
] != 0.0)
93 T absxi
= btFabs((*this)[ix
]);
98 ssq
= ssq
* (temp
* temp
) + BT_ONE
;
104 temp
= absxi
/ scale
;
109 norm
= scale
* sqrt(ssq
);
117 if (m_storage
.size())
119 // for (int i=0;i<m_storage.size();i++)
121 //memset(&m_storage[0],0,sizeof(T)*m_storage.size());
122 btSetZero(&m_storage
[0],m_storage
.size());
125 const T
& operator[] (int index
) const
127 return m_storage
[index
];
130 T
& operator[] (int index
)
132 return m_storage
[index
];
135 T
* getBufferPointerWritable()
137 return m_storage
.size() ? &m_storage
[0] : 0;
140 const T
* getBufferPointer() const
142 return m_storage
.size() ? &m_storage
[0] : 0;
147 template <typename T>
148 void setElem(btMatrixX<T>& mat, int row, int col, T val)
150 mat.setElem(row,col,val);
155 template <typename T
>
161 int m_resizeOperations
;
162 int m_setElemOperations
;
164 btAlignedObjectArray
<T
> m_storage
;
165 mutable btAlignedObjectArray
< btAlignedObjectArray
<int> > m_rowNonZeroElements1
;
167 T
* getBufferPointerWritable()
169 return m_storage
.size() ? &m_storage
[0] : 0;
172 const T
* getBufferPointer() const
174 return m_storage
.size() ? &m_storage
[0] : 0;
180 m_resizeOperations(0),
181 m_setElemOperations(0)
184 btMatrixX(int rows
,int cols
)
188 m_resizeOperations(0),
189 m_setElemOperations(0)
193 void resize(int rows
, int cols
)
195 m_resizeOperations
++;
199 BT_PROFILE("m_storage.resize");
200 m_storage
.resize(rows
*cols
);
211 ///we don't want this read/write operator(), because we cannot keep track of non-zero elements, use setElem instead
212 /*T& operator() (int row,int col)
214 return m_storage[col*m_rows+row];
218 void addElem(int row
,int col
, T val
)
222 if (m_storage
[col
+row
*m_cols
]==0.f
)
224 setElem(row
,col
,val
);
227 m_storage
[row
*m_cols
+col
] += val
;
233 void setElem(int row
,int col
, T val
)
235 m_setElemOperations
++;
236 m_storage
[row
*m_cols
+col
] = val
;
239 void mulElem(int row
,int col
, T val
)
241 m_setElemOperations
++;
242 //mul doesn't change sparsity info
244 m_storage
[row
*m_cols
+col
] *= val
;
250 void copyLowerToUpperTriangle()
253 for (int row
=0;row
<rows();row
++)
255 for (int col
=0;col
<row
;col
++)
257 setElem(col
,row
, (*this)(row
,col
));
262 //printf("copyLowerToUpperTriangle copied %d elements out of %dx%d=%d\n", count,rows(),cols(),cols()*rows());
265 const T
& operator() (int row
,int col
) const
267 return m_storage
[col
+row
*m_cols
];
274 BT_PROFILE("storage=0");
275 btSetZero(&m_storage
[0],m_storage
.size());
276 //memset(&m_storage[0],0,sizeof(T)*m_storage.size());
277 //for (int i=0;i<m_storage.size();i++)
284 btAssert(rows() == cols());
287 for (int row
=0;row
<rows();row
++)
295 void printMatrix(const char* msg
)
297 printf("%s ---------------------\n",msg
);
298 for (int i
=0;i
<rows();i
++)
301 for (int j
=0;j
<cols();j
++)
303 printf("%2.1f\t",(*this)(i
,j
));
306 printf("\n---------------------\n");
311 void rowComputeNonZeroElements() const
313 m_rowNonZeroElements1
.resize(rows());
314 for (int i
=0;i
<rows();i
++)
316 m_rowNonZeroElements1
[i
].resize(0);
317 for (int j
=0;j
<cols();j
++)
319 if ((*this)(i
,j
)!=0.f
)
321 m_rowNonZeroElements1
[i
].push_back(j
);
326 btMatrixX
transpose() const
328 //transpose is optimized for sparse matrices
329 btMatrixX
tr(m_cols
,m_rows
);
331 for (int i
=0;i
<m_cols
;i
++)
332 for (int j
=0;j
<m_rows
;j
++)
344 btMatrixX
operator*(const btMatrixX
& other
)
346 //btMatrixX*btMatrixX implementation, brute force
347 btAssert(cols() == other
.rows());
349 btMatrixX
res(rows(),other
.cols());
351 // BT_PROFILE("btMatrixX mul");
352 for (int j
=0; j
< res
.cols(); ++j
)
355 for (int i
=0; i
< res
.rows(); ++i
)
359 //int waste=0,waste2=0;
362 // bool useOtherCol = true;
364 for (int v
=0;v
<rows();v
++)
369 dotProd
+=w
*other(v
,j
);
376 res
.setElem(i
,j
,dotProd
);
383 // this assumes the 4th and 8th rows of B and C are zero.
384 void multiplyAdd2_p8r (const btScalar
*B
, const btScalar
*C
, int numRows
, int numRowsOther
,int row
, int col
)
386 const btScalar
*bb
= B
;
387 for ( int i
= 0;i
<numRows
;i
++)
389 const btScalar
*cc
= C
;
390 for ( int j
= 0;j
<numRowsOther
;j
++)
399 addElem(row
+i
,col
+j
,sum
);
406 void multiply2_p8r (const btScalar
*B
, const btScalar
*C
, int numRows
, int numRowsOther
, int row
, int col
)
408 btAssert (numRows
>0 && numRowsOther
>0 && B
&& C
);
409 const btScalar
*bb
= B
;
410 for ( int i
= 0;i
<numRows
;i
++)
412 const btScalar
*cc
= C
;
413 for ( int j
= 0;j
<numRowsOther
;j
++)
422 setElem(row
+i
,col
+j
,sum
);
429 void setSubMatrix(int rowstart
,int colstart
,int rowend
,int colend
,const T value
)
431 int numRows
= rowend
+1-rowstart
;
432 int numCols
= colend
+1-colstart
;
434 for (int row
=0;row
<numRows
;row
++)
436 for (int col
=0;col
<numCols
;col
++)
438 setElem(rowstart
+row
,colstart
+col
,value
);
443 void setSubMatrix(int rowstart
,int colstart
,int rowend
,int colend
,const btMatrixX
& block
)
445 btAssert(rowend
+1-rowstart
== block
.rows());
446 btAssert(colend
+1-colstart
== block
.cols());
447 for (int row
=0;row
<block
.rows();row
++)
449 for (int col
=0;col
<block
.cols();col
++)
451 setElem(rowstart
+row
,colstart
+col
,block(row
,col
));
455 void setSubMatrix(int rowstart
,int colstart
,int rowend
,int colend
,const btVectorX
<T
>& block
)
457 btAssert(rowend
+1-rowstart
== block
.rows());
458 btAssert(colend
+1-colstart
== block
.cols());
459 for (int row
=0;row
<block
.rows();row
++)
461 for (int col
=0;col
<block
.cols();col
++)
463 setElem(rowstart
+row
,colstart
+col
,block
[row
]);
471 btMatrixX
neg(rows(),cols());
472 for (int i
=0;i
<rows();i
++)
473 for (int j
=0;j
<cols();j
++)
485 typedef btMatrixX
<float> btMatrixXf
;
486 typedef btVectorX
<float> btVectorXf
;
488 typedef btMatrixX
<double> btMatrixXd
;
489 typedef btVectorX
<double> btVectorXd
;
492 #ifdef BT_DEBUG_OSTREAM
493 template <typename T
>
494 std::ostream
& operator<< (std::ostream
& os
, const btMatrixX
<T
>& mat
)
498 //printf("%s ---------------------\n",msg);
499 for (int i
=0;i
<mat
.rows();i
++)
501 for (int j
=0;j
<mat
.cols();j
++)
503 os
<< std::setw(12) << mat(i
,j
);
506 os
<< std::endl
<< " ";
509 //printf("\n---------------------\n");
513 template <typename T
>
514 std::ostream
& operator<< (std::ostream
& os
, const btVectorX
<T
>& mat
)
518 //printf("%s ---------------------\n",msg);
519 for (int i
=0;i
<mat
.rows();i
++)
521 os
<< std::setw(12) << mat
[i
];
523 os
<< std::endl
<< " ";
526 //printf("\n---------------------\n");
531 #endif //BT_DEBUG_OSTREAM
534 inline void setElem(btMatrixXd
& mat
, int row
, int col
, double val
)
536 mat
.setElem(row
,col
,val
);
539 inline void setElem(btMatrixXf
& mat
, int row
, int col
, float val
)
541 mat
.setElem(row
,col
,val
);
544 #ifdef BT_USE_DOUBLE_PRECISION
545 #define btVectorXu btVectorXd
546 #define btMatrixXu btMatrixXd
548 #define btVectorXu btVectorXf
549 #define btMatrixXu btMatrixXf
550 #endif //BT_USE_DOUBLE_PRECISION
554 #endif//BT_MATRIX_H_H