diff options
Diffstat (limited to 'extern/bullet2/src/LinearMath')
20 files changed, 616 insertions, 315 deletions
diff --git a/extern/bullet2/src/LinearMath/btAabbUtil2.h b/extern/bullet2/src/LinearMath/btAabbUtil2.h index 2eacb8e242b..429163c8138 100644 --- a/extern/bullet2/src/LinearMath/btAabbUtil2.h +++ b/extern/bullet2/src/LinearMath/btAabbUtil2.h @@ -17,8 +17,8 @@ subject to the following restrictions: #ifndef AABB_UTIL2 #define AABB_UTIL2 -#include "LinearMath/btVector3.h" -#include "LinearMath/btSimdMinMax.h" +#include "btVector3.h" +#include "btSimdMinMax.h" #define btMin(a,b) ((a < b ? a : b)) @@ -73,8 +73,8 @@ SIMD_FORCE_INLINE bool btRayAabb(const btVector3& rayFrom, const btVector3& aabbMax, btScalar& param, btVector3& normal) { - btVector3 aabbHalfExtent = (aabbMax-aabbMin)* 0.5f; - btVector3 aabbCenter = (aabbMax+aabbMin)* 0.5f; + btVector3 aabbHalfExtent = (aabbMax-aabbMin)* btScalar(0.5); + btVector3 aabbCenter = (aabbMax+aabbMin)* btScalar(0.5); btVector3 source = rayFrom - aabbCenter; btVector3 target = rayTo - aabbCenter; int sourceOutcode = btOutcode(source,aabbHalfExtent); @@ -110,7 +110,7 @@ SIMD_FORCE_INLINE bool btRayAabb(const btVector3& rayFrom, } bit<<=1; } - normSign = -1.f; + normSign = btScalar(-1.); } if (lambda_enter <= lambda_exit) { diff --git a/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp b/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp index 19b811b0ce8..1f5877fa37e 100644 --- a/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp +++ b/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp @@ -16,7 +16,7 @@ subject to the following restrictions: #include "btAlignedAllocator.h" -#if defined (WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) +#if defined (BT_HAS_ALIGNED_ALOCATOR) #include <malloc.h> void* btAlignedAlloc (int size, int alignment) @@ -31,6 +31,26 @@ void btAlignedFree (void* ptr) #else +#ifdef __CELLOS_LV2__ + +#include <stdlib.h> + +int numAllocs = 0; +int numFree = 0; + +void* btAlignedAlloc (int size, int alignment) +{ + numAllocs++; + return memalign(alignment, size); +} + +void btAlignedFree (void* ptr) +{ + numFree++; + free(ptr); +} + +#else ///todo ///will add some multi-platform version that works without _aligned_malloc/_aligned_free @@ -41,7 +61,10 @@ void* btAlignedAlloc (int size, int alignment) void btAlignedFree (void* ptr) { - delete ptr; + delete [] (char*) ptr; } +#endif // #endif + + diff --git a/extern/bullet2/src/LinearMath/btAlignedAllocator.h b/extern/bullet2/src/LinearMath/btAlignedAllocator.h index 159399ce7d4..07585717f45 100644 --- a/extern/bullet2/src/LinearMath/btAlignedAllocator.h +++ b/extern/bullet2/src/LinearMath/btAlignedAllocator.h @@ -36,11 +36,13 @@ class btAlignedAllocator { typedef btAlignedAllocator< T , Alignment > self_type; public: + //just going down a list: btAlignedAllocator() {} - + /* btAlignedAllocator( const self_type & ) {} - + */ + template < typename Other > btAlignedAllocator( const btAlignedAllocator< Other , Alignment > & ) {} @@ -53,6 +55,7 @@ public: pointer address ( reference ref ) const { return &ref; } const_pointer address ( const_reference ref ) const { return &ref; } pointer allocate ( size_type n , const_pointer * hint = 0 ) { + (void)hint; return reinterpret_cast< pointer >(btAlignedAlloc( sizeof(value_type) * n , Alignment )); } void construct ( pointer ptr , const value_type & value ) { new (ptr) value_type( value ); } diff --git a/extern/bullet2/src/LinearMath/btAlignedObjectArray.h b/extern/bullet2/src/LinearMath/btAlignedObjectArray.h index 3bfdb36f4c7..8bef5eb5d06 100644 --- a/extern/bullet2/src/LinearMath/btAlignedObjectArray.h +++ b/extern/bullet2/src/LinearMath/btAlignedObjectArray.h @@ -20,18 +20,37 @@ subject to the following restrictions: #include "btScalar.h" // has definitions like SIMD_FORCE_INLINE #include "btAlignedAllocator.h" +///If the platform doesn't support placement new, you can disable BT_USE_PLACEMENT_NEW +///then the btAlignedObjectArray doesn't support objects with virtual methods, and non-trivial constructors/destructors +///You can enable BT_USE_MEMCPY, then swapping elements in the array will use memcpy instead of operator= +///see discussion here: http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1231 and +///http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1240 + +#define BT_USE_PLACEMENT_NEW 1 +//#define BT_USE_MEMCPY 1 //disable, because it is cumbersome to find out for each platform where memcpy is defined. It can be in <memory.h> or <string.h> or otherwise... + +#ifdef BT_USE_MEMCPY +#include <memory.h> +#include <string.h> +#endif //BT_USE_MEMCPY + +#ifdef BT_USE_PLACEMENT_NEW +#include <new> //for placement new +#endif //BT_USE_PLACEMENT_NEW + + ///btAlignedObjectArray uses a subset of the stl::vector interface for its methods ///It is developed to replace stl::vector to avoid STL alignment issues to add SIMD/SSE data template <typename T> //template <class T> class btAlignedObjectArray { + btAlignedAllocator<T , 16> m_allocator; + int m_size; int m_capacity; T* m_data; - btAlignedAllocator<T , 16> m_allocator; - protected: SIMD_FORCE_INLINE int allocSize(int size) { @@ -40,8 +59,12 @@ class btAlignedObjectArray SIMD_FORCE_INLINE void copy(int start,int end, T* dest) { int i; - for (i=0;i<m_size;++i) + for (i=start;i<end;++i) +#ifdef BT_USE_PLACEMENT_NEW + new (&dest[i]) T(m_data[i]); +#else dest[i] = m_data[i]; +#endif //BT_USE_PLACEMENT_NEW } SIMD_FORCE_INLINE void init() @@ -53,7 +76,7 @@ class btAlignedObjectArray SIMD_FORCE_INLINE void destroy(int first,int last) { int i; - for (i=0; i<m_size;i++) + for (i=first; i<last;i++) { m_data[i].~T(); } @@ -74,6 +97,8 @@ class btAlignedObjectArray } } + + public: @@ -123,17 +148,50 @@ class btAlignedObjectArray m_data[m_size].~T(); } - SIMD_FORCE_INLINE void resize(int newsize) + SIMD_FORCE_INLINE void resize(int newsize, const T& fillData=T()) { - if (newsize > size()) + int curSize = size(); + + if (newsize < size()) + { + for(int i = curSize; i < newsize; i++) + { + m_data[i].~T(); + } + } else { - reserve(newsize); + if (newsize > size()) + { + reserve(newsize); + } +#ifdef BT_USE_PLACEMENT_NEW + for (int i=curSize;i<newsize;i++) + { + new ( &m_data[i]) T(fillData); + } +#endif //BT_USE_PLACEMENT_NEW + } m_size = newsize; } + SIMD_FORCE_INLINE T& expand( const T& fillValue=T()) + { + int sz = size(); + if( sz == capacity() ) + { + reserve( allocSize(size()) ); + } + m_size++; +#ifdef BT_USE_PLACEMENT_NEW + new (&m_data[sz]) T(fillValue); //use the in-place new (not really allocating heap memory) +#endif + + return m_data[sz]; + } + SIMD_FORCE_INLINE void push_back(const T& _Val) { @@ -143,8 +201,12 @@ class btAlignedObjectArray reserve( allocSize(size()) ); } - m_data[size()] = _Val; - //::new ( m_data[m_size] ) T(_Val); +#ifdef BT_USE_PLACEMENT_NEW + new ( &m_data[m_size] ) T(_Val); +#else + m_data[size()] = _Val; +#endif //BT_USE_PLACEMENT_NEW + m_size++; } @@ -154,24 +216,152 @@ class btAlignedObjectArray { // determine new minimum length of allocated storage if (capacity() < _Count) { // not enough room, reallocate - if (capacity() < _Count) - { - T* s = (T*)allocate(_Count); + T* s = (T*)allocate(_Count); + + copy(0, size(), s); + + destroy(0,size()); - copy(0, size(), s); + deallocate(); + + m_data = s; + + m_capacity = _Count; + + } + } - destroy(0,size()); - deallocate(); + class less + { + public: - m_data = s; - - m_capacity = _Count; + bool operator() ( const T& a, const T& b ) + { + return ( a < b ); + } + }; + + ///heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/ + template <typename L> + void downHeap(T *pArr, int k, int n,L CompareFunc) + { + /* PRE: a[k+1..N] is a heap */ + /* POST: a[k..N] is a heap */ + + T temp = pArr[k - 1]; + /* k has child(s) */ + while (k <= n/2) + { + int child = 2*k; + + if ((child < n) && CompareFunc(pArr[child - 1] , pArr[child])) + { + child++; + } + /* pick larger child */ + if (CompareFunc(temp , pArr[child - 1])) + { + /* move child up */ + pArr[k - 1] = pArr[child - 1]; + k = child; } + else + { + break; + } + } + pArr[k - 1] = temp; + } /*downHeap*/ + + void swap(int index0,int index1) + { +#ifdef BT_USE_MEMCPY + char temp[sizeof(T)]; + memcpy(temp,&m_data[index0],sizeof(T)); + memcpy(&m_data[index0],&m_data[index1],sizeof(T)); + memcpy(&m_data[index1],temp,sizeof(T)); +#else + T temp = m_data[index0]; + m_data[index0] = m_data[index1]; + m_data[index1] = temp; +#endif //BT_USE_PLACEMENT_NEW + + } + + template <typename L> + void heapSort(L CompareFunc) + { + /* sort a[0..N-1], N.B. 0 to N-1 */ + int k; + int n = m_size; + for (k = n/2; k > 0; k--) + { + downHeap(m_data, k, n, CompareFunc); + } + + /* a[1..N] is now a heap */ + while ( n>=1 ) + { + swap(0,n-1); /* largest of a[0..n-1] */ + + + n = n - 1; + /* restore a[1..i-1] heap */ + downHeap(m_data, 1, n, CompareFunc); + } + } + + ///non-recursive binary search, assumes sorted array + int findBinarySearch(const T& key) const + { + int first = 0; + int last = size(); + + //assume sorted array + while (first <= last) { + int mid = (first + last) / 2; // compute mid point. + if (key > m_data[mid]) + first = mid + 1; // repeat search in top half. + else if (key < m_data[mid]) + last = mid - 1; // repeat search in bottom half. + else + return mid; // found it. return position ///// + } + return size(); // failed to find key + } + + + int findLinearSearch(const T& key) const + { + int index=size(); + int i; + + for (i=0;i<size();i++) + { + if (m_data[i] == key) + { + index = i; + break; } } + return index; + } + + void remove(const T& key) + { + + int findIndex = findLinearSearch(key); + if (findIndex<size()) + { + swap( findIndex,size()-1); + pop_back(); + } + } }; #endif //BT_OBJECT_ARRAY__ + + diff --git a/extern/bullet2/src/LinearMath/btDefaultMotionState.h b/extern/bullet2/src/LinearMath/btDefaultMotionState.h index 6b85b37fb9e..d4ec8e8879c 100644 --- a/extern/bullet2/src/LinearMath/btDefaultMotionState.h +++ b/extern/bullet2/src/LinearMath/btDefaultMotionState.h @@ -31,12 +31,7 @@ struct btDefaultMotionState : public btMotionState m_graphicsWorldTrans = centerOfMassWorldTrans * m_centerOfMassOffset ; } - ///Bullet gives a callback for objects that are about to be deactivated (put asleep) - /// You can intercept this callback for your own bookkeeping. - ///Also you can return false to disable deactivation for this object this frame. - virtual bool deactivationCallback(void* userPointer) { - return true; - } + }; diff --git a/extern/bullet2/src/LinearMath/btGeometryUtil.cpp b/extern/bullet2/src/LinearMath/btGeometryUtil.cpp index 5036894b2b3..3d0fb122a6b 100644 --- a/extern/bullet2/src/LinearMath/btGeometryUtil.cpp +++ b/extern/bullet2/src/LinearMath/btGeometryUtil.cpp @@ -16,14 +16,23 @@ subject to the following restrictions: #include "btGeometryUtil.h" -bool btGeometryUtil::isPointInsidePlanes(const btAlignedObjectArray<btVector3>& planeEquations, const btVector3& point, float margin) + +/* + Make sure this dummy function never changes so that it + can be used by probes that are checking whether the + library is actually installed. +*/ +extern "C" void btBulletMathProbe () {} + + +bool btGeometryUtil::isPointInsidePlanes(const btAlignedObjectArray<btVector3>& planeEquations, const btVector3& point, btScalar margin) { int numbrushes = planeEquations.size(); for (int i=0;i<numbrushes;i++) { const btVector3& N1 = planeEquations[i]; - float dist = float(N1.dot(point))+float(N1[3])-margin; - if (dist>0.f) + btScalar dist = btScalar(N1.dot(point))+btScalar(N1[3])-margin; + if (dist>btScalar(0.)) { return false; } @@ -33,14 +42,14 @@ bool btGeometryUtil::isPointInsidePlanes(const btAlignedObjectArray<btVector3>& } -bool btGeometryUtil::areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray<btVector3>& vertices, float margin) +bool btGeometryUtil::areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray<btVector3>& vertices, btScalar margin) { int numvertices = vertices.size(); for (int i=0;i<numvertices;i++) { const btVector3& N1 = vertices[i]; - float dist = float(planeNormal.dot(N1))+float(planeNormal[3])-margin; - if (dist>0.f) + btScalar dist = btScalar(planeNormal.dot(N1))+btScalar(planeNormal[3])-margin; + if (dist>btScalar(0.)) { return false; } @@ -54,7 +63,7 @@ bool notExist(const btVector3& planeEquation,const btAlignedObjectArray<btVector for (int i=0;i<numbrushes;i++) { const btVector3& N1 = planeEquations[i]; - if (planeEquation.dot(N1) > 0.999f) + if (planeEquation.dot(N1) > btScalar(0.999)) { return false; } @@ -83,11 +92,11 @@ void btGeometryUtil::getPlaneEquationsFromVertices(btAlignedObjectArray<btVector btVector3 planeEquation,edge0,edge1; edge0 = N2-N1; edge1 = N3-N1; - float normalSign = 1.f; + btScalar normalSign = btScalar(1.); for (int ww=0;ww<2;ww++) { planeEquation = normalSign * edge0.cross(edge1); - if (planeEquation.length2() > 0.0001f) + if (planeEquation.length2() > btScalar(0.0001)) { planeEquation.normalize(); if (notExist(planeEquation,planeEquationsOut)) @@ -95,13 +104,13 @@ void btGeometryUtil::getPlaneEquationsFromVertices(btAlignedObjectArray<btVector planeEquation[3] = -planeEquation.dot(N1); //check if inside, and replace supportingVertexOut if needed - if (areVerticesBehindPlane(planeEquation,vertices,0.01f)) + if (areVerticesBehindPlane(planeEquation,vertices,btScalar(0.01))) { planeEquationsOut.push_back(planeEquation); } } } - normalSign = -1.f; + normalSign = btScalar(-1.); } } @@ -132,9 +141,9 @@ void btGeometryUtil::getVerticesFromPlaneEquations(const btAlignedObjectArray<bt btVector3 n3n1; n3n1 = N3.cross(N1); btVector3 n1n2; n1n2 = N1.cross(N2); - if ( ( n2n3.length2() > 0.0001f ) && - ( n3n1.length2() > 0.0001f ) && - ( n1n2.length2() > 0.0001f ) ) + if ( ( n2n3.length2() > btScalar(0.0001) ) && + ( n3n1.length2() > btScalar(0.0001) ) && + ( n1n2.length2() > btScalar(0.0001) ) ) { //point P out of 3 plane equations: @@ -143,10 +152,10 @@ void btGeometryUtil::getVerticesFromPlaneEquations(const btAlignedObjectArray<bt // N1 . ( N2 * N3 ) - float quotient = (N1.dot(n2n3)); - if (btFabs(quotient) > 0.000001f) + btScalar quotient = (N1.dot(n2n3)); + if (btFabs(quotient) > btScalar(0.000001)) { - quotient = -1.f / quotient; + quotient = btScalar(-1.) / quotient; n2n3 *= N1[3]; n3n1 *= N2[3]; n1n2 *= N3[3]; @@ -156,7 +165,7 @@ void btGeometryUtil::getVerticesFromPlaneEquations(const btAlignedObjectArray<bt potentialVertex *= quotient; //check if inside, and replace supportingVertexOut if needed - if (isPointInsidePlanes(planeEquations,potentialVertex,0.01f)) + if (isPointInsidePlanes(planeEquations,potentialVertex,btScalar(0.01))) { verticesOut.push_back(potentialVertex); } diff --git a/extern/bullet2/src/LinearMath/btGeometryUtil.h b/extern/bullet2/src/LinearMath/btGeometryUtil.h index 018ffa72296..766cd75c383 100644 --- a/extern/bullet2/src/LinearMath/btGeometryUtil.h +++ b/extern/bullet2/src/LinearMath/btGeometryUtil.h @@ -28,11 +28,11 @@ class btGeometryUtil static void getVerticesFromPlaneEquations(const btAlignedObjectArray<btVector3>& planeEquations , btAlignedObjectArray<btVector3>& verticesOut ); - static bool isInside(const btAlignedObjectArray<btVector3>& vertices, const btVector3& planeNormal, float margin); + static bool isInside(const btAlignedObjectArray<btVector3>& vertices, const btVector3& planeNormal, btScalar margin); - static bool isPointInsidePlanes(const btAlignedObjectArray<btVector3>& planeEquations, const btVector3& point, float margin); + static bool isPointInsidePlanes(const btAlignedObjectArray<btVector3>& planeEquations, const btVector3& point, btScalar margin); - static bool areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray<btVector3>& vertices, float margin); + static bool areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray<btVector3>& vertices, btScalar margin); }; diff --git a/extern/bullet2/src/LinearMath/btIDebugDraw.h b/extern/bullet2/src/LinearMath/btIDebugDraw.h index 86db735ce94..5f40ca39157 100644 --- a/extern/bullet2/src/LinearMath/btIDebugDraw.h +++ b/extern/bullet2/src/LinearMath/btIDebugDraw.h @@ -28,7 +28,7 @@ DEALINGS IN THE SOFTWARE. #ifndef IDEBUG_DRAW__H #define IDEBUG_DRAW__H -#include "LinearMath/btVector3.h" +#include "btVector3.h" class btIDebugDraw @@ -56,14 +56,45 @@ class btIDebugDraw virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color)=0; - virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,float distance,int lifeTime,const btVector3& color)=0; + virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color)=0; + + virtual void reportErrorWarning(const char* warningString) = 0; virtual void setDebugMode(int debugMode) =0; virtual int getDebugMode() const = 0; + inline void drawAabb(const btVector3& from,const btVector3& to,const btVector3& color) + { + btVector3 halfExtents = (to-from)* 0.5f; + btVector3 center = (to+from) *0.5f; + int i,j; + + btVector3 edgecoord(1.f,1.f,1.f),pa,pb; + for (i=0;i<4;i++) + { + for (j=0;j<3;j++) + { + pa = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1], + edgecoord[2]*halfExtents[2]); + pa+=center; + + int othercoord = j%3; + edgecoord[othercoord]*=-1.f; + pb = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1], + edgecoord[2]*halfExtents[2]); + pb+=center; + + drawLine(pa,pb,color); + } + edgecoord = btVector3(-1.f,-1.f,-1.f); + if (i<3) + edgecoord[i]*=-1.f; + } + } }; + #endif //IDEBUG_DRAW__H diff --git a/extern/bullet2/src/LinearMath/btMatrix3x3.h b/extern/bullet2/src/LinearMath/btMatrix3x3.h index c3cc90a82c7..fda348b42ab 100644 --- a/extern/bullet2/src/LinearMath/btMatrix3x3.h +++ b/extern/bullet2/src/LinearMath/btMatrix3x3.h @@ -16,10 +16,10 @@ subject to the following restrictions: #ifndef btMatrix3x3_H #define btMatrix3x3_H -#include "LinearMath/btScalar.h" +#include "btScalar.h" -#include "LinearMath/btVector3.h" -#include "LinearMath/btQuaternion.h" +#include "btVector3.h" +#include "btQuaternion.h" class btMatrix3x3 { @@ -45,12 +45,14 @@ class btMatrix3x3 { zx, zy, zz); } - btVector3 getColumn(int i) const + SIMD_FORCE_INLINE btVector3 getColumn(int i) const { return btVector3(m_el[0][i],m_el[1][i],m_el[2][i]); } + + - const btVector3& getRow(int i) const + SIMD_FORCE_INLINE const btVector3& getRow(int i) const { return m_el[i]; } @@ -58,13 +60,13 @@ class btMatrix3x3 { SIMD_FORCE_INLINE btVector3& operator[](int i) { - assert(0 <= i && i < 3); + btFullAssert(0 <= i && i < 3); return m_el[i]; } - const btVector3& operator[](int i) const + SIMD_FORCE_INLINE const btVector3& operator[](int i) const { - assert(0 <= i && i < 3); + btFullAssert(0 <= i && i < 3); return m_el[i]; } @@ -73,41 +75,30 @@ class btMatrix3x3 { void setFromOpenGLSubMatrix(const btScalar *m) { - m_el[0][0] = (m[0]); - m_el[1][0] = (m[1]); - m_el[2][0] = (m[2]); - m_el[0][1] = (m[4]); - m_el[1][1] = (m[5]); - m_el[2][1] = (m[6]); - m_el[0][2] = (m[8]); - m_el[1][2] = (m[9]); - m_el[2][2] = (m[10]); + m_el[0].setValue(m[0],m[4],m[8]); + m_el[1].setValue(m[1],m[5],m[9]); + m_el[2].setValue(m[2],m[6],m[10]); + } void setValue(const btScalar& xx, const btScalar& xy, const btScalar& xz, const btScalar& yx, const btScalar& yy, const btScalar& yz, const btScalar& zx, const btScalar& zy, const btScalar& zz) { - m_el[0][0] = btScalar(xx); - m_el[0][1] = btScalar(xy); - m_el[0][2] = btScalar(xz); - m_el[1][0] = btScalar(yx); - m_el[1][1] = btScalar(yy); - m_el[1][2] = btScalar(yz); - m_el[2][0] = btScalar(zx); - m_el[2][1] = btScalar(zy); - m_el[2][2] = btScalar(zz); + m_el[0].setValue(xx,xy,xz); + m_el[1].setValue(yx,yy,yz); + m_el[2].setValue(zx,zy,zz); } void setRotation(const btQuaternion& q) { btScalar d = q.length2(); - assert(d != btScalar(0.0)); + btFullAssert(d != btScalar(0.0)); btScalar s = btScalar(2.0) / d; - btScalar xs = q[0] * s, ys = q[1] * s, zs = q[2] * s; - btScalar wx = q[3] * xs, wy = q[3] * ys, wz = q[3] * zs; - btScalar xx = q[0] * xs, xy = q[0] * ys, xz = q[0] * zs; - btScalar yy = q[1] * ys, yz = q[1] * zs, zz = q[2] * zs; + btScalar xs = q.x() * s, ys = q.y() * s, zs = q.z() * s; + btScalar wx = q.w() * xs, wy = q.w() * ys, wz = q.w() * zs; + btScalar xx = q.x() * xs, xy = q.x() * ys, xz = q.x() * zs; + btScalar yy = q.y() * ys, yz = q.y() * zs, zz = q.z() * zs; setValue(btScalar(1.0) - (yy + zz), xy - wz, xz + wy, xy + wz, btScalar(1.0) - (xx + zz), yz - wx, xz - wy, yz + wx, btScalar(1.0) - (xx + yy)); @@ -168,90 +159,88 @@ class btMatrix3x3 { void getOpenGLSubMatrix(btScalar *m) const { - m[0] = btScalar(m_el[0][0]); - m[1] = btScalar(m_el[1][0]); - m[2] = btScalar(m_el[2][0]); + m[0] = btScalar(m_el[0].x()); + m[1] = btScalar(m_el[1].x()); + m[2] = btScalar(m_el[2].x()); m[3] = btScalar(0.0); - m[4] = btScalar(m_el[0][1]); - m[5] = btScalar(m_el[1][1]); - m[6] = btScalar(m_el[2][1]); + m[4] = btScalar(m_el[0].y()); + m[5] = btScalar(m_el[1].y()); + m[6] = btScalar(m_el[2].y()); m[7] = btScalar(0.0); - m[8] = btScalar(m_el[0][2]); - m[9] = btScalar(m_el[1][2]); - m[10] = btScalar(m_el[2][2]); + m[8] = btScalar(m_el[0].z()); + m[9] = btScalar(m_el[1].z()); + m[10] = btScalar(m_el[2].z()); m[11] = btScalar(0.0); } void getRotation(btQuaternion& q) const { - btScalar trace = m_el[0][0] + m_el[1][1] + m_el[2][2]; + btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z(); + btScalar temp[4]; if (trace > btScalar(0.0)) { btScalar s = btSqrt(trace + btScalar(1.0)); - q[3] = s * btScalar(0.5); + temp[3]=(s * btScalar(0.5)); s = btScalar(0.5) / s; - q[0] = (m_el[2][1] - m_el[1][2]) * s; - q[1] = (m_el[0][2] - m_el[2][0]) * s; - q[2] = (m_el[1][0] - m_el[0][1]) * s; + temp[0]=((m_el[2].y() - m_el[1].z()) * s); + temp[1]=((m_el[0].z() - m_el[2].x()) * s); + temp[2]=((m_el[1].x() - m_el[0].y()) * s); } else { - int i = m_el[0][0] < m_el[1][1] ? - (m_el[1][1] < m_el[2][2] ? 2 : 1) : - (m_el[0][0] < m_el[2][2] ? 2 : 0); + int i = m_el[0].x() < m_el[1].y() ? + (m_el[1].y() < m_el[2].z() ? 2 : 1) : + (m_el[0].x() < m_el[2].z() ? 2 : 0); int j = (i + 1) % 3; int k = (i + 2) % 3; btScalar s = btSqrt(m_el[i][i] - m_el[j][j] - m_el[k][k] + btScalar(1.0)); - q[i] = s * btScalar(0.5); + temp[i] = s * btScalar(0.5); s = btScalar(0.5) / s; - q[3] = (m_el[k][j] - m_el[j][k]) * s; - q[j] = (m_el[j][i] + m_el[i][j]) * s; - q[k] = (m_el[k][i] + m_el[i][k]) * s; + temp[3] = (m_el[k][j] - m_el[j][k]) * s; + temp[j] = (m_el[j][i] + m_el[i][j]) * s; + temp[k] = (m_el[k][i] + m_el[i][k]) * s; } + q.setValue(temp[0],temp[1],temp[2],temp[3]); } - - void getEuler(btScalar& yaw, btScalar& pitch, btScalar& roll) const { - pitch = btScalar(btAsin(-m_el[2][0])); - if (pitch < SIMD_2_PI) + + if (btScalar(m_el[1].z()) < btScalar(1)) { - if (pitch > SIMD_2_PI) + if (btScalar(m_el[1].z()) > -btScalar(1)) { - yaw = btScalar(btAtan2(m_el[1][0], m_el[0][0])); - roll = btScalar(btAtan2(m_el[2][1], m_el[2][2])); + yaw = btScalar(btAtan2(m_el[1].x(), m_el[0].x())); + pitch = btScalar(btAsin(-m_el[1].y())); + roll = btScalar(btAtan2(m_el[2].y(), m_el[2].z())); } else { - yaw = btScalar(-btAtan2(-m_el[0][1], m_el[0][2])); + yaw = btScalar(-btAtan2(-m_el[0].y(), m_el[0].z())); + pitch = SIMD_HALF_PI; roll = btScalar(0.0); } } else { - yaw = btScalar(btAtan2(-m_el[0][1], m_el[0][2])); + yaw = btScalar(btAtan2(-m_el[0].y(), m_el[0].z())); + pitch = -SIMD_HALF_PI; roll = btScalar(0.0); } } - - btVector3 getScaling() const - { - return btVector3(m_el[0][0] * m_el[0][0] + m_el[1][0] * m_el[1][0] + m_el[2][0] * m_el[2][0], - m_el[0][1] * m_el[0][1] + m_el[1][1] * m_el[1][1] + m_el[2][1] * m_el[2][1], - m_el[0][2] * m_el[0][2] + m_el[1][2] * m_el[1][2] + m_el[2][2] * m_el[2][2]); - } + + btMatrix3x3 scaled(const btVector3& s) const { - return btMatrix3x3(m_el[0][0] * s[0], m_el[0][1] * s[1], m_el[0][2] * s[2], - m_el[1][0] * s[0], m_el[1][1] * s[1], m_el[1][2] * s[2], - m_el[2][0] * s[0], m_el[2][1] * s[1], m_el[2][2] * s[2]); + return btMatrix3x3(m_el[0].x() * s.x(), m_el[0].y() * s.y(), m_el[0].z() * s.z(), + m_el[1].x() * s.x(), m_el[1].y() * s.y(), m_el[1].z() * s.z(), + m_el[2].x() * s.x(), m_el[2].y() * s.y(), m_el[2].z() * s.z()); } btScalar determinant() const; @@ -263,11 +252,21 @@ class btMatrix3x3 { btMatrix3x3 transposeTimes(const btMatrix3x3& m) const; btMatrix3x3 timesTranspose(const btMatrix3x3& m) const; - btScalar tdot(int c, const btVector3& v) const + SIMD_FORCE_INLINE btScalar tdotx(const btVector3& v) const + { + return m_el[0].x() * v.x() + m_el[1].x() * v.y() + m_el[2].x() * v.z(); + } + SIMD_FORCE_INLINE btScalar tdoty(const btVector3& v) const + { + return m_el[0].y() * v.x() + m_el[1].y() * v.y() + m_el[2].y() * v.z(); + } + SIMD_FORCE_INLINE btScalar tdotz(const btVector3& v) const { - return m_el[0][c] * v[0] + m_el[1][c] * v[1] + m_el[2][c] * v[2]; + return m_el[0].z() * v.x() + m_el[1].z() * v.y() + m_el[2].z() * v.z(); } + + protected: btScalar cofac(int r1, int c1, int r2, int c2) const { @@ -280,9 +279,9 @@ class btMatrix3x3 { SIMD_FORCE_INLINE btMatrix3x3& btMatrix3x3::operator*=(const btMatrix3x3& m) { - setValue(m.tdot(0, m_el[0]), m.tdot(1, m_el[0]), m.tdot(2, m_el[0]), - m.tdot(0, m_el[1]), m.tdot(1, m_el[1]), m.tdot(2, m_el[1]), - m.tdot(0, m_el[2]), m.tdot(1, m_el[2]), m.tdot(2, m_el[2])); + setValue(m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]), + m.tdotx(m_el[1]), m.tdoty(m_el[1]), m.tdotz(m_el[1]), + m.tdotx(m_el[2]), m.tdoty(m_el[2]), m.tdotz(m_el[2])); return *this; } @@ -297,17 +296,17 @@ class btMatrix3x3 { btMatrix3x3::absolute() const { return btMatrix3x3( - btFabs(m_el[0][0]), btFabs(m_el[0][1]), btFabs(m_el[0][2]), - btFabs(m_el[1][0]), btFabs(m_el[1][1]), btFabs(m_el[1][2]), - btFabs(m_el[2][0]), btFabs(m_el[2][1]), btFabs(m_el[2][2])); + btFabs(m_el[0].x()), btFabs(m_el[0].y()), btFabs(m_el[0].z()), + btFabs(m_el[1].x()), btFabs(m_el[1].y()), btFabs(m_el[1].z()), + btFabs(m_el[2].x()), btFabs(m_el[2].y()), btFabs(m_el[2].z())); } SIMD_FORCE_INLINE btMatrix3x3 btMatrix3x3::transpose() const { - return btMatrix3x3(m_el[0][0], m_el[1][0], m_el[2][0], - m_el[0][1], m_el[1][1], m_el[2][1], - m_el[0][2], m_el[1][2], m_el[2][2]); + return btMatrix3x3(m_el[0].x(), m_el[1].x(), m_el[2].x(), + m_el[0].y(), m_el[1].y(), m_el[2].y(), + m_el[0].z(), m_el[1].z(), m_el[2].z()); } SIMD_FORCE_INLINE btMatrix3x3 @@ -323,26 +322,26 @@ class btMatrix3x3 { { btVector3 co(cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1)); btScalar det = (*this)[0].dot(co); - assert(det != btScalar(0.0f)); - btScalar s = btScalar(1.0f) / det; - return btMatrix3x3(co[0] * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s, - co[1] * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s, - co[2] * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s); + btFullAssert(det != btScalar(0.0)); + btScalar s = btScalar(1.0) / det; + return btMatrix3x3(co.x() * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s, + co.y() * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s, + co.z() * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s); } SIMD_FORCE_INLINE btMatrix3x3 btMatrix3x3::transposeTimes(const btMatrix3x3& m) const { return btMatrix3x3( - m_el[0][0] * m[0][0] + m_el[1][0] * m[1][0] + m_el[2][0] * m[2][0], - m_el[0][0] * m[0][1] + m_el[1][0] * m[1][1] + m_el[2][0] * m[2][1], - m_el[0][0] * m[0][2] + m_el[1][0] * m[1][2] + m_el[2][0] * m[2][2], - m_el[0][1] * m[0][0] + m_el[1][1] * m[1][0] + m_el[2][1] * m[2][0], - m_el[0][1] * m[0][1] + m_el[1][1] * m[1][1] + m_el[2][1] * m[2][1], - m_el[0][1] * m[0][2] + m_el[1][1] * m[1][2] + m_el[2][1] * m[2][2], - m_el[0][2] * m[0][0] + m_el[1][2] * m[1][0] + m_el[2][2] * m[2][0], - m_el[0][2] * m[0][1] + m_el[1][2] * m[1][1] + m_el[2][2] * m[2][1], - m_el[0][2] * m[0][2] + m_el[1][2] * m[1][2] + m_el[2][2] * m[2][2]); + m_el[0].x() * m[0].x() + m_el[1].x() * m[1].x() + m_el[2].x() * m[2].x(), + m_el[0].x() * m[0].y() + m_el[1].x() * m[1].y() + m_el[2].x() * m[2].y(), + m_el[0].x() * m[0].z() + m_el[1].x() * m[1].z() + m_el[2].x() * m[2].z(), + m_el[0].y() * m[0].x() + m_el[1].y() * m[1].x() + m_el[2].y() * m[2].x(), + m_el[0].y() * m[0].y() + m_el[1].y() * m[1].y() + m_el[2].y() * m[2].y(), + m_el[0].y() * m[0].z() + m_el[1].y() * m[1].z() + m_el[2].y() * m[2].z(), + m_el[0].z() * m[0].x() + m_el[1].z() * m[1].x() + m_el[2].z() * m[2].x(), + m_el[0].z() * m[0].y() + m_el[1].z() * m[1].y() + m_el[2].z() * m[2].y(), + m_el[0].z() * m[0].z() + m_el[1].z() * m[1].z() + m_el[2].z() * m[2].x()); } SIMD_FORCE_INLINE btMatrix3x3 @@ -365,19 +364,19 @@ class btMatrix3x3 { SIMD_FORCE_INLINE btVector3 operator*(const btVector3& v, const btMatrix3x3& m) { - return btVector3(m.tdot(0, v), m.tdot(1, v), m.tdot(2, v)); + return btVector3(m.tdotx(v), m.tdoty(v), m.tdotz(v)); } SIMD_FORCE_INLINE btMatrix3x3 operator*(const btMatrix3x3& m1, const btMatrix3x3& m2) { return btMatrix3x3( - m2.tdot(0, m1[0]), m2.tdot(1, m1[0]), m2.tdot(2, m1[0]), - m2.tdot(0, m1[1]), m2.tdot(1, m1[1]), m2.tdot(2, m1[1]), - m2.tdot(0, m1[2]), m2.tdot(1, m1[2]), m2.tdot(2, m1[2])); + m2.tdotx( m1[0]), m2.tdoty( m1[0]), m2.tdotz( m1[0]), + m2.tdotx( m1[1]), m2.tdoty( m1[1]), m2.tdotz( m1[1]), + m2.tdotx( m1[2]), m2.tdoty( m1[2]), m2.tdotz( m1[2])); } - +/* SIMD_FORCE_INLINE btMatrix3x3 btMultTransposeLeft(const btMatrix3x3& m1, const btMatrix3x3& m2) { return btMatrix3x3( m1[0][0] * m2[0][0] + m1[1][0] * m2[1][0] + m1[2][0] * m2[2][0], @@ -390,6 +389,7 @@ class btMatrix3x3 { m1[0][2] * m2[0][1] + m1[1][2] * m2[1][1] + m1[2][2] * m2[2][1], m1[0][2] * m2[0][2] + m1[1][2] * m2[1][2] + m1[2][2] * m2[2][2]); } +*/ #endif diff --git a/extern/bullet2/src/LinearMath/btMotionState.h b/extern/bullet2/src/LinearMath/btMotionState.h index a9e212d3c71..1975e5ff900 100644 --- a/extern/bullet2/src/LinearMath/btMotionState.h +++ b/extern/bullet2/src/LinearMath/btMotionState.h @@ -16,7 +16,7 @@ subject to the following restrictions: #ifndef BT_MOTIONSTATE_H #define BT_MOTIONSTATE_H -#include "LinearMath/btTransform.h" +#include "btTransform.h" ///btMotionState allows the dynamics world to synchronize the updated world transforms with graphics ///For optimizations, potentially only moving objects get synchronized (using setWorldPosition/setWorldOrientation) @@ -34,10 +34,7 @@ class btMotionState //Bullet only calls the update of worldtransform for active objects virtual void setWorldTransform(const btTransform& worldTrans)=0; - //future: when Bullet makes attempt to deactivate object, you can intercept this callback (return false to disable deactivation for this object this frame) - virtual bool deactivationCallback(void* userPointer) { - return true; - } + }; #endif //BT_MOTIONSTATE_H diff --git a/extern/bullet2/src/LinearMath/btPoint3.h b/extern/bullet2/src/LinearMath/btPoint3.h index 4be7e9015bb..a2020e26d12 100644 --- a/extern/bullet2/src/LinearMath/btPoint3.h +++ b/extern/bullet2/src/LinearMath/btPoint3.h @@ -17,7 +17,7 @@ subject to the following restrictions: #ifndef btPoint3_H #define btPoint3_H -#include "LinearMath/btVector3.h" +#include "btVector3.h" typedef btVector3 btPoint3; diff --git a/extern/bullet2/src/LinearMath/btQuadWord.h b/extern/bullet2/src/LinearMath/btQuadWord.h index 4331b668210..961ac484d20 100644 --- a/extern/bullet2/src/LinearMath/btQuadWord.h +++ b/extern/bullet2/src/LinearMath/btQuadWord.h @@ -16,12 +16,13 @@ subject to the following restrictions: #ifndef SIMD_QUADWORD_H #define SIMD_QUADWORD_H -#include "LinearMath/btScalar.h" +#include "btScalar.h" -ATTRIBUTE_ALIGNED16 (class btQuadWord) +///btQuadWord is base-class for vectors, points +class btQuadWord { protected: btScalar m_x; @@ -31,8 +32,8 @@ ATTRIBUTE_ALIGNED16 (class btQuadWord) public: - SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_x)[i]; } - SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_x)[i]; } +// SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_x)[i]; } +// SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_x)[i]; } SIMD_FORCE_INLINE const btScalar& getX() const { return m_x; } @@ -40,11 +41,13 @@ ATTRIBUTE_ALIGNED16 (class btQuadWord) SIMD_FORCE_INLINE const btScalar& getZ() const { return m_z; } - SIMD_FORCE_INLINE void setX(float x) { m_x = x;}; + SIMD_FORCE_INLINE void setX(btScalar x) { m_x = x;}; - SIMD_FORCE_INLINE void setY(float y) { m_y = y;}; + SIMD_FORCE_INLINE void setY(btScalar y) { m_y = y;}; - SIMD_FORCE_INLINE void setZ(float z) { m_z = z;}; + SIMD_FORCE_INLINE void setZ(btScalar z) { m_z = z;}; + + SIMD_FORCE_INLINE void setW(btScalar w) { m_unusedW = w;}; SIMD_FORCE_INLINE const btScalar& x() const { return m_x; } @@ -52,15 +55,18 @@ ATTRIBUTE_ALIGNED16 (class btQuadWord) SIMD_FORCE_INLINE const btScalar& z() const { return m_z; } + SIMD_FORCE_INLINE const btScalar& w() const { return m_unusedW; } + - operator btScalar *() { return &m_x; } - operator const btScalar *() const { return &m_x; } + SIMD_FORCE_INLINE operator btScalar *() { return &m_x; } + SIMD_FORCE_INLINE operator const btScalar *() const { return &m_x; } SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z) { m_x=x; m_y=y; m_z=z; + m_unusedW = 0.f; } /* void getValue(btScalar *m) const @@ -78,15 +84,15 @@ ATTRIBUTE_ALIGNED16 (class btQuadWord) m_unusedW=w; } - SIMD_FORCE_INLINE btQuadWord() : - m_x(0.f),m_y(0.f),m_z(0.f),m_unusedW(0.f) + SIMD_FORCE_INLINE btQuadWord() + // :m_x(btScalar(0.)),m_y(btScalar(0.)),m_z(btScalar(0.)),m_unusedW(btScalar(0.)) { } SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z) :m_x(x),m_y(y),m_z(z) //todo, remove this in release/simd ? - ,m_unusedW(0.f) + ,m_unusedW(btScalar(0.)) { } diff --git a/extern/bullet2/src/LinearMath/btQuaternion.h b/extern/bullet2/src/LinearMath/btQuaternion.h index aec25a54955..d5a7913b742 100644 --- a/extern/bullet2/src/LinearMath/btQuaternion.h +++ b/extern/bullet2/src/LinearMath/btQuaternion.h @@ -17,7 +17,7 @@ subject to the following restrictions: #ifndef SIMD__QUATERNION_H_ #define SIMD__QUATERNION_H_ -#include "LinearMath/btVector3.h" +#include "btVector3.h" class btQuaternion : public btQuadWord { public: @@ -68,13 +68,13 @@ public: btQuaternion& operator+=(const btQuaternion& q) { - m_x += q.x(); m_y += q.y(); m_z += q.z(); m_unusedW += q[3]; + m_x += q.x(); m_y += q.y(); m_z += q.z(); m_unusedW += q.m_unusedW; return *this; } btQuaternion& operator-=(const btQuaternion& q) { - m_x -= q.x(); m_y -= q.y(); m_z -= q.z(); m_unusedW -= q[3]; + m_x -= q.x(); m_y -= q.y(); m_z -= q.z(); m_unusedW -= q.m_unusedW; return *this; } @@ -87,16 +87,16 @@ public: btQuaternion& operator*=(const btQuaternion& q) { - setValue(m_unusedW * q.x() + m_x * q[3] + m_y * q.z() - m_z * q.y(), - m_unusedW * q.y() + m_y * q[3] + m_z * q.x() - m_x * q.z(), - m_unusedW * q.z() + m_z * q[3] + m_x * q.y() - m_y * q.x(), - m_unusedW * q[3] - m_x * q.x() - m_y * q.y() - m_z * q.z()); + setValue(m_unusedW * q.x() + m_x * q.m_unusedW + m_y * q.z() - m_z * q.y(), + m_unusedW * q.y() + m_y * q.m_unusedW + m_z * q.x() - m_x * q.z(), + m_unusedW * q.z() + m_z * q.m_unusedW + m_x * q.y() - m_y * q.x(), + m_unusedW * q.m_unusedW - m_x * q.x() - m_y * q.y() - m_z * q.z()); return *this; } btScalar dot(const btQuaternion& q) const { - return m_x * q.x() + m_y * q.y() + m_z * q.z() + m_unusedW * q[3]; + return m_x * q.x() + m_y * q.y() + m_z * q.z() + m_unusedW * q.m_unusedW; } btScalar length2() const @@ -150,7 +150,7 @@ public: btScalar getAngle() const { - btScalar s = 2.f * btAcos(m_unusedW); + btScalar s = btScalar(2.) * btAcos(m_unusedW); return s; } @@ -165,20 +165,20 @@ public: operator+(const btQuaternion& q2) const { const btQuaternion& q1 = *this; - return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1[3] + q2[3]); + return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_unusedW + q2.m_unusedW); } SIMD_FORCE_INLINE btQuaternion operator-(const btQuaternion& q2) const { const btQuaternion& q1 = *this; - return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1[3] - q2[3]); + return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_unusedW - q2.m_unusedW); } SIMD_FORCE_INLINE btQuaternion operator-() const { const btQuaternion& q2 = *this; - return btQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2[3]); + return btQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2.m_unusedW); } SIMD_FORCE_INLINE btQuaternion farthest( const btQuaternion& qd) const @@ -202,7 +202,7 @@ public: return btQuaternion((m_x * s0 + q.x() * s1) * d, (m_y * s0 + q.y() * s1) * d, (m_z * s0 + q.z() * s1) * d, - (m_unusedW * s0 + q[3] * s1) * d); + (m_unusedW * s0 + q.m_unusedW * s1) * d); } else { @@ -219,7 +219,7 @@ public: SIMD_FORCE_INLINE btQuaternion operator-(const btQuaternion& q) { - return btQuaternion(-q.x(), -q.y(), -q.z(), -q[3]); + return btQuaternion(-q.x(), -q.y(), -q.z(), -q.w()); } @@ -227,27 +227,27 @@ operator-(const btQuaternion& q) SIMD_FORCE_INLINE btQuaternion operator*(const btQuaternion& q1, const btQuaternion& q2) { - return btQuaternion(q1[3] * q2.x() + q1.x() * q2[3] + q1.y() * q2.z() - q1.z() * q2.y(), - q1[3] * q2.y() + q1.y() * q2[3] + q1.z() * q2.x() - q1.x() * q2.z(), - q1[3] * q2.z() + q1.z() * q2[3] + q1.x() * q2.y() - q1.y() * q2.x(), - q1[3] * q2[3] - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z()); + return btQuaternion(q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(), + q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z(), + q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x(), + q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z()); } SIMD_FORCE_INLINE btQuaternion operator*(const btQuaternion& q, const btVector3& w) { - return btQuaternion( q[3] * w.x() + q.y() * w.z() - q.z() * w.y(), - q[3] * w.y() + q.z() * w.x() - q.x() * w.z(), - q[3] * w.z() + q.x() * w.y() - q.y() * w.x(), + return btQuaternion( q.w() * w.x() + q.y() * w.z() - q.z() * w.y(), + q.w() * w.y() + q.z() * w.x() - q.x() * w.z(), + q.w() * w.z() + q.x() * w.y() - q.y() * w.x(), -q.x() * w.x() - q.y() * w.y() - q.z() * w.z()); } SIMD_FORCE_INLINE btQuaternion operator*(const btVector3& w, const btQuaternion& q) { - return btQuaternion( w.x() * q[3] + w.y() * q.z() - w.z() * q.y(), - w.y() * q[3] + w.z() * q.x() - w.x() * q.z(), - w.z() * q[3] + w.x() * q.y() - w.y() * q.x(), + return btQuaternion( w.x() * q.w() + w.y() * q.z() - w.z() * q.y(), + w.y() * q.w() + w.z() * q.x() - w.x() * q.z(), + w.z() * q.w() + w.x() * q.y() - w.y() * q.x(), -w.x() * q.x() - w.y() * q.y() - w.z() * q.z()); } diff --git a/extern/bullet2/src/LinearMath/btQuickprof.cpp b/extern/bullet2/src/LinearMath/btQuickprof.cpp index 4d013a65853..37a0c8c3be5 100644 --- a/extern/bullet2/src/LinearMath/btQuickprof.cpp +++ b/extern/bullet2/src/LinearMath/btQuickprof.cpp @@ -27,7 +27,7 @@ subject to the following restrictions: // Note: We must declare these private static variables again here to // avoid link errors. bool btProfiler::mEnabled = false; -hidden::Clock btProfiler::mClock; +btClock btProfiler::mClock; unsigned long int btProfiler::mCurrentCycleStartMicroseconds = 0; unsigned long int btProfiler::mLastCycleDurationMicroseconds = 0; std::map<std::string, hidden::ProfileBlock*> btProfiler::mProfileBlocks; diff --git a/extern/bullet2/src/LinearMath/btQuickprof.h b/extern/bullet2/src/LinearMath/btQuickprof.h index ec560c8e33e..9389fcd8156 100644 --- a/extern/bullet2/src/LinearMath/btQuickprof.h +++ b/extern/bullet2/src/LinearMath/btQuickprof.h @@ -22,16 +22,16 @@ subject to the following restrictions: #ifndef QUICK_PROF_H #define QUICK_PROF_H -#define USE_QUICKPROF 1 +#include "btScalar.h" -#ifdef USE_QUICKPROF +//#define USE_QUICKPROF 1 +//Don't use quickprof for now, because it contains STL. TODO: replace STL by Bullet container classes. -#include <iostream> -#include <fstream> -#include <string> -#include <map> +//if you don't need btClock, you can comment next line +#define USE_BT_CLOCK 1 +#ifdef USE_BT_CLOCK #ifdef __PPU__ #include <sys/sys_time.h> #include <stdio.h> @@ -43,7 +43,12 @@ typedef uint64_t __int64; #endif #if defined(WIN32) || defined(_WIN32) - #define USE_WINDOWS_TIMERS + + #define USE_WINDOWS_TIMERS + #define WIN32_LEAN_AND_MEAN + #define NOWINRES + #define NOMCX + #define NOIME #include <windows.h> #include <time.h> #else @@ -51,39 +56,12 @@ typedef uint64_t __int64; #endif #define mymin(a,b) (a > b ? a : b) -namespace hidden -{ - /// A simple data structure representing a single timed block - /// of code. - struct ProfileBlock - { - ProfileBlock() - { - currentBlockStartMicroseconds = 0; - currentCycleTotalMicroseconds = 0; - lastCycleTotalMicroseconds = 0; - totalMicroseconds = 0; - } - /// The starting time (in us) of the current block update. - unsigned long int currentBlockStartMicroseconds; - - /// The accumulated time (in us) spent in this block during the - /// current profiling cycle. - unsigned long int currentCycleTotalMicroseconds; - - /// The accumulated time (in us) spent in this block during the - /// past profiling cycle. - unsigned long int lastCycleTotalMicroseconds; - - /// The total accumulated time (in us) spent in this block. - unsigned long int totalMicroseconds; - }; - - class Clock +/// basic clock +class btClock { public: - Clock() + btClock() { #ifdef USE_WINDOWS_TIMERS QueryPerformanceFrequency(&mClockFrequency); @@ -91,7 +69,7 @@ namespace hidden reset(); } - ~Clock() + ~btClock() { } @@ -111,14 +89,14 @@ namespace hidden __asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); mStartTime = newTime; #else - gettimeofday(&mStartTime, NULL); + gettimeofday(&mStartTime, 0); #endif #endif } /// Returns the time in ms since the last call to reset or since - /// the Clock was created. + /// the btClock was created. unsigned long int getTimeMilliseconds() { #ifdef USE_WINDOWS_TIMERS @@ -168,7 +146,7 @@ namespace hidden #else struct timeval currentTime; - gettimeofday(¤tTime, NULL); + gettimeofday(¤tTime, 0); return (currentTime.tv_sec - mStartTime.tv_sec) * 1000 + (currentTime.tv_usec - mStartTime.tv_usec) / 1000; #endif //__PPU__ @@ -226,7 +204,7 @@ namespace hidden #else struct timeval currentTime; - gettimeofday(¤tTime, NULL); + gettimeofday(¤tTime, 0); return (currentTime.tv_sec - mStartTime.tv_sec) * 1000000 + (currentTime.tv_usec - mStartTime.tv_usec); #endif//__PPU__ @@ -248,6 +226,50 @@ namespace hidden #endif //__PPU__ }; + +#endif //USE_BT_CLOCK + + +#ifdef USE_QUICKPROF + + +#include <iostream> +#include <fstream> +#include <string> +#include <map> + + + + +namespace hidden +{ + /// A simple data structure representing a single timed block + /// of code. + struct ProfileBlock + { + ProfileBlock() + { + currentBlockStartMicroseconds = 0; + currentCycleTotalMicroseconds = 0; + lastCycleTotalMicroseconds = 0; + totalMicroseconds = 0; + } + + /// The starting time (in us) of the current block update. + unsigned long int currentBlockStartMicroseconds; + + /// The accumulated time (in us) spent in this block during the + /// current profiling cycle. + unsigned long int currentCycleTotalMicroseconds; + + /// The accumulated time (in us) spent in this block during the + /// past profiling cycle. + unsigned long int lastCycleTotalMicroseconds; + + /// The total accumulated time (in us) spent in this block. + unsigned long int totalMicroseconds; + }; + }; /// A static class that manages timing for a set of profiling blocks. @@ -336,6 +358,7 @@ public: /// Prints an error message to standard output. inline static void printError(const std::string& msg) { + //btAssert(0); std::cout << "[QuickProf error] " << msg << std::endl; } @@ -343,7 +366,7 @@ public: static bool mEnabled; /// The clock used to time profile blocks. - static hidden::Clock mClock; + static btClock mClock; /// The starting time (in us) of the current profiling cycle. static unsigned long int mCurrentCycleStartMicroseconds; diff --git a/extern/bullet2/src/LinearMath/btScalar.h b/extern/bullet2/src/LinearMath/btScalar.h index dd76fb2de1a..222315c1c74 100644 --- a/extern/bullet2/src/LinearMath/btScalar.h +++ b/extern/bullet2/src/LinearMath/btScalar.h @@ -25,10 +25,11 @@ subject to the following restrictions: #ifdef WIN32 - #if defined(__MINGW32__) || defined(__CYGWIN__) + #if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300) #define SIMD_FORCE_INLINE inline #define ATTRIBUTE_ALIGNED16(a) a #else + #define BT_HAS_ALIGNED_ALOCATOR #pragma warning(disable:4530) #pragma warning(disable:4996) #pragma warning(disable:4786) @@ -38,8 +39,21 @@ subject to the following restrictions: #include <assert.h> #define btAssert assert + //btFullAssert is optional, slows down a lot + #define btFullAssert(x) #else +#if defined (__CELLOS_LV2__) + #define SIMD_FORCE_INLINE inline + #define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) + #ifndef assert + #include <assert.h> + #endif + #define btAssert assert + //btFullAssert is optional, slows down a lot + #define btFullAssert(x) +#else + //non-windows systems #define SIMD_FORCE_INLINE inline @@ -48,16 +62,28 @@ subject to the following restrictions: #include <assert.h> #endif #define btAssert assert + //btFullAssert is optional, slows down a lot + #define btFullAssert(x) +#endif //__CELLOS_LV2__ #endif +/// older compilers (gcc 3.x) and Sun needs double version of sqrt etc. +/// exclude Apple Intel (i's assumed to be a Macbook or new Intel Dual Core Processor) +#if defined (__sun) || defined (__sun__) || defined (__sparc) || (defined (__APPLE__) && ! defined (__i386__)) +//use slow double float precision operation on those platforms +#ifndef BT_USE_DOUBLE_PRECISION +#define BT_FORCE_DOUBLE_FUNCTIONS +#endif +#endif +#if defined(BT_USE_DOUBLE_PRECISION) +typedef double btScalar; +#else +typedef float btScalar; +#endif -typedef float btScalar; -///older compilers (gcc 3.x) and Sun needs double versions of srqt etc. -///exclude Apple Intel (it's assumed to be a Macbook or newer Intel Dual Core processor) -#if defined (__sun) || defined (__sun__) || defined (__sparc) || (defined (__APPLE__) && ! defined (__i386__)) -//use slow double float precision operation on those platforms +#if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS) SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrt(x); } SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); } @@ -90,13 +116,19 @@ SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); } #endif -#define SIMD_2_PI 6.283185307179586232f -#define SIMD_PI (SIMD_2_PI * btScalar(0.5f)) -#define SIMD_HALF_PI (SIMD_2_PI * btScalar(0.25f)) -#define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0f)) -#define SIMD_DEGS_PER_RAD (btScalar(360.0f) / SIMD_2_PI) +#define SIMD_2_PI btScalar(6.283185307179586232) +#define SIMD_PI (SIMD_2_PI * btScalar(0.5)) +#define SIMD_HALF_PI (SIMD_2_PI * btScalar(0.25)) +#define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0)) +#define SIMD_DEGS_PER_RAD (btScalar(360.0) / SIMD_2_PI) + +#ifdef BT_USE_DOUBLE_PRECISION +#define SIMD_EPSILON DBL_EPSILON +#define SIMD_INFINITY DBL_MAX +#else #define SIMD_EPSILON FLT_EPSILON #define SIMD_INFINITY FLT_MAX +#endif SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; } @@ -117,7 +149,7 @@ SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y) */ SIMD_FORCE_INLINE int btIsNegative(btScalar x) { - return x < 0.0f ? 1 : 0; + return x < btScalar(0.0) ? 1 : 0; } SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; } diff --git a/extern/bullet2/src/LinearMath/btSimdMinMax.h b/extern/bullet2/src/LinearMath/btSimdMinMax.h index 2731c8b09f3..75e83f3c53f 100644 --- a/extern/bullet2/src/LinearMath/btSimdMinMax.h +++ b/extern/bullet2/src/LinearMath/btSimdMinMax.h @@ -16,7 +16,7 @@ subject to the following restrictions: #ifndef SIMD_MINMAX_H #define SIMD_MINMAX_H -#include "LinearMath/btScalar.h" +#include "btScalar.h" template <class T> SIMD_FORCE_INLINE const T& btMin(const T& a, const T& b) { diff --git a/extern/bullet2/src/LinearMath/btTransform.h b/extern/bullet2/src/LinearMath/btTransform.h index 3f9a48407c7..b1f3dfca492 100644 --- a/extern/bullet2/src/LinearMath/btTransform.h +++ b/extern/bullet2/src/LinearMath/btTransform.h @@ -17,8 +17,8 @@ subject to the following restrictions: #ifndef btTransform_H #define btTransform_H -#include "LinearMath/btVector3.h" -#include "LinearMath/btMatrix3x3.h" +#include "btVector3.h" +#include "btMatrix3x3.h" ///btTransform supports rigid transforms (only translation and rotation, no scaling/shear) @@ -48,17 +48,19 @@ public: m_origin = t1(t2.m_origin); } - void multInverseLeft(const btTransform& t1, const btTransform& t2) { +/* void multInverseLeft(const btTransform& t1, const btTransform& t2) { btVector3 v = t2.m_origin - t1.m_origin; m_basis = btMultTransposeLeft(t1.m_basis, t2.m_basis); m_origin = v * t1.m_basis; } + */ + SIMD_FORCE_INLINE btVector3 operator()(const btVector3& x) const { - return btVector3(m_basis[0].dot(x) + m_origin[0], - m_basis[1].dot(x) + m_origin[1], - m_basis[2].dot(x) + m_origin[2]); + return btVector3(m_basis[0].dot(x) + m_origin.x(), + m_basis[1].dot(x) + m_origin.y(), + m_basis[2].dot(x) + m_origin.z()); } SIMD_FORCE_INLINE btVector3 operator*(const btVector3& x) const @@ -88,18 +90,16 @@ public: void setFromOpenGLMatrix(const btScalar *m) { m_basis.setFromOpenGLSubMatrix(m); - m_origin[0] = m[12]; - m_origin[1] = m[13]; - m_origin[2] = m[14]; + m_origin.setValue(m[12],m[13],m[14]); } void getOpenGLMatrix(btScalar *m) const { m_basis.getOpenGLSubMatrix(m); - m[12] = m_origin[0]; - m[13] = m_origin[1]; - m[14] = m_origin[2]; - m[15] = btScalar(1.0f); + m[12] = m_origin.x(); + m[13] = m_origin.y(); + m[14] = m_origin.z(); + m[15] = btScalar(1.0); } SIMD_FORCE_INLINE void setOrigin(const btVector3& origin) diff --git a/extern/bullet2/src/LinearMath/btTransformUtil.h b/extern/bullet2/src/LinearMath/btTransformUtil.h index 39fa830f4df..bc42fd166b6 100644 --- a/extern/bullet2/src/LinearMath/btTransformUtil.h +++ b/extern/bullet2/src/LinearMath/btTransformUtil.h @@ -16,48 +16,40 @@ subject to the following restrictions: #ifndef SIMD_TRANSFORM_UTIL_H #define SIMD_TRANSFORM_UTIL_H -#include "LinearMath/btTransform.h" -#define ANGULAR_MOTION_THRESHOLD 0.5f*SIMD_HALF_PI +#include "btTransform.h" +#define ANGULAR_MOTION_THRESHOLD btScalar(0.5)*SIMD_HALF_PI #define SIMDSQRT12 btScalar(0.7071067811865475244008443621048490) -#define btRecipSqrt(x) ((float)(1.0f/btSqrt(float(x)))) /* reciprocal square root */ +#define btRecipSqrt(x) ((btScalar)(btScalar(1.0)/btSqrt(btScalar(x)))) /* reciprocal square root */ inline btVector3 btAabbSupport(const btVector3& halfExtents,const btVector3& supportDir) { - return btVector3(supportDir.x() < btScalar(0.0f) ? -halfExtents.x() : halfExtents.x(), - supportDir.y() < btScalar(0.0f) ? -halfExtents.y() : halfExtents.y(), - supportDir.z() < btScalar(0.0f) ? -halfExtents.z() : halfExtents.z()); + return btVector3(supportDir.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(), + supportDir.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(), + supportDir.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z()); } inline void btPlaneSpace1 (const btVector3& n, btVector3& p, btVector3& q) { - if (btFabs(n[2]) > SIMDSQRT12) { + if (btFabs(n.z()) > SIMDSQRT12) { // choose p in y-z plane btScalar a = n[1]*n[1] + n[2]*n[2]; btScalar k = btRecipSqrt (a); - p[0] = 0; - p[1] = -n[2]*k; - p[2] = n[1]*k; + p.setValue(0,-n[2]*k,n[1]*k); // set q = n x p - q[0] = a*k; - q[1] = -n[0]*p[2]; - q[2] = n[0]*p[1]; + q.setValue(a*k,-n[0]*p[2],n[0]*p[1]); } else { // choose p in x-y plane - btScalar a = n[0]*n[0] + n[1]*n[1]; + btScalar a = n.x()*n.x() + n.y()*n.y(); btScalar k = btRecipSqrt (a); - p[0] = -n[1]*k; - p[1] = n[0]*k; - p[2] = 0; + p.setValue(-n.y()*k,n.x()*k,0); // set q = n x p - q[0] = -n[2]*p[1]; - q[1] = n[2]*p[0]; - q[2] = a*k; + q.setValue(-n.z()*p.y(),n.z()*p.x(),a*k); } } @@ -74,9 +66,9 @@ public: predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep); // #define QUATERNION_DERIVATIVE #ifdef QUATERNION_DERIVATIVE - btQuaternion orn = curTrans.getRotation(); - orn += (angvel * orn) * (timeStep * 0.5f); - orn.normalize(); + btQuaternion predictedOrn = curTrans.getRotation(); + predictedOrn += (angvel * predictedOrn) * (timeStep * btScalar(0.5)); + predictedOrn.normalize(); #else //exponential map btVector3 axis; @@ -87,20 +79,21 @@ public: fAngle = ANGULAR_MOTION_THRESHOLD / timeStep; } - if ( fAngle < 0.001f ) + if ( fAngle < btScalar(0.001) ) { // use Taylor's expansions of sync function - axis = angvel*( 0.5f*timeStep-(timeStep*timeStep*timeStep)*(0.020833333333f)*fAngle*fAngle ); + axis = angvel*( btScalar(0.5)*timeStep-(timeStep*timeStep*timeStep)*(btScalar(0.020833333333))*fAngle*fAngle ); } else { // sync(fAngle) = sin(c*fAngle)/t - axis = angvel*( btSin(0.5f*fAngle*timeStep)/fAngle ); + axis = angvel*( btSin(btScalar(0.5)*fAngle*timeStep)/fAngle ); } - btQuaternion dorn (axis.x(),axis.y(),axis.z(),btCos( fAngle*timeStep*0.5f )); + btQuaternion dorn (axis.x(),axis.y(),axis.z(),btCos( fAngle*timeStep*btScalar(0.5) )); btQuaternion orn0 = curTrans.getRotation(); btQuaternion predictedOrn = dorn * orn0; + predictedOrn.normalize(); #endif predictedTransform.setRotation(predictedOrn); } @@ -130,11 +123,11 @@ public: angle = dorn.getAngle(); axis = btVector3(dorn.x(),dorn.y(),dorn.z()); - axis[3] = 0.f; + axis[3] = btScalar(0.); //check for axis length btScalar len = axis.length2(); if (len < SIMD_EPSILON*SIMD_EPSILON) - axis = btVector3(1.f,0.f,0.f); + axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.)); else axis /= btSqrt(len); } diff --git a/extern/bullet2/src/LinearMath/btVector3.h b/extern/bullet2/src/LinearMath/btVector3.h index 5a35652ecd3..74d41ad2a19 100644 --- a/extern/bullet2/src/LinearMath/btVector3.h +++ b/extern/bullet2/src/LinearMath/btVector3.h @@ -19,11 +19,10 @@ subject to the following restrictions: #include "btQuadWord.h" - -///btVector3 is 16byte aligned, and has an extra unused component m_w -///this extra component can be used by derived classes (Quaternion?) or by user -class btVector3 : public btQuadWord { - +///btVector3 can be used to represent 3D points and vectors. +///It has an un-used w component to suit 16-byte alignment when btVector3 is stored in containers. This extra component can be used by derived classes (Quaternion?) or by user +///Ideally, this class should be replaced by a platform optimized SIMD version that keeps the data in registers +class btVector3 : public btQuadWord { public: SIMD_FORCE_INLINE btVector3() {} @@ -31,7 +30,7 @@ public: SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z) - :btQuadWord(x,y,z,0.f) + :btQuadWord(x,y,z,btScalar(0.)) { } @@ -64,7 +63,7 @@ public: SIMD_FORCE_INLINE btVector3& operator/=(const btScalar& s) { - assert(s != btScalar(0.0)); + btFullAssert(s != btScalar(0.0)); return *this *= btScalar(1.0) / s; } @@ -99,7 +98,7 @@ public: SIMD_FORCE_INLINE btScalar angle(const btVector3& v) const { btScalar s = btSqrt(length2() * v.length2()); - assert(s != btScalar(0.0)); + btFullAssert(s != btScalar(0.0)); return btAcos(dot(v) / s); } @@ -148,10 +147,10 @@ public: SIMD_FORCE_INLINE void setInterpolate3(const btVector3& v0, const btVector3& v1, btScalar rt) { - btScalar s = 1.0f - rt; - m_x = s * v0[0] + rt * v1.x(); - m_y = s * v0[1] + rt * v1.y(); - m_z = s * v0[2] + rt * v1.z(); + btScalar s = btScalar(1.0) - rt; + m_x = s * v0.x() + rt * v1.x(); + m_y = s * v0.y() + rt * v1.y(); + m_z = s * v0.z() + rt * v1.z(); //don't do the unused w component // m_co[3] = s * v0[3] + rt * v1[3]; } @@ -213,7 +212,7 @@ operator*(const btScalar& s, const btVector3& v) SIMD_FORCE_INLINE btVector3 operator/(const btVector3& v, const btScalar& s) { - assert(s != btScalar(0.0)); + btFullAssert(s != btScalar(0.0)); return v * (btScalar(1.0) / s); } @@ -271,7 +270,7 @@ lerp(const btVector3& v1, const btVector3& v2, const btScalar& t) SIMD_FORCE_INLINE bool operator==(const btVector3& p1, const btVector3& p2) { - return p1[0] == p2[0] && p1[1] == p2[1] && p1[2] == p2[2]; + return p1.x() == p2.x() && p1.y() == p2.y() && p1.z() == p2.z(); } SIMD_FORCE_INLINE btScalar btVector3::distance2(const btVector3& v) const @@ -327,13 +326,13 @@ public: - float getW() const { return m_unusedW;} + btScalar getW() const { return m_unusedW;} SIMD_FORCE_INLINE int maxAxis4() const { int maxIndex = -1; - float maxVal = -1e30f; + btScalar maxVal = btScalar(-1e30); if (m_x > maxVal) { maxIndex = 0; @@ -366,7 +365,7 @@ public: SIMD_FORCE_INLINE int minAxis4() const { int minIndex = -1; - float minVal = 1e30f; + btScalar minVal = btScalar(1e30); if (m_x < minVal) { minIndex = 0; |