Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErwin Coumans <blender@erwincoumans.com>2006-10-23 06:54:30 +0400
committerErwin Coumans <blender@erwincoumans.com>2006-10-23 06:54:30 +0400
commit44d16f056215e6068f0b186a0ab766165cf3966e (patch)
treef0ad85e29c32563d1d4c1c46db4e2cd22f7f78dc /extern/bullet2/src/LinearMath
parente459764b4b056959e354edca3868a91ff9bc272f (diff)
Added refactored Bullet 2.x library. Important: these files are not part of the Blender build yet. First, the integration will be updated to make use of the new Bullet version. Then all build systems needs to be updated.
The refactoring didn't leave a single file the same, all filenames and classes have bt prefix, methodnames start with lowercase, a single headerfile can be included, and also a single include path. Plan is to make use of this Bullet 2.x version in extern/bullet2 within the coming weeks, then extern/bullet can be discarded/ignored/content removed.
Diffstat (limited to 'extern/bullet2/src/LinearMath')
-rw-r--r--extern/bullet2/src/LinearMath/CMakeLists.txt9
-rw-r--r--extern/bullet2/src/LinearMath/btAabbUtil2.h57
-rw-r--r--extern/bullet2/src/LinearMath/btDefaultMotionState.h34
-rw-r--r--extern/bullet2/src/LinearMath/btIDebugDraw.h69
-rw-r--r--extern/bullet2/src/LinearMath/btList.h73
-rw-r--r--extern/bullet2/src/LinearMath/btMatrix3x3.h395
-rw-r--r--extern/bullet2/src/LinearMath/btMinMax.h69
-rw-r--r--extern/bullet2/src/LinearMath/btMotionState.h38
-rw-r--r--extern/bullet2/src/LinearMath/btPoint3.h24
-rw-r--r--extern/bullet2/src/LinearMath/btQuadWord.h134
-rw-r--r--extern/bullet2/src/LinearMath/btQuaternion.h290
-rw-r--r--extern/bullet2/src/LinearMath/btQuickprof.cpp45
-rw-r--r--extern/bullet2/src/LinearMath/btQuickprof.h687
-rw-r--r--extern/bullet2/src/LinearMath/btRandom.h42
-rw-r--r--extern/bullet2/src/LinearMath/btScalar.h126
-rw-r--r--extern/bullet2/src/LinearMath/btSimdMinMax.h40
-rw-r--r--extern/bullet2/src/LinearMath/btTransform.h193
-rw-r--r--extern/bullet2/src/LinearMath/btTransformUtil.h143
-rw-r--r--extern/bullet2/src/LinearMath/btVector3.h403
19 files changed, 2871 insertions, 0 deletions
diff --git a/extern/bullet2/src/LinearMath/CMakeLists.txt b/extern/bullet2/src/LinearMath/CMakeLists.txt
new file mode 100644
index 00000000000..b9546167534
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/CMakeLists.txt
@@ -0,0 +1,9 @@
+
+INCLUDE_DIRECTORIES(
+${BULLET_PHYSICS_SOURCE_DIR}/src }
+)
+
+ADD_LIBRARY(LibLinearMath
+btQuickprof.cpp
+)
+
diff --git a/extern/bullet2/src/LinearMath/btAabbUtil2.h b/extern/bullet2/src/LinearMath/btAabbUtil2.h
new file mode 100644
index 00000000000..1cc7d4ebdf2
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btAabbUtil2.h
@@ -0,0 +1,57 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+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.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+
+#ifndef AABB_UTIL2
+#define AABB_UTIL2
+
+#include "LinearMath/btVector3.h"
+
+#define btMin(a,b) ((a < b ? a : b))
+#define btMax(a,b) ((a > b ? a : b))
+
+
+/// conservative test for overlap between two aabbs
+SIMD_FORCE_INLINE bool TestAabbAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1,
+ const btVector3 &aabbMin2, const btVector3 &aabbMax2)
+{
+ bool overlap = true;
+ overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
+ overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
+ overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
+ return overlap;
+}
+
+/// conservative test for overlap between triangle and aabb
+SIMD_FORCE_INLINE bool TestTriangleAgainstAabb2(const btVector3 *vertices,
+ const btVector3 &aabbMin, const btVector3 &aabbMax)
+{
+ const btVector3 &p1 = vertices[0];
+ const btVector3 &p2 = vertices[1];
+ const btVector3 &p3 = vertices[2];
+
+ if (btMin(btMin(p1[0], p2[0]), p3[0]) > aabbMax[0]) return false;
+ if (btMax(btMax(p1[0], p2[0]), p3[0]) < aabbMin[0]) return false;
+
+ if (btMin(btMin(p1[2], p2[2]), p3[2]) > aabbMax[2]) return false;
+ if (btMax(btMax(p1[2], p2[2]), p3[2]) < aabbMin[2]) return false;
+
+ if (btMin(btMin(p1[1], p2[1]), p3[1]) > aabbMax[1]) return false;
+ if (btMax(btMax(p1[1], p2[1]), p3[1]) < aabbMin[1]) return false;
+ return true;
+}
+
+#endif
+
diff --git a/extern/bullet2/src/LinearMath/btDefaultMotionState.h b/extern/bullet2/src/LinearMath/btDefaultMotionState.h
new file mode 100644
index 00000000000..c64f1352e10
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btDefaultMotionState.h
@@ -0,0 +1,34 @@
+#ifndef DEFAULT_MOTION_STATE_H
+#define DEFAULT_MOTION_STATE_H
+
+///btDefaultMotionState provides a common implementation to synchronize world transforms with offsets
+struct btDefaultMotionState : public btMotionState
+{
+ btTransform m_graphicsWorldTrans;
+ btTransform m_centerOfMassOffset;
+ btTransform m_startWorldTrans;
+ void* m_userPointer;
+
+ btDefaultMotionState(const btTransform& startTrans,const btTransform& centerOfMassOffset = btTransform::getIdentity())
+ : m_graphicsWorldTrans(startTrans),
+ m_centerOfMassOffset(centerOfMassOffset),
+ m_startWorldTrans(startTrans),
+ m_userPointer(0)
+
+ {
+ }
+
+ ///synchronizes world transform from user to physics
+ virtual void getWorldTransform(btTransform& centerOfMassWorldTrans )
+ {
+ centerOfMassWorldTrans = m_centerOfMassOffset.inverse() * m_graphicsWorldTrans ;
+ }
+
+ ///synchronizes world transform from physics to user
+ virtual void setWorldTransform(const btTransform& centerOfMassWorldTrans)
+ {
+ m_graphicsWorldTrans = centerOfMassWorldTrans * m_centerOfMassOffset ;
+ }
+};
+
+#endif //DEFAULT_MOTION_STATE_H \ No newline at end of file
diff --git a/extern/bullet2/src/LinearMath/btIDebugDraw.h b/extern/bullet2/src/LinearMath/btIDebugDraw.h
new file mode 100644
index 00000000000..86db735ce94
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btIDebugDraw.h
@@ -0,0 +1,69 @@
+/*
+Copyright (c) 2005 Gino van den Bergen / Erwin Coumans http://continuousphysics.com
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef IDEBUG_DRAW__H
+#define IDEBUG_DRAW__H
+
+#include "LinearMath/btVector3.h"
+
+
+class btIDebugDraw
+{
+ public:
+
+ enum DebugDrawModes
+ {
+ DBG_NoDebug=0,
+ DBG_DrawWireframe = 1,
+ DBG_DrawAabb=2,
+ DBG_DrawFeaturesText=4,
+ DBG_DrawContactPoints=8,
+ DBG_NoDeactivation=16,
+ DBG_NoHelpText = 32,
+ DBG_DrawText=64,
+ DBG_ProfileTimings = 128,
+ DBG_EnableSatComparison = 256,
+ DBG_DisableBulletLCP = 512,
+ DBG_EnableCCD = 1024,
+ DBG_MAX_DEBUG_DRAW_MODE
+ };
+
+ virtual ~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 setDebugMode(int debugMode) =0;
+
+ virtual int getDebugMode() const = 0;
+
+
+};
+
+#endif //IDEBUG_DRAW__H
+
diff --git a/extern/bullet2/src/LinearMath/btList.h b/extern/bullet2/src/LinearMath/btList.h
new file mode 100644
index 00000000000..c87b47faf2b
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btList.h
@@ -0,0 +1,73 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+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.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+
+#ifndef GEN_LIST_H
+#define GEN_LIST_H
+
+class btGEN_Link {
+public:
+ btGEN_Link() : m_next(0), m_prev(0) {}
+ btGEN_Link(btGEN_Link *next, btGEN_Link *prev) : m_next(next), m_prev(prev) {}
+
+ btGEN_Link *getNext() const { return m_next; }
+ btGEN_Link *getPrev() const { return m_prev; }
+
+ bool isHead() const { return m_prev == 0; }
+ bool isTail() const { return m_next == 0; }
+
+ void insertBefore(btGEN_Link *link) {
+ m_next = link;
+ m_prev = link->m_prev;
+ m_next->m_prev = this;
+ m_prev->m_next = this;
+ }
+
+ void insertAfter(btGEN_Link *link) {
+ m_next = link->m_next;
+ m_prev = link;
+ m_next->m_prev = this;
+ m_prev->m_next = this;
+ }
+
+ void remove() {
+ m_next->m_prev = m_prev;
+ m_prev->m_next = m_next;
+ }
+
+private:
+ btGEN_Link *m_next;
+ btGEN_Link *m_prev;
+};
+
+class btGEN_List {
+public:
+ btGEN_List() : m_head(&m_tail, 0), m_tail(0, &m_head) {}
+
+ btGEN_Link *getHead() const { return m_head.getNext(); }
+ btGEN_Link *getTail() const { return m_tail.getPrev(); }
+
+ void addHead(btGEN_Link *link) { link->insertAfter(&m_head); }
+ void addTail(btGEN_Link *link) { link->insertBefore(&m_tail); }
+
+private:
+ btGEN_Link m_head;
+ btGEN_Link m_tail;
+};
+
+#endif
+
+
+
diff --git a/extern/bullet2/src/LinearMath/btMatrix3x3.h b/extern/bullet2/src/LinearMath/btMatrix3x3.h
new file mode 100644
index 00000000000..c3cc90a82c7
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btMatrix3x3.h
@@ -0,0 +1,395 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+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.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#ifndef btMatrix3x3_H
+#define btMatrix3x3_H
+
+#include "LinearMath/btScalar.h"
+
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btQuaternion.h"
+
+
+class btMatrix3x3 {
+ public:
+ btMatrix3x3 () {}
+
+// explicit btMatrix3x3(const btScalar *m) { setFromOpenGLSubMatrix(m); }
+
+ explicit btMatrix3x3(const btQuaternion& q) { setRotation(q); }
+ /*
+ template <typename btScalar>
+ Matrix3x3(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
+ {
+ setEulerYPR(yaw, pitch, roll);
+ }
+ */
+ btMatrix3x3(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)
+ {
+ setValue(xx, xy, xz,
+ yx, yy, yz,
+ zx, zy, zz);
+ }
+
+ 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
+ {
+ return m_el[i];
+ }
+
+
+ SIMD_FORCE_INLINE btVector3& operator[](int i)
+ {
+ assert(0 <= i && i < 3);
+ return m_el[i];
+ }
+
+ const btVector3& operator[](int i) const
+ {
+ assert(0 <= i && i < 3);
+ return m_el[i];
+ }
+
+ btMatrix3x3& operator*=(const btMatrix3x3& m);
+
+
+ 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]);
+ }
+
+ 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);
+ }
+
+ void setRotation(const btQuaternion& q)
+ {
+ btScalar d = q.length2();
+ assert(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;
+ 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));
+ }
+
+
+
+ void setEulerYPR(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
+ {
+
+ btScalar cy(btCos(yaw));
+ btScalar sy(btSin(yaw));
+ btScalar cp(btCos(pitch));
+ btScalar sp(btSin(pitch));
+ btScalar cr(btCos(roll));
+ btScalar sr(btSin(roll));
+ btScalar cc = cy * cr;
+ btScalar cs = cy * sr;
+ btScalar sc = sy * cr;
+ btScalar ss = sy * sr;
+ setValue(cc - sp * ss, -cs - sp * sc, -sy * cp,
+ cp * sr, cp * cr, -sp,
+ sc + sp * cs, -ss + sp * cc, cy * cp);
+
+ }
+
+ /**
+ * setEulerZYX
+ * @param euler a const reference to a btVector3 of euler angles
+ * These angles are used to produce a rotation matrix. The euler
+ * angles are applied in ZYX order. I.e a vector is first rotated
+ * about X then Y and then Z
+ **/
+
+ void setEulerZYX(btScalar eulerX,btScalar eulerY,btScalar eulerZ) {
+ btScalar ci ( btCos(eulerX));
+ btScalar cj ( btCos(eulerY));
+ btScalar ch ( btCos(eulerZ));
+ btScalar si ( btSin(eulerX));
+ btScalar sj ( btSin(eulerY));
+ btScalar sh ( btSin(eulerZ));
+ btScalar cc = ci * ch;
+ btScalar cs = ci * sh;
+ btScalar sc = si * ch;
+ btScalar ss = si * sh;
+
+ setValue(cj * ch, sj * sc - cs, sj * cc + ss,
+ cj * sh, sj * ss + cc, sj * cs - sc,
+ -sj, cj * si, cj * ci);
+ }
+
+ void setIdentity()
+ {
+ setValue(btScalar(1.0), btScalar(0.0), btScalar(0.0),
+ btScalar(0.0), btScalar(1.0), btScalar(0.0),
+ btScalar(0.0), btScalar(0.0), btScalar(1.0));
+ }
+
+ 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[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[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[11] = btScalar(0.0);
+ }
+
+ void getRotation(btQuaternion& q) const
+ {
+ btScalar trace = m_el[0][0] + m_el[1][1] + m_el[2][2];
+
+ if (trace > btScalar(0.0))
+ {
+ btScalar s = btSqrt(trace + btScalar(1.0));
+ q[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;
+ }
+ 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 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);
+ 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;
+ }
+ }
+
+
+
+ void getEuler(btScalar& yaw, btScalar& pitch, btScalar& roll) const
+ {
+ pitch = btScalar(btAsin(-m_el[2][0]));
+ if (pitch < SIMD_2_PI)
+ {
+ if (pitch > SIMD_2_PI)
+ {
+ yaw = btScalar(btAtan2(m_el[1][0], m_el[0][0]));
+ roll = btScalar(btAtan2(m_el[2][1], m_el[2][2]));
+ }
+ else
+ {
+ yaw = btScalar(-btAtan2(-m_el[0][1], m_el[0][2]));
+ roll = btScalar(0.0);
+ }
+ }
+ else
+ {
+ yaw = btScalar(btAtan2(-m_el[0][1], m_el[0][2]));
+ 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]);
+ }
+
+ btScalar determinant() const;
+ btMatrix3x3 adjoint() const;
+ btMatrix3x3 absolute() const;
+ btMatrix3x3 transpose() const;
+ btMatrix3x3 inverse() const;
+
+ btMatrix3x3 transposeTimes(const btMatrix3x3& m) const;
+ btMatrix3x3 timesTranspose(const btMatrix3x3& m) const;
+
+ btScalar tdot(int c, const btVector3& v) const
+ {
+ return m_el[0][c] * v[0] + m_el[1][c] * v[1] + m_el[2][c] * v[2];
+ }
+
+ protected:
+ btScalar cofac(int r1, int c1, int r2, int c2) const
+ {
+ return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1];
+ }
+
+ btVector3 m_el[3];
+ };
+
+ 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]));
+ return *this;
+ }
+
+ SIMD_FORCE_INLINE btScalar
+ btMatrix3x3::determinant() const
+ {
+ return triple((*this)[0], (*this)[1], (*this)[2]);
+ }
+
+
+ SIMD_FORCE_INLINE 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]));
+ }
+
+ 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]);
+ }
+
+ SIMD_FORCE_INLINE btMatrix3x3
+ btMatrix3x3::adjoint() const
+ {
+ return btMatrix3x3(cofac(1, 1, 2, 2), cofac(0, 2, 2, 1), cofac(0, 1, 1, 2),
+ cofac(1, 2, 2, 0), cofac(0, 0, 2, 2), cofac(0, 2, 1, 0),
+ cofac(1, 0, 2, 1), cofac(0, 1, 2, 0), cofac(0, 0, 1, 1));
+ }
+
+ SIMD_FORCE_INLINE btMatrix3x3
+ btMatrix3x3::inverse() const
+ {
+ 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);
+ }
+
+ 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]);
+ }
+
+ SIMD_FORCE_INLINE btMatrix3x3
+ btMatrix3x3::timesTranspose(const btMatrix3x3& m) const
+ {
+ return btMatrix3x3(
+ m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]),
+ m_el[1].dot(m[0]), m_el[1].dot(m[1]), m_el[1].dot(m[2]),
+ m_el[2].dot(m[0]), m_el[2].dot(m[1]), m_el[2].dot(m[2]));
+
+ }
+
+ SIMD_FORCE_INLINE btVector3
+ operator*(const btMatrix3x3& m, const btVector3& v)
+ {
+ return btVector3(m[0].dot(v), m[1].dot(v), m[2].dot(v));
+ }
+
+
+ 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));
+ }
+
+ 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]));
+ }
+
+
+ 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],
+ m1[0][0] * m2[0][1] + m1[1][0] * m2[1][1] + m1[2][0] * m2[2][1],
+ m1[0][0] * m2[0][2] + m1[1][0] * m2[1][2] + m1[2][0] * m2[2][2],
+ m1[0][1] * m2[0][0] + m1[1][1] * m2[1][0] + m1[2][1] * m2[2][0],
+ m1[0][1] * m2[0][1] + m1[1][1] * m2[1][1] + m1[2][1] * m2[2][1],
+ m1[0][1] * m2[0][2] + m1[1][1] * m2[1][2] + m1[2][1] * m2[2][2],
+ m1[0][2] * m2[0][0] + m1[1][2] * m2[1][0] + m1[2][2] * m2[2][0],
+ 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/btMinMax.h b/extern/bullet2/src/LinearMath/btMinMax.h
new file mode 100644
index 00000000000..1b8a3633f38
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btMinMax.h
@@ -0,0 +1,69 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+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.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+
+#ifndef GEN_MINMAX_H
+#define GEN_MINMAX_H
+
+template <class T>
+SIMD_FORCE_INLINE const T& GEN_min(const T& a, const T& b)
+{
+ return b < a ? b : a;
+}
+
+template <class T>
+SIMD_FORCE_INLINE const T& GEN_max(const T& a, const T& b)
+{
+ return a < b ? b : a;
+}
+
+template <class T>
+SIMD_FORCE_INLINE const T& GEN_clamped(const T& a, const T& lb, const T& ub)
+{
+ return a < lb ? lb : (ub < a ? ub : a);
+}
+
+template <class T>
+SIMD_FORCE_INLINE void GEN_set_min(T& a, const T& b)
+{
+ if (b < a)
+ {
+ a = b;
+ }
+}
+
+template <class T>
+SIMD_FORCE_INLINE void GEN_set_max(T& a, const T& b)
+{
+ if (a < b)
+ {
+ a = b;
+ }
+}
+
+template <class T>
+SIMD_FORCE_INLINE void GEN_clamp(T& a, const T& lb, const T& ub)
+{
+ if (a < lb)
+ {
+ a = lb;
+ }
+ else if (ub < a)
+ {
+ a = ub;
+ }
+}
+
+#endif
diff --git a/extern/bullet2/src/LinearMath/btMotionState.h b/extern/bullet2/src/LinearMath/btMotionState.h
new file mode 100644
index 00000000000..4bbb3d44888
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btMotionState.h
@@ -0,0 +1,38 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+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.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_MOTIONSTATE_H
+#define BT_MOTIONSTATE_H
+
+#include "LinearMath/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)
+class btMotionState
+{
+ public:
+
+ virtual ~btMotionState()
+ {
+
+ }
+
+ virtual void getWorldTransform(btTransform& worldTrans )=0;
+
+ virtual void setWorldTransform(const btTransform& worldTrans)=0;
+
+};
+
+#endif //BT_MOTIONSTATE_H
diff --git a/extern/bullet2/src/LinearMath/btPoint3.h b/extern/bullet2/src/LinearMath/btPoint3.h
new file mode 100644
index 00000000000..4be7e9015bb
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btPoint3.h
@@ -0,0 +1,24 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+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.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+
+#ifndef btPoint3_H
+#define btPoint3_H
+
+#include "LinearMath/btVector3.h"
+
+typedef btVector3 btPoint3;
+
+#endif
diff --git a/extern/bullet2/src/LinearMath/btQuadWord.h b/extern/bullet2/src/LinearMath/btQuadWord.h
new file mode 100644
index 00000000000..28bb2051dea
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btQuadWord.h
@@ -0,0 +1,134 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+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.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#ifndef SIMD_QUADWORD_H
+#define SIMD_QUADWORD_H
+
+#include "LinearMath/btScalar.h"
+
+
+
+
+
+class btQuadWord
+{
+ protected:
+ ATTRIBUTE_ALIGNED16 (btScalar m_x);
+ btScalar m_y;
+ btScalar m_z;
+ btScalar m_unusedW;
+
+ 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 const btScalar& getX() const { return m_x; }
+
+ SIMD_FORCE_INLINE const btScalar& getY() const { return m_y; }
+
+ SIMD_FORCE_INLINE const btScalar& getZ() const { return m_z; }
+
+ SIMD_FORCE_INLINE void setX(float x) { m_x = x;};
+
+ SIMD_FORCE_INLINE void setY(float y) { m_y = y;};
+
+ SIMD_FORCE_INLINE void setZ(float z) { m_z = z;};
+
+ SIMD_FORCE_INLINE const btScalar& x() const { return m_x; }
+
+ SIMD_FORCE_INLINE const btScalar& y() const { return m_y; }
+
+ SIMD_FORCE_INLINE const btScalar& z() const { return m_z; }
+
+
+ operator btScalar *() { return &m_x; }
+ 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;
+ }
+
+/* void getValue(btScalar *m) const
+ {
+ m[0] = m_x;
+ m[1] = m_y;
+ m[2] = m_z;
+ }
+*/
+ SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
+ {
+ m_x=x;
+ m_y=y;
+ m_z=z;
+ 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(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)
+ {
+ }
+
+ SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
+ :m_x(x),m_y(y),m_z(z),m_unusedW(w)
+ {
+ }
+
+
+ SIMD_FORCE_INLINE void setMax(const btQuadWord& other)
+ {
+ if (other.m_x > m_x)
+ m_x = other.m_x;
+
+ if (other.m_y > m_y)
+ m_y = other.m_y;
+
+ if (other.m_z > m_z)
+ m_z = other.m_z;
+
+ if (other.m_unusedW > m_unusedW)
+ m_unusedW = other.m_unusedW;
+ }
+
+ SIMD_FORCE_INLINE void setMin(const btQuadWord& other)
+ {
+ if (other.m_x < m_x)
+ m_x = other.m_x;
+
+ if (other.m_y < m_y)
+ m_y = other.m_y;
+
+ if (other.m_z < m_z)
+ m_z = other.m_z;
+
+ if (other.m_unusedW < m_unusedW)
+ m_unusedW = other.m_unusedW;
+ }
+
+
+
+};
+
+#endif //SIMD_QUADWORD_H
diff --git a/extern/bullet2/src/LinearMath/btQuaternion.h b/extern/bullet2/src/LinearMath/btQuaternion.h
new file mode 100644
index 00000000000..aec25a54955
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btQuaternion.h
@@ -0,0 +1,290 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+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.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+
+#ifndef SIMD__QUATERNION_H_
+#define SIMD__QUATERNION_H_
+
+#include "LinearMath/btVector3.h"
+
+class btQuaternion : public btQuadWord {
+public:
+ btQuaternion() {}
+
+ // template <typename btScalar>
+ // explicit Quaternion(const btScalar *v) : Tuple4<btScalar>(v) {}
+
+ btQuaternion(const btScalar& x, const btScalar& y, const btScalar& z, const btScalar& w)
+ : btQuadWord(x, y, z, w)
+ {}
+
+ btQuaternion(const btVector3& axis, const btScalar& angle)
+ {
+ setRotation(axis, angle);
+ }
+
+ btQuaternion(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
+ {
+ setEuler(yaw, pitch, roll);
+ }
+
+ void setRotation(const btVector3& axis, const btScalar& angle)
+ {
+ btScalar d = axis.length();
+ assert(d != btScalar(0.0));
+ btScalar s = btSin(angle * btScalar(0.5)) / d;
+ setValue(axis.x() * s, axis.y() * s, axis.z() * s,
+ btCos(angle * btScalar(0.5)));
+ }
+
+ void setEuler(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
+ {
+ btScalar halfYaw = btScalar(yaw) * btScalar(0.5);
+ btScalar halfPitch = btScalar(pitch) * btScalar(0.5);
+ btScalar halfRoll = btScalar(roll) * btScalar(0.5);
+ btScalar cosYaw = btCos(halfYaw);
+ btScalar sinYaw = btSin(halfYaw);
+ btScalar cosPitch = btCos(halfPitch);
+ btScalar sinPitch = btSin(halfPitch);
+ btScalar cosRoll = btCos(halfRoll);
+ btScalar sinRoll = btSin(halfRoll);
+ setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw,
+ cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw,
+ sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw,
+ cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw);
+ }
+
+ btQuaternion& operator+=(const btQuaternion& q)
+ {
+ m_x += q.x(); m_y += q.y(); m_z += q.z(); m_unusedW += q[3];
+ return *this;
+ }
+
+ btQuaternion& operator-=(const btQuaternion& q)
+ {
+ m_x -= q.x(); m_y -= q.y(); m_z -= q.z(); m_unusedW -= q[3];
+ return *this;
+ }
+
+ btQuaternion& operator*=(const btScalar& s)
+ {
+ m_x *= s; m_y *= s; m_z *= s; m_unusedW *= s;
+ return *this;
+ }
+
+
+ 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());
+ 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];
+ }
+
+ btScalar length2() const
+ {
+ return dot(*this);
+ }
+
+ btScalar length() const
+ {
+ return btSqrt(length2());
+ }
+
+ btQuaternion& normalize()
+ {
+ return *this /= length();
+ }
+
+ SIMD_FORCE_INLINE btQuaternion
+ operator*(const btScalar& s) const
+ {
+ return btQuaternion(x() * s, y() * s, z() * s, m_unusedW * s);
+ }
+
+
+
+ btQuaternion operator/(const btScalar& s) const
+ {
+ assert(s != btScalar(0.0));
+ return *this * (btScalar(1.0) / s);
+ }
+
+
+ btQuaternion& operator/=(const btScalar& s)
+ {
+ assert(s != btScalar(0.0));
+ return *this *= btScalar(1.0) / s;
+ }
+
+
+ btQuaternion normalized() const
+ {
+ return *this / length();
+ }
+
+ btScalar angle(const btQuaternion& q) const
+ {
+ btScalar s = btSqrt(length2() * q.length2());
+ assert(s != btScalar(0.0));
+ return btAcos(dot(q) / s);
+ }
+
+ btScalar getAngle() const
+ {
+ btScalar s = 2.f * btAcos(m_unusedW);
+ return s;
+ }
+
+
+
+ btQuaternion inverse() const
+ {
+ return btQuaternion(m_x, m_y, m_z, -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]);
+ }
+
+ 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]);
+ }
+
+ SIMD_FORCE_INLINE btQuaternion operator-() const
+ {
+ const btQuaternion& q2 = *this;
+ return btQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2[3]);
+ }
+
+ SIMD_FORCE_INLINE btQuaternion farthest( const btQuaternion& qd) const
+ {
+ btQuaternion diff,sum;
+ diff = *this - qd;
+ sum = *this + qd;
+ if( diff.dot(diff) > sum.dot(sum) )
+ return qd;
+ return (-qd);
+ }
+
+ btQuaternion slerp(const btQuaternion& q, const btScalar& t) const
+ {
+ btScalar theta = angle(q);
+ if (theta != btScalar(0.0))
+ {
+ btScalar d = btScalar(1.0) / btSin(theta);
+ btScalar s0 = btSin((btScalar(1.0) - t) * theta);
+ btScalar s1 = btSin(t * theta);
+ 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);
+ }
+ else
+ {
+ return *this;
+ }
+ }
+
+ SIMD_FORCE_INLINE const btScalar& getW() const { return m_unusedW; }
+
+};
+
+
+
+SIMD_FORCE_INLINE btQuaternion
+operator-(const btQuaternion& q)
+{
+ return btQuaternion(-q.x(), -q.y(), -q.z(), -q[3]);
+}
+
+
+
+
+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());
+}
+
+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(),
+ -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(),
+ -w.x() * q.x() - w.y() * q.y() - w.z() * q.z());
+}
+
+SIMD_FORCE_INLINE btScalar
+dot(const btQuaternion& q1, const btQuaternion& q2)
+{
+ return q1.dot(q2);
+}
+
+
+SIMD_FORCE_INLINE btScalar
+length(const btQuaternion& q)
+{
+ return q.length();
+}
+
+SIMD_FORCE_INLINE btScalar
+angle(const btQuaternion& q1, const btQuaternion& q2)
+{
+ return q1.angle(q2);
+}
+
+
+SIMD_FORCE_INLINE btQuaternion
+inverse(const btQuaternion& q)
+{
+ return q.inverse();
+}
+
+SIMD_FORCE_INLINE btQuaternion
+slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t)
+{
+ return q1.slerp(q2, t);
+}
+
+
+#endif
+
+
+
diff --git a/extern/bullet2/src/LinearMath/btQuickprof.cpp b/extern/bullet2/src/LinearMath/btQuickprof.cpp
new file mode 100644
index 00000000000..23b8b8b2c40
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btQuickprof.cpp
@@ -0,0 +1,45 @@
+/************************************************************************
+* QuickProf *
+* Copyright (C) 2006 *
+* Tyler Streeter tylerstreeter@gmail.com *
+* All rights reserved. *
+* Web: http://quickprof.sourceforge.net *
+* *
+* This library is free software; you can redistribute it and/or *
+* modify it under the terms of EITHER: *
+* (1) The GNU Lesser bteral Public License as published by the Free *
+* Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. The text of the GNU Lesser *
+* bteral Public License is included with this library in the *
+* file license-LGPL.txt. *
+* (2) The BSD-style license that is included with this library in *
+* the file license-BSD.txt. *
+* *
+* This library is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
+* license-LGPL.txt and license-BSD.txt for more details. *
+************************************************************************/
+
+// Please visit the project website (http://quickprof.sourceforge.net)
+// for usage instructions.
+
+// Credits: The Clock class was inspired by the Timer classes in
+// Ogre (www.ogre3d.org).
+
+#include "LinearMath/btQuickprof.h"
+
+#ifdef USE_QUICKPROF
+
+// Note: We must declare these private static variables again here to
+// avoid link errors.
+bool btProfiler::mEnabled = false;
+hidden::Clock btProfiler::mClock;
+unsigned long int btProfiler::mCurrentCycleStartMicroseconds = 0;
+unsigned long int btProfiler::mLastCycleDurationMicroseconds = 0;
+std::map<std::string, hidden::ProfileBlock*> btProfiler::mProfileBlocks;
+std::ofstream btProfiler::mOutputFile;
+bool btProfiler::mFirstFileOutput = true;
+btProfiler::BlockTimingMethod btProfiler::mFileOutputMethod;
+unsigned long int btProfiler::mCycleNumber = 0;
+#endif //USE_QUICKPROF
diff --git a/extern/bullet2/src/LinearMath/btQuickprof.h b/extern/bullet2/src/LinearMath/btQuickprof.h
new file mode 100644
index 00000000000..801ef07a946
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btQuickprof.h
@@ -0,0 +1,687 @@
+/************************************************************************
+* QuickProf *
+* Copyright (C) 2006 *
+* Tyler Streeter tylerstreeter@gmail.com *
+* All rights reserved. *
+* Web: http://quickprof.sourceforge.net *
+* *
+* This library is free software; you can redistribute it and/or *
+* modify it under the terms of EITHER: *
+* (1) The GNU Lesser bteral Public License as published by the Free *
+* Software Foundation; either version 2.1 of the License, or (at *
+* your option) any later version. The text of the GNU Lesser *
+* bteral Public License is included with this library in the *
+* file license-LGPL.txt. *
+* (2) The BSD-style license that is included with this library in *
+* the file license-BSD.txt. *
+* *
+* This library is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
+* license-LGPL.txt and license-BSD.txt for more details. *
+************************************************************************/
+
+// Please visit the project website (http://quickprof.sourceforge.net)
+// for usage instructions.
+
+// Credits: The Clock class was inspired by the Timer classes in
+// Ogre (www.ogre3d.org).
+
+#ifndef QUICK_PROF_H
+#define QUICK_PROF_H
+
+#define USE_QUICKPROF 1
+
+#ifdef USE_QUICKPROF
+
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <map>
+
+#ifdef __PPU__
+#include <sys/sys_time.h>
+#include <stdio.h>
+typedef uint64_t __int64;
+#endif
+
+#if defined(WIN32) || defined(_WIN32)
+ #define USE_WINDOWS_TIMERS
+ #include <windows.h>
+ #include <time.h>
+#else
+ #include <sys/time.h>
+#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
+ {
+ public:
+ Clock()
+ {
+#ifdef USE_WINDOWS_TIMERS
+ QueryPerformanceFrequency(&mClockFrequency);
+#endif
+ reset();
+ }
+
+ ~Clock()
+ {
+ }
+
+ /// Resets the initial reference time.
+ void reset()
+ {
+#ifdef USE_WINDOWS_TIMERS
+ QueryPerformanceCounter(&mStartTime);
+ mStartTick = GetTickCount();
+ mPrevElapsedTime = 0;
+#else
+#ifdef __PPU__
+
+ typedef uint64_t __int64;
+ typedef __int64 ClockSize;
+ ClockSize newTime;
+ __asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
+ mStartTime = newTime;
+#else
+ gettimeofday(&mStartTime, NULL);
+#endif
+
+#endif
+ }
+
+ /// Returns the time in ms since the last call to reset or since
+ /// the Clock was created.
+ unsigned long int getTimeMilliseconds()
+ {
+#ifdef USE_WINDOWS_TIMERS
+ LARGE_INTEGER currentTime;
+ QueryPerformanceCounter(&currentTime);
+ LONGLONG elapsedTime = currentTime.QuadPart -
+ mStartTime.QuadPart;
+
+ // Compute the number of millisecond ticks elapsed.
+ unsigned long msecTicks = (unsigned long)(1000 * elapsedTime /
+ mClockFrequency.QuadPart);
+
+ // Check for unexpected leaps in the Win32 performance counter.
+ // (This is caused by unexpected data across the PCI to ISA
+ // bridge, aka south bridge. See Microsoft KB274323.)
+ unsigned long elapsedTicks = GetTickCount() - mStartTick;
+ signed long msecOff = (signed long)(msecTicks - elapsedTicks);
+ if (msecOff < -100 || msecOff > 100)
+ {
+ // Adjust the starting time forwards.
+ LONGLONG msecAdjustment = mymin(msecOff *
+ mClockFrequency.QuadPart / 1000, elapsedTime -
+ mPrevElapsedTime);
+ mStartTime.QuadPart += msecAdjustment;
+ elapsedTime -= msecAdjustment;
+
+ // Recompute the number of millisecond ticks elapsed.
+ msecTicks = (unsigned long)(1000 * elapsedTime /
+ mClockFrequency.QuadPart);
+ }
+
+ // Store the current elapsed time for adjustments next time.
+ mPrevElapsedTime = elapsedTime;
+
+ return msecTicks;
+#else
+
+#ifdef __PPU__
+ __int64 freq=sys_time_get_timebase_frequency();
+ double dFreq=((double) freq) / 1000.0;
+ typedef uint64_t __int64;
+ typedef __int64 ClockSize;
+ ClockSize newTime;
+ __asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
+
+ return (newTime-mStartTime) / dFreq;
+#else
+
+ struct timeval currentTime;
+ gettimeofday(&currentTime, NULL);
+ return (currentTime.tv_sec - mStartTime.tv_sec) * 1000 +
+ (currentTime.tv_usec - mStartTime.tv_usec) / 1000;
+#endif //__PPU__
+#endif
+ }
+
+ /// Returns the time in us since the last call to reset or since
+ /// the Clock was created.
+ unsigned long int getTimeMicroseconds()
+ {
+#ifdef USE_WINDOWS_TIMERS
+ LARGE_INTEGER currentTime;
+ QueryPerformanceCounter(&currentTime);
+ LONGLONG elapsedTime = currentTime.QuadPart -
+ mStartTime.QuadPart;
+
+ // Compute the number of millisecond ticks elapsed.
+ unsigned long msecTicks = (unsigned long)(1000 * elapsedTime /
+ mClockFrequency.QuadPart);
+
+ // Check for unexpected leaps in the Win32 performance counter.
+ // (This is caused by unexpected data across the PCI to ISA
+ // bridge, aka south bridge. See Microsoft KB274323.)
+ unsigned long elapsedTicks = GetTickCount() - mStartTick;
+ signed long msecOff = (signed long)(msecTicks - elapsedTicks);
+ if (msecOff < -100 || msecOff > 100)
+ {
+ // Adjust the starting time forwards.
+ LONGLONG msecAdjustment = mymin(msecOff *
+ mClockFrequency.QuadPart / 1000, elapsedTime -
+ mPrevElapsedTime);
+ mStartTime.QuadPart += msecAdjustment;
+ elapsedTime -= msecAdjustment;
+ }
+
+ // Store the current elapsed time for adjustments next time.
+ mPrevElapsedTime = elapsedTime;
+
+ // Convert to microseconds.
+ unsigned long usecTicks = (unsigned long)(1000000 * elapsedTime /
+ mClockFrequency.QuadPart);
+
+ return usecTicks;
+#else
+
+#ifdef __PPU__
+ __int64 freq=sys_time_get_timebase_frequency();
+ double dFreq=((double) freq)/ 1000000.0;
+ typedef uint64_t __int64;
+ typedef __int64 ClockSize;
+ ClockSize newTime;
+ __asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory");
+
+ return (newTime-mStartTime) / dFreq;
+#else
+
+ struct timeval currentTime;
+ gettimeofday(&currentTime, NULL);
+ return (currentTime.tv_sec - mStartTime.tv_sec) * 1000000 +
+ (currentTime.tv_usec - mStartTime.tv_usec);
+#endif//__PPU__
+#endif
+ }
+
+ private:
+#ifdef USE_WINDOWS_TIMERS
+ LARGE_INTEGER mClockFrequency;
+ DWORD mStartTick;
+ LONGLONG mPrevElapsedTime;
+ LARGE_INTEGER mStartTime;
+#else
+#ifdef __PPU__
+ uint64_t mStartTime;
+#else
+ struct timeval mStartTime;
+#endif
+#endif //__PPU__
+
+ };
+};
+
+/// A static class that manages timing for a set of profiling blocks.
+class btProfiler
+{
+public:
+ /// A set of ways to retrieve block timing data.
+ enum BlockTimingMethod
+ {
+ /// The total time spent in the block (in seconds) since the
+ /// profiler was initialized.
+ BLOCK_TOTAL_SECONDS,
+
+ /// The total time spent in the block (in ms) since the
+ /// profiler was initialized.
+ BLOCK_TOTAL_MILLISECONDS,
+
+ /// The total time spent in the block (in us) since the
+ /// profiler was initialized.
+ BLOCK_TOTAL_MICROSECONDS,
+
+ /// The total time spent in the block, as a % of the total
+ /// elapsed time since the profiler was initialized.
+ BLOCK_TOTAL_PERCENT,
+
+ /// The time spent in the block (in seconds) in the most recent
+ /// profiling cycle.
+ BLOCK_CYCLE_SECONDS,
+
+ /// The time spent in the block (in ms) in the most recent
+ /// profiling cycle.
+ BLOCK_CYCLE_MILLISECONDS,
+
+ /// The time spent in the block (in us) in the most recent
+ /// profiling cycle.
+ BLOCK_CYCLE_MICROSECONDS,
+
+ /// The time spent in the block (in seconds) in the most recent
+ /// profiling cycle, as a % of the total cycle time.
+ BLOCK_CYCLE_PERCENT
+ };
+
+ /// Initializes the profiler. This must be called first. If this is
+ /// never called, the profiler is effectively disabled; all other
+ /// functions will return immediately. The first parameter
+ /// is the name of an output data file; if this string is not empty,
+ /// data will be saved on every profiling cycle; if this string is
+ /// empty, no data will be saved to a file. The second parameter
+ /// determines which timing method is used when printing data to the
+ /// output file.
+ inline static void init(const std::string outputFilename="",
+ BlockTimingMethod outputMethod=BLOCK_CYCLE_MILLISECONDS);
+
+ /// Cleans up allocated memory.
+ inline static void destroy();
+
+ /// Begins timing the named block of code.
+ inline static void beginBlock(const std::string& name);
+
+ /// Updates the accumulated time spent in the named block by adding
+ /// the elapsed time since the last call to startBlock for this block
+ /// name.
+ inline static void endBlock(const std::string& name);
+
+ /// Returns the time spent in the named block according to the
+ /// given timing method. See comments on BlockTimingMethod for details.
+ inline static double getBlockTime(const std::string& name,
+ BlockTimingMethod method=BLOCK_CYCLE_MILLISECONDS);
+
+ /// Defines the end of a profiling cycle. Use this regularly if you
+ /// want to generate detailed timing information. This must not be
+ /// called within a timing block.
+ inline static void endProfilingCycle();
+
+ /// A helper function that creates a string of statistics for
+ /// each timing block. This is mainly for printing an overall
+ /// summary to the command line.
+ inline static std::string createStatsString(
+ BlockTimingMethod method=BLOCK_TOTAL_PERCENT);
+
+//private:
+ inline btProfiler();
+
+ inline ~btProfiler();
+
+ /// Prints an error message to standard output.
+ inline static void printError(const std::string& msg)
+ {
+ std::cout << "[QuickProf error] " << msg << std::endl;
+ }
+
+ /// Determines whether the profiler is enabled.
+ static bool mEnabled;
+
+ /// The clock used to time profile blocks.
+ static hidden::Clock mClock;
+
+ /// The starting time (in us) of the current profiling cycle.
+ static unsigned long int mCurrentCycleStartMicroseconds;
+
+ /// The duration (in us) of the most recent profiling cycle.
+ static unsigned long int mLastCycleDurationMicroseconds;
+
+ /// Internal map of named profile blocks.
+ static std::map<std::string, hidden::ProfileBlock*> mProfileBlocks;
+
+ /// The data file used if this feature is enabled in 'init.'
+ static std::ofstream mOutputFile;
+
+ /// Tracks whether we have begun print data to the output file.
+ static bool mFirstFileOutput;
+
+ /// The method used when printing timing data to an output file.
+ static BlockTimingMethod mFileOutputMethod;
+
+ /// The number of the current profiling cycle.
+ static unsigned long int mCycleNumber;
+};
+
+
+btProfiler::btProfiler()
+{
+ // This never gets called because a btProfiler instance is never
+ // created.
+}
+
+btProfiler::~btProfiler()
+{
+ // This never gets called because a btProfiler instance is never
+ // created.
+}
+
+void btProfiler::init(const std::string outputFilename,
+ BlockTimingMethod outputMethod)
+{
+ mEnabled = true;
+
+ if (!outputFilename.empty())
+ {
+ mOutputFile.open(outputFilename.c_str());
+ }
+
+ mFileOutputMethod = outputMethod;
+
+ mClock.reset();
+
+ // Set the start time for the first cycle.
+ mCurrentCycleStartMicroseconds = mClock.getTimeMicroseconds();
+}
+
+void btProfiler::destroy()
+{
+ if (!mEnabled)
+ {
+ return;
+ }
+
+ if (mOutputFile.is_open())
+ {
+ mOutputFile.close();
+ }
+
+ // Destroy all ProfileBlocks.
+ while (!mProfileBlocks.empty())
+ {
+ delete (*mProfileBlocks.begin()).second;
+ mProfileBlocks.erase(mProfileBlocks.begin());
+ }
+}
+
+void btProfiler::beginBlock(const std::string& name)
+{
+ if (!mEnabled)
+ {
+ return;
+ }
+
+ if (name.empty())
+ {
+ printError("Cannot allow unnamed profile blocks.");
+ return;
+ }
+
+ hidden::ProfileBlock* block = mProfileBlocks[name];
+
+ if (!block)
+ {
+ // Create a new ProfileBlock.
+ mProfileBlocks[name] = new hidden::ProfileBlock();
+ block = mProfileBlocks[name];
+ }
+
+ // We do this at the end to get more accurate results.
+ block->currentBlockStartMicroseconds = mClock.getTimeMicroseconds();
+}
+
+void btProfiler::endBlock(const std::string& name)
+{
+ if (!mEnabled)
+ {
+ return;
+ }
+
+ // We do this at the beginning to get more accurate results.
+ unsigned long int endTick = mClock.getTimeMicroseconds();
+
+ hidden::ProfileBlock* block = mProfileBlocks[name];
+
+ if (!block)
+ {
+ // The named block does not exist. Print an error.
+ printError("The profile block named '" + name +
+ "' does not exist.");
+ return;
+ }
+
+ unsigned long int blockDuration = endTick -
+ block->currentBlockStartMicroseconds;
+ block->currentCycleTotalMicroseconds += blockDuration;
+ block->totalMicroseconds += blockDuration;
+}
+
+double btProfiler::getBlockTime(const std::string& name,
+ BlockTimingMethod method)
+{
+ if (!mEnabled)
+ {
+ return 0;
+ }
+
+ hidden::ProfileBlock* block = mProfileBlocks[name];
+
+ if (!block)
+ {
+ // The named block does not exist. Print an error.
+ printError("The profile block named '" + name +
+ "' does not exist.");
+ return 0;
+ }
+
+ double result = 0;
+
+ switch(method)
+ {
+ case BLOCK_TOTAL_SECONDS:
+ result = (double)block->totalMicroseconds * (double)0.000001;
+ break;
+ case BLOCK_TOTAL_MILLISECONDS:
+ result = (double)block->totalMicroseconds * (double)0.001;
+ break;
+ case BLOCK_TOTAL_MICROSECONDS:
+ result = (double)block->totalMicroseconds;
+ break;
+ case BLOCK_TOTAL_PERCENT:
+ {
+ double timeSinceInit = (double)mClock.getTimeMicroseconds();
+ if (timeSinceInit <= 0)
+ {
+ result = 0;
+ }
+ else
+ {
+ result = 100.0 * (double)block->totalMicroseconds /
+ timeSinceInit;
+ }
+ break;
+ }
+ case BLOCK_CYCLE_SECONDS:
+ result = (double)block->lastCycleTotalMicroseconds *
+ (double)0.000001;
+ break;
+ case BLOCK_CYCLE_MILLISECONDS:
+ result = (double)block->lastCycleTotalMicroseconds *
+ (double)0.001;
+ break;
+ case BLOCK_CYCLE_MICROSECONDS:
+ result = (double)block->lastCycleTotalMicroseconds;
+ break;
+ case BLOCK_CYCLE_PERCENT:
+ {
+ if (0 == mLastCycleDurationMicroseconds)
+ {
+ // We have not yet finished a cycle, so just return zero
+ // percent to avoid a divide by zero error.
+ result = 0;
+ }
+ else
+ {
+ result = 100.0 * (double)block->lastCycleTotalMicroseconds /
+ mLastCycleDurationMicroseconds;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return result;
+}
+
+void btProfiler::endProfilingCycle()
+{
+ if (!mEnabled)
+ {
+ return;
+ }
+
+ // Store the duration of the cycle that just finished.
+ mLastCycleDurationMicroseconds = mClock.getTimeMicroseconds() -
+ mCurrentCycleStartMicroseconds;
+
+ // For each block, update data for the cycle that just finished.
+ std::map<std::string, hidden::ProfileBlock*>::iterator iter;
+ for (iter = mProfileBlocks.begin(); iter != mProfileBlocks.end(); ++iter)
+ {
+ hidden::ProfileBlock* block = (*iter).second;
+ block->lastCycleTotalMicroseconds =
+ block->currentCycleTotalMicroseconds;
+ block->currentCycleTotalMicroseconds = 0;
+ }
+
+ if (mOutputFile.is_open())
+ {
+ // Print data to the output file.
+ if (mFirstFileOutput)
+ {
+ // On the first iteration, print a header line that shows the
+ // names of each profiling block.
+ mOutputFile << "#cycle, ";
+
+ for (iter = mProfileBlocks.begin(); iter != mProfileBlocks.end();
+ ++iter)
+ {
+ mOutputFile << (*iter).first << ", ";
+ }
+
+ mOutputFile << std::endl;
+ mFirstFileOutput = false;
+ }
+
+ mOutputFile << mCycleNumber << ", ";
+
+ for (iter = mProfileBlocks.begin(); iter != mProfileBlocks.end();
+ ++iter)
+ {
+ mOutputFile << getBlockTime((*iter).first, mFileOutputMethod)
+ << ", ";
+ }
+
+ mOutputFile << std::endl;
+ }
+
+ ++mCycleNumber;
+ mCurrentCycleStartMicroseconds = mClock.getTimeMicroseconds();
+}
+
+std::string btProfiler::createStatsString(BlockTimingMethod method)
+{
+ if (!mEnabled)
+ {
+ return "";
+ }
+
+ std::string s;
+ std::string suffix;
+
+ switch(method)
+ {
+ case BLOCK_TOTAL_SECONDS:
+ suffix = "s";
+ break;
+ case BLOCK_TOTAL_MILLISECONDS:
+ suffix = "ms";
+ break;
+ case BLOCK_TOTAL_MICROSECONDS:
+ suffix = "us";
+ break;
+ case BLOCK_TOTAL_PERCENT:
+ {
+ suffix = "%";
+ break;
+ }
+ case BLOCK_CYCLE_SECONDS:
+ suffix = "s";
+ break;
+ case BLOCK_CYCLE_MILLISECONDS:
+ suffix = "ms";
+ break;
+ case BLOCK_CYCLE_MICROSECONDS:
+ suffix = "us";
+ break;
+ case BLOCK_CYCLE_PERCENT:
+ {
+ suffix = "%";
+ break;
+ }
+ default:
+ break;
+ }
+
+ std::map<std::string, hidden::ProfileBlock*>::iterator iter;
+ for (iter = mProfileBlocks.begin(); iter != mProfileBlocks.end(); ++iter)
+ {
+ if (iter != mProfileBlocks.begin())
+ {
+ s += "\n";
+ }
+
+ char blockTime[64];
+ sprintf(blockTime, "%lf", getBlockTime((*iter).first, method));
+
+ s += (*iter).first;
+ s += ": ";
+ s += blockTime;
+ s += " ";
+ s += suffix;
+ }
+
+ return s;
+}
+
+
+#define BEGIN_PROFILE(a) btProfiler::beginBlock(a)
+#define END_PROFILE(a) btProfiler::endBlock(a)
+
+#else //USE_QUICKPROF
+#define BEGIN_PROFILE(a)
+#define END_PROFILE(a)
+
+#endif //USE_QUICKPROF
+
+#endif //QUICK_PROF_H
+
diff --git a/extern/bullet2/src/LinearMath/btRandom.h b/extern/bullet2/src/LinearMath/btRandom.h
new file mode 100644
index 00000000000..fdf65e01caf
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btRandom.h
@@ -0,0 +1,42 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+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.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+
+#ifndef GEN_RANDOM_H
+#define GEN_RANDOM_H
+
+#ifdef MT19937
+
+#include <limits.h>
+#include <mt19937.h>
+
+#define GEN_RAND_MAX UINT_MAX
+
+SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { init_genrand(seed); }
+SIMD_FORCE_INLINE unsigned int GEN_rand() { return genrand_int32(); }
+
+#else
+
+#include <stdlib.h>
+
+#define GEN_RAND_MAX RAND_MAX
+
+SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { srand(seed); }
+SIMD_FORCE_INLINE unsigned int GEN_rand() { return rand(); }
+
+#endif
+
+#endif
+
diff --git a/extern/bullet2/src/LinearMath/btScalar.h b/extern/bullet2/src/LinearMath/btScalar.h
new file mode 100644
index 00000000000..dea040a80bd
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btScalar.h
@@ -0,0 +1,126 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+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.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+
+#ifndef SIMD___SCALAR_H
+#define SIMD___SCALAR_H
+
+#include <math.h>
+
+#include <cstdlib>
+#include <cfloat>
+#include <float.h>
+
+#ifdef WIN32
+
+ #if defined(__MINGW32__) || defined(__CYGWIN__)
+ #define SIMD_FORCE_INLINE inline
+ #else
+ #pragma warning(disable:4530)
+ #pragma warning(disable:4996)
+ #pragma warning(disable:4786)
+ #define SIMD_FORCE_INLINE __forceinline
+ #endif //__MINGW32__
+
+ //#define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a
+ #define ATTRIBUTE_ALIGNED16(a) a
+ #include <assert.h>
+ #define ASSERT assert
+#else
+
+ //non-windows systems
+
+ #define SIMD_FORCE_INLINE inline
+ #define ATTRIBUTE_ALIGNED16(a) a
+ #ifndef assert
+ #include <assert.h>
+ #endif
+ #define ASSERT assert
+#endif
+
+
+
+typedef float btScalar;
+
+#if defined (__sun) || defined (__sun__) || defined (__sparc) || defined (__APPLE__)
+//use double float precision operation on those platforms for Blender
+
+SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrt(x); }
+SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); }
+SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); }
+SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); }
+SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); }
+SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { return acos(x); }
+SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asin(x); }
+SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); }
+SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); }
+SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return exp(x); }
+SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); }
+SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); }
+
+#else
+
+SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrtf(x); }
+SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); }
+SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); }
+SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); }
+SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); }
+SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { return acosf(x); }
+SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asinf(x); }
+SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); }
+SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); }
+SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); }
+SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); }
+SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); }
+
+#endif
+
+
+const btScalar SIMD_2_PI = 6.283185307179586232f;
+const btScalar SIMD_PI = SIMD_2_PI * btScalar(0.5f);
+const btScalar SIMD_HALF_PI = SIMD_2_PI * btScalar(0.25f);
+const btScalar SIMD_RADS_PER_DEG = SIMD_2_PI / btScalar(360.0f);
+const btScalar SIMD_DEGS_PER_RAD = btScalar(360.0f) / SIMD_2_PI;
+const btScalar SIMD_EPSILON = FLT_EPSILON;
+const btScalar SIMD_INFINITY = FLT_MAX;
+
+SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; }
+
+SIMD_FORCE_INLINE bool btEqual(btScalar a, btScalar eps) {
+ return (((a) <= eps) && !((a) < -eps));
+}
+SIMD_FORCE_INLINE bool btGreaterEqual (btScalar a, btScalar eps) {
+ return (!((a) <= eps));
+}
+
+/*SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); }
+SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); }
+SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); }
+SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { return acosf(x); }
+SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { return asinf(x); }
+SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); }
+SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); }
+*/
+
+SIMD_FORCE_INLINE int btSign(btScalar x) {
+ return x < 0.0f ? -1 : x > 0.0f ? 1 : 0;
+}
+
+SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; }
+SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; }
+
+
+
+#endif //SIMD___SCALAR_H
diff --git a/extern/bullet2/src/LinearMath/btSimdMinMax.h b/extern/bullet2/src/LinearMath/btSimdMinMax.h
new file mode 100644
index 00000000000..16c31552f88
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btSimdMinMax.h
@@ -0,0 +1,40 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+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.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+
+#ifndef SIMD_MINMAX_H
+#define SIMD_MINMAX_H
+
+template <class T>
+SIMD_FORCE_INLINE const T& btMin(const T& a, const T& b) {
+ return b < a ? b : a;
+}
+
+template <class T>
+SIMD_FORCE_INLINE const T& btMax(const T& a, const T& b) {
+ return a < b ? b : a;
+}
+
+template <class T>
+SIMD_FORCE_INLINE void btSetMin(T& a, const T& b) {
+ if (a > b) a = b;
+}
+
+template <class T>
+SIMD_FORCE_INLINE void btSetMax(T& a, const T& b) {
+ if (a < b) a = b;
+}
+
+#endif
diff --git a/extern/bullet2/src/LinearMath/btTransform.h b/extern/bullet2/src/LinearMath/btTransform.h
new file mode 100644
index 00000000000..3f9a48407c7
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btTransform.h
@@ -0,0 +1,193 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+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.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+
+#ifndef btTransform_H
+#define btTransform_H
+
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btMatrix3x3.h"
+
+
+///btTransform supports rigid transforms (only translation and rotation, no scaling/shear)
+class btTransform {
+
+
+public:
+
+
+ btTransform() {}
+
+ explicit SIMD_FORCE_INLINE btTransform(const btQuaternion& q,
+ const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0)))
+ : m_basis(q),
+ m_origin(c)
+ {}
+
+ explicit SIMD_FORCE_INLINE btTransform(const btMatrix3x3& b,
+ const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0)))
+ : m_basis(b),
+ m_origin(c)
+ {}
+
+
+ SIMD_FORCE_INLINE void mult(const btTransform& t1, const btTransform& t2) {
+ m_basis = t1.m_basis * t2.m_basis;
+ m_origin = t1(t2.m_origin);
+ }
+
+ 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]);
+ }
+
+ SIMD_FORCE_INLINE btVector3 operator*(const btVector3& x) const
+ {
+ return (*this)(x);
+ }
+
+ SIMD_FORCE_INLINE btMatrix3x3& getBasis() { return m_basis; }
+ SIMD_FORCE_INLINE const btMatrix3x3& getBasis() const { return m_basis; }
+
+ SIMD_FORCE_INLINE btVector3& getOrigin() { return m_origin; }
+ SIMD_FORCE_INLINE const btVector3& getOrigin() const { return m_origin; }
+
+ btQuaternion getRotation() const {
+ btQuaternion q;
+ m_basis.getRotation(q);
+ return q;
+ }
+ template <typename Scalar2>
+ void setValue(const Scalar2 *m)
+ {
+ m_basis.setValue(m);
+ m_origin.setValue(&m[12]);
+ }
+
+
+ void setFromOpenGLMatrix(const btScalar *m)
+ {
+ m_basis.setFromOpenGLSubMatrix(m);
+ m_origin[0] = m[12];
+ m_origin[1] = m[13];
+ m_origin[2] = 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);
+ }
+
+ SIMD_FORCE_INLINE void setOrigin(const btVector3& origin)
+ {
+ m_origin = origin;
+ }
+
+ SIMD_FORCE_INLINE btVector3 invXform(const btVector3& inVec) const;
+
+
+
+ SIMD_FORCE_INLINE void setBasis(const btMatrix3x3& basis)
+ {
+ m_basis = basis;
+ }
+
+ SIMD_FORCE_INLINE void setRotation(const btQuaternion& q)
+ {
+ m_basis.setRotation(q);
+ }
+
+
+
+ void setIdentity()
+ {
+ m_basis.setIdentity();
+ m_origin.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
+ }
+
+
+ btTransform& operator*=(const btTransform& t)
+ {
+ m_origin += m_basis * t.m_origin;
+ m_basis *= t.m_basis;
+ return *this;
+ }
+
+ btTransform inverse() const
+ {
+ btMatrix3x3 inv = m_basis.transpose();
+ return btTransform(inv, inv * -m_origin);
+ }
+
+ btTransform inverseTimes(const btTransform& t) const;
+
+ btTransform operator*(const btTransform& t) const;
+
+ static btTransform getIdentity()
+ {
+ btTransform tr;
+ tr.setIdentity();
+ return tr;
+ }
+
+private:
+
+ btMatrix3x3 m_basis;
+ btVector3 m_origin;
+};
+
+
+SIMD_FORCE_INLINE btVector3
+btTransform::invXform(const btVector3& inVec) const
+{
+ btVector3 v = inVec - m_origin;
+ return (m_basis.transpose() * v);
+}
+
+SIMD_FORCE_INLINE btTransform
+btTransform::inverseTimes(const btTransform& t) const
+{
+ btVector3 v = t.getOrigin() - m_origin;
+ return btTransform(m_basis.transposeTimes(t.m_basis),
+ v * m_basis);
+}
+
+SIMD_FORCE_INLINE btTransform
+btTransform::operator*(const btTransform& t) const
+{
+ return btTransform(m_basis * t.m_basis,
+ (*this)(t.m_origin));
+}
+
+
+
+#endif
+
+
+
+
+
diff --git a/extern/bullet2/src/LinearMath/btTransformUtil.h b/extern/bullet2/src/LinearMath/btTransformUtil.h
new file mode 100644
index 00000000000..da8e4aa72a8
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btTransformUtil.h
@@ -0,0 +1,143 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+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.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#ifndef SIMD_TRANSFORM_UTIL_H
+#define SIMD_TRANSFORM_UTIL_H
+
+#include "LinearMath/btTransform.h"
+#define ANGULAR_MOTION_TRESHOLD 0.5f*SIMD_HALF_PI
+
+
+
+#define SIMDSQRT12 btScalar(0.7071067811865475244008443621048490)
+
+#define btRecipSqrt(x) ((float)(1.0f/btSqrt(float(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());
+}
+
+
+inline void btPlaneSpace1 (const btVector3& n, btVector3& p, btVector3& q)
+{
+ if (btFabs(n[2]) > 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;
+ // set q = n x p
+ q[0] = a*k;
+ q[1] = -n[0]*p[2];
+ q[2] = n[0]*p[1];
+ }
+ else {
+ // choose p in x-y plane
+ btScalar a = n[0]*n[0] + n[1]*n[1];
+ btScalar k = btRecipSqrt (a);
+ p[0] = -n[1]*k;
+ p[1] = n[0]*k;
+ p[2] = 0;
+ // set q = n x p
+ q[0] = -n[2]*p[1];
+ q[1] = n[2]*p[0];
+ q[2] = a*k;
+ }
+}
+
+
+
+/// Utils related to temporal transforms
+class btTransformUtil
+{
+
+public:
+
+ static void integrateTransform(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep,btTransform& predictedTransform)
+ {
+ predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep);
+// #define QUATERNION_DERIVATIVE
+ #ifdef QUATERNION_DERIVATIVE
+ btQuaternion orn = curTrans.getRotation();
+ orn += (angvel * orn) * (timeStep * 0.5f);
+ orn.normalize();
+ #else
+ //exponential map
+ btVector3 axis;
+ btScalar fAngle = angvel.length();
+ //limit the angular motion
+ if (fAngle*timeStep > ANGULAR_MOTION_TRESHOLD)
+ {
+ fAngle = ANGULAR_MOTION_TRESHOLD / timeStep;
+ }
+
+ if ( fAngle < 0.001f )
+ {
+ // use Taylor's expansions of sync function
+ axis = angvel*( 0.5f*timeStep-(timeStep*timeStep*timeStep)*(0.020833333333f)*fAngle*fAngle );
+ }
+ else
+ {
+ // sync(fAngle) = sin(c*fAngle)/t
+ axis = angvel*( btSin(0.5f*fAngle*timeStep)/fAngle );
+ }
+ btQuaternion dorn (axis.x(),axis.y(),axis.z(),btCos( fAngle*timeStep*0.5f ));
+ btQuaternion orn0 = curTrans.getRotation();
+
+ btQuaternion predictedOrn = dorn * orn0;
+ #endif
+ predictedTransform.setRotation(predictedOrn);
+ }
+
+ static void calculateVelocity(const btTransform& transform0,const btTransform& transform1,btScalar timeStep,btVector3& linVel,btVector3& angVel)
+ {
+ linVel = (transform1.getOrigin() - transform0.getOrigin()) / timeStep;
+#ifdef USE_QUATERNION_DIFF
+ btQuaternion orn0 = transform0.getRotation();
+ btQuaternion orn1a = transform1.getRotation();
+ btQuaternion orn1 = orn0.farthest(orn1a);
+ btQuaternion dorn = orn1 * orn0.inverse();
+#else
+ btMatrix3x3 dmat = transform1.getBasis() * transform0.getBasis().inverse();
+ btQuaternion dorn;
+ dmat.getRotation(dorn);
+#endif//USE_QUATERNION_DIFF
+
+ btVector3 axis;
+ btScalar angle;
+ angle = dorn.getAngle();
+ axis = btVector3(dorn.x(),dorn.y(),dorn.z());
+ axis[3] = 0.f;
+ //check for axis length
+ btScalar len = axis.length2();
+ if (len < SIMD_EPSILON*SIMD_EPSILON)
+ axis = btVector3(1.f,0.f,0.f);
+ else
+ axis /= btSqrt(len);
+
+
+ angVel = axis * angle / timeStep;
+
+ }
+
+
+};
+
+#endif //SIMD_TRANSFORM_UTIL_H
+
diff --git a/extern/bullet2/src/LinearMath/btVector3.h b/extern/bullet2/src/LinearMath/btVector3.h
new file mode 100644
index 00000000000..5a35652ecd3
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btVector3.h
@@ -0,0 +1,403 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+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.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+
+#ifndef SIMD__VECTOR3_H
+#define SIMD__VECTOR3_H
+
+#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 {
+
+
+public:
+ SIMD_FORCE_INLINE btVector3() {}
+
+
+
+ SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z)
+ :btQuadWord(x,y,z,0.f)
+ {
+ }
+
+// SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
+// : btQuadWord(x,y,z,w)
+// {
+// }
+
+
+
+ SIMD_FORCE_INLINE btVector3& operator+=(const btVector3& v)
+ {
+ m_x += v.x(); m_y += v.y(); m_z += v.z();
+ return *this;
+ }
+
+
+
+ SIMD_FORCE_INLINE btVector3& operator-=(const btVector3& v)
+ {
+ m_x -= v.x(); m_y -= v.y(); m_z -= v.z();
+ return *this;
+ }
+
+ SIMD_FORCE_INLINE btVector3& operator*=(const btScalar& s)
+ {
+ m_x *= s; m_y *= s; m_z *= s;
+ return *this;
+ }
+
+ SIMD_FORCE_INLINE btVector3& operator/=(const btScalar& s)
+ {
+ assert(s != btScalar(0.0));
+ return *this *= btScalar(1.0) / s;
+ }
+
+ SIMD_FORCE_INLINE btScalar dot(const btVector3& v) const
+ {
+ return m_x * v.x() + m_y * v.y() + m_z * v.z();
+ }
+
+ SIMD_FORCE_INLINE btScalar length2() const
+ {
+ return dot(*this);
+ }
+
+ SIMD_FORCE_INLINE btScalar length() const
+ {
+ return btSqrt(length2());
+ }
+
+ SIMD_FORCE_INLINE btScalar distance2(const btVector3& v) const;
+
+ SIMD_FORCE_INLINE btScalar distance(const btVector3& v) const;
+
+ SIMD_FORCE_INLINE btVector3& normalize()
+ {
+ return *this /= length();
+ }
+
+ SIMD_FORCE_INLINE btVector3 normalized() const;
+
+ SIMD_FORCE_INLINE btVector3 rotate( const btVector3& wAxis, const btScalar angle );
+
+ SIMD_FORCE_INLINE btScalar angle(const btVector3& v) const
+ {
+ btScalar s = btSqrt(length2() * v.length2());
+ assert(s != btScalar(0.0));
+ return btAcos(dot(v) / s);
+ }
+
+ SIMD_FORCE_INLINE btVector3 absolute() const
+ {
+ return btVector3(
+ btFabs(m_x),
+ btFabs(m_y),
+ btFabs(m_z));
+ }
+
+ SIMD_FORCE_INLINE btVector3 cross(const btVector3& v) const
+ {
+ return btVector3(
+ m_y * v.z() - m_z * v.y(),
+ m_z * v.x() - m_x * v.z(),
+ m_x * v.y() - m_y * v.x());
+ }
+
+ SIMD_FORCE_INLINE btScalar triple(const btVector3& v1, const btVector3& v2) const
+ {
+ return m_x * (v1.y() * v2.z() - v1.z() * v2.y()) +
+ m_y * (v1.z() * v2.x() - v1.x() * v2.z()) +
+ m_z * (v1.x() * v2.y() - v1.y() * v2.x());
+ }
+
+ SIMD_FORCE_INLINE int minAxis() const
+ {
+ return m_x < m_y ? (m_x < m_z ? 0 : 2) : (m_y < m_z ? 1 : 2);
+ }
+
+ SIMD_FORCE_INLINE int maxAxis() const
+ {
+ return m_x < m_y ? (m_y < m_z ? 2 : 1) : (m_x < m_z ? 2 : 0);
+ }
+
+ SIMD_FORCE_INLINE int furthestAxis() const
+ {
+ return absolute().minAxis();
+ }
+
+ SIMD_FORCE_INLINE int closestAxis() const
+ {
+ return absolute().maxAxis();
+ }
+
+ 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();
+ //don't do the unused w component
+ // m_co[3] = s * v0[3] + rt * v1[3];
+ }
+
+ SIMD_FORCE_INLINE btVector3 lerp(const btVector3& v, const btScalar& t) const
+ {
+ return btVector3(m_x + (v.x() - m_x) * t,
+ m_y + (v.y() - m_y) * t,
+ m_z + (v.z() - m_z) * t);
+ }
+
+
+ SIMD_FORCE_INLINE btVector3& operator*=(const btVector3& v)
+ {
+ m_x *= v.x(); m_y *= v.y(); m_z *= v.z();
+ return *this;
+ }
+
+
+
+};
+
+SIMD_FORCE_INLINE btVector3
+operator+(const btVector3& v1, const btVector3& v2)
+{
+ return btVector3(v1.x() + v2.x(), v1.y() + v2.y(), v1.z() + v2.z());
+}
+
+SIMD_FORCE_INLINE btVector3
+operator*(const btVector3& v1, const btVector3& v2)
+{
+ return btVector3(v1.x() * v2.x(), v1.y() * v2.y(), v1.z() * v2.z());
+}
+
+SIMD_FORCE_INLINE btVector3
+operator-(const btVector3& v1, const btVector3& v2)
+{
+ return btVector3(v1.x() - v2.x(), v1.y() - v2.y(), v1.z() - v2.z());
+}
+
+SIMD_FORCE_INLINE btVector3
+operator-(const btVector3& v)
+{
+ return btVector3(-v.x(), -v.y(), -v.z());
+}
+
+SIMD_FORCE_INLINE btVector3
+operator*(const btVector3& v, const btScalar& s)
+{
+ return btVector3(v.x() * s, v.y() * s, v.z() * s);
+}
+
+SIMD_FORCE_INLINE btVector3
+operator*(const btScalar& s, const btVector3& v)
+{
+ return v * s;
+}
+
+SIMD_FORCE_INLINE btVector3
+operator/(const btVector3& v, const btScalar& s)
+{
+ assert(s != btScalar(0.0));
+ return v * (btScalar(1.0) / s);
+}
+
+SIMD_FORCE_INLINE btVector3
+operator/(const btVector3& v1, const btVector3& v2)
+{
+ return btVector3(v1.x() / v2.x(),v1.y() / v2.y(),v1.z() / v2.z());
+}
+
+SIMD_FORCE_INLINE btScalar
+dot(const btVector3& v1, const btVector3& v2)
+{
+ return v1.dot(v2);
+}
+
+
+
+SIMD_FORCE_INLINE btScalar
+distance2(const btVector3& v1, const btVector3& v2)
+{
+ return v1.distance2(v2);
+}
+
+
+SIMD_FORCE_INLINE btScalar
+distance(const btVector3& v1, const btVector3& v2)
+{
+ return v1.distance(v2);
+}
+
+SIMD_FORCE_INLINE btScalar
+angle(const btVector3& v1, const btVector3& v2)
+{
+ return v1.angle(v2);
+}
+
+SIMD_FORCE_INLINE btVector3
+cross(const btVector3& v1, const btVector3& v2)
+{
+ return v1.cross(v2);
+}
+
+SIMD_FORCE_INLINE btScalar
+triple(const btVector3& v1, const btVector3& v2, const btVector3& v3)
+{
+ return v1.triple(v2, v3);
+}
+
+SIMD_FORCE_INLINE btVector3
+lerp(const btVector3& v1, const btVector3& v2, const btScalar& t)
+{
+ return v1.lerp(v2, 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];
+}
+
+SIMD_FORCE_INLINE btScalar btVector3::distance2(const btVector3& v) const
+{
+ return (v - *this).length2();
+}
+
+SIMD_FORCE_INLINE btScalar btVector3::distance(const btVector3& v) const
+{
+ return (v - *this).length();
+}
+
+SIMD_FORCE_INLINE btVector3 btVector3::normalized() const
+{
+ return *this / length();
+}
+
+SIMD_FORCE_INLINE btVector3 btVector3::rotate( const btVector3& wAxis, const btScalar angle )
+{
+ // wAxis must be a unit lenght vector
+
+ btVector3 o = wAxis * wAxis.dot( *this );
+ btVector3 x = *this - o;
+ btVector3 y;
+
+ y = wAxis.cross( *this );
+
+ return ( o + x * btCos( angle ) + y * btSin( angle ) );
+}
+
+class btVector4 : public btVector3
+{
+public:
+
+ SIMD_FORCE_INLINE btVector4() {}
+
+
+ SIMD_FORCE_INLINE btVector4(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
+ : btVector3(x,y,z)
+ {
+ m_unusedW = w;
+ }
+
+
+ SIMD_FORCE_INLINE btVector4 absolute4() const
+ {
+ return btVector4(
+ btFabs(m_x),
+ btFabs(m_y),
+ btFabs(m_z),
+ btFabs(m_unusedW));
+ }
+
+
+
+ float getW() const { return m_unusedW;}
+
+
+ SIMD_FORCE_INLINE int maxAxis4() const
+ {
+ int maxIndex = -1;
+ float maxVal = -1e30f;
+ if (m_x > maxVal)
+ {
+ maxIndex = 0;
+ maxVal = m_x;
+ }
+ if (m_y > maxVal)
+ {
+ maxIndex = 1;
+ maxVal = m_y;
+ }
+ if (m_z > maxVal)
+ {
+ maxIndex = 2;
+ maxVal = m_z;
+ }
+ if (m_unusedW > maxVal)
+ {
+ maxIndex = 3;
+ maxVal = m_unusedW;
+ }
+
+
+
+
+ return maxIndex;
+
+ }
+
+
+ SIMD_FORCE_INLINE int minAxis4() const
+ {
+ int minIndex = -1;
+ float minVal = 1e30f;
+ if (m_x < minVal)
+ {
+ minIndex = 0;
+ minVal = m_x;
+ }
+ if (m_y < minVal)
+ {
+ minIndex = 1;
+ minVal = m_y;
+ }
+ if (m_z < minVal)
+ {
+ minIndex = 2;
+ minVal = m_z;
+ }
+ if (m_unusedW < minVal)
+ {
+ minIndex = 3;
+ minVal = m_unusedW;
+ }
+
+ return minIndex;
+
+ }
+
+
+ SIMD_FORCE_INLINE int closestAxis4() const
+ {
+ return absolute4().maxAxis4();
+ }
+
+};
+
+#endif //SIMD__VECTOR3_H