Apple contribution for OSX SSE and iOS NEON optimizations unit tests, thanks to Jordan Hubbard, Ian Ollmann and Hristo Hristov.

For OSX:
cd build
./premake_osx xcode4
for iOS:
cd build
./ios_build.sh
./ios_run.sh

Also integrated the branches/StackAllocation to make it easier to multi-thread collision detection in the near future. It avoids changing the btCollisionObject while performing collision detection.

As this is a large patch, some stuff might be temporarily broken, I'll keep an eye out on issues.
This commit is contained in:
erwin.coumans
2012-06-07 00:56:30 +00:00
parent 777b92a2ad
commit 73b217fb07
323 changed files with 30730 additions and 13635 deletions

View File

@@ -57,7 +57,7 @@ SET(AllBulletDemos_SRCS
IF (WIN32) IF (WIN32)
ADD_EXECUTABLE(AppAllBulletDemos ADD_EXECUTABLE(AppAllBulletDemos
${AllBulletDemos_SRCS} ${AllBulletDemos_SRCS}
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ELSE() ELSE()
ADD_EXECUTABLE(AppAllBulletDemos ADD_EXECUTABLE(AppAllBulletDemos

View File

@@ -27,7 +27,7 @@ ADD_EXECUTABLE(AppBasicDemo
main.cpp main.cpp
BasicDemo.cpp BasicDemo.cpp
BasicDemo.h BasicDemo.h
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ELSE() ELSE()
ADD_EXECUTABLE(AppBasicDemo ADD_EXECUTABLE(AppBasicDemo
@@ -74,7 +74,7 @@ ELSE (USE_GLUT)
Win32BasicDemo.cpp Win32BasicDemo.cpp
BasicDemo.cpp BasicDemo.cpp
BasicDemo.h BasicDemo.h
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )

View File

@@ -1252,21 +1252,24 @@ void BenchmarkDemo::exitPhysics()
RagDoll* doll = m_ragdolls[i]; RagDoll* doll = m_ragdolls[i];
delete doll; delete doll;
} }
m_ragdolls.clear();
//cleanup in the reverse order of creation/initialization //cleanup in the reverse order of creation/initialization
if (m_dynamicsWorld)
//remove the rigidbodies from the dynamics world and delete them {
for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) //remove the rigidbodies from the dynamics world and delete them
{ for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; {
btRigidBody* body = btRigidBody::upcast(obj); btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
if (body && body->getMotionState()) btRigidBody* body = btRigidBody::upcast(obj);
{ if (body && body->getMotionState())
delete body->getMotionState(); {
} delete body->getMotionState();
m_dynamicsWorld->removeCollisionObject( obj ); }
delete obj; m_dynamicsWorld->removeCollisionObject( obj );
} delete obj;
}
}
//delete collision shapes //delete collision shapes
for (int j=0;j<m_collisionShapes.size();j++) for (int j=0;j<m_collisionShapes.size();j++)
@@ -1274,20 +1277,26 @@ void BenchmarkDemo::exitPhysics()
btCollisionShape* shape = m_collisionShapes[j]; btCollisionShape* shape = m_collisionShapes[j];
delete shape; delete shape;
} }
m_collisionShapes.clear();
//delete dynamics world //delete dynamics world
delete m_dynamicsWorld; delete m_dynamicsWorld;
m_dynamicsWorld=0;
//delete solver //delete solver
delete m_solver; delete m_solver;
m_solver=0;
//delete broadphase //delete broadphase
delete m_overlappingPairCache; delete m_overlappingPairCache;
m_overlappingPairCache=0;
//delete dispatcher //delete dispatcher
delete m_dispatcher; delete m_dispatcher;
m_dispatcher=0;
delete m_collisionConfiguration; delete m_collisionConfiguration;
m_collisionConfiguration=0;
} }

View File

@@ -27,7 +27,7 @@ IF (USE_GLUT)
main.cpp main.cpp
BenchmarkDemo.cpp BenchmarkDemo.cpp
BenchmarkDemo.h BenchmarkDemo.h
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ELSE() ELSE()
ADD_EXECUTABLE(AppBenchmarks ADD_EXECUTABLE(AppBenchmarks
@@ -83,7 +83,7 @@ ELSE (USE_GLUT)
BenchmarkDemo.cpp BenchmarkDemo.cpp
BenchmarkDemo.h BenchmarkDemo.h
Win32BenchmarkDemo.cpp Win32BenchmarkDemo.cpp
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ENDIF (USE_GLUT) ENDIF (USE_GLUT)
ELSE (USE_GRAPHICAL_BENCHMARK) ELSE (USE_GRAPHICAL_BENCHMARK)

View File

@@ -22,12 +22,12 @@ subject to the following restrictions:
#include "GlutStuff.h" #include "GlutStuff.h"
#include "GLDebugDrawer.h" #include "GLDebugDrawer.h"
GLDebugDrawer gDebugDrawer; GLDebugDrawer gDebugDrawer;
#define benchmarkDemo benchmarkDemo4 #define benchmarkDemo benchmarkDemo2
#endif //USE_GRAPHICAL_BENCHMARK #endif //USE_GRAPHICAL_BENCHMARK
#define NUM_DEMOS 7 #define NUM_DEMOS 7
#define NUM_TESTS 650 #define NUM_TESTS 200
extern bool gDisableDeactivation; extern bool gDisableDeactivation;
@@ -75,6 +75,7 @@ int main(int argc,char** argv)
} }
demoArray[d]->exitPhysics();
} }
for (d=0;d<NUM_DEMOS;d++) for (d=0;d<NUM_DEMOS;d++)

View File

@@ -0,0 +1,22 @@
project "AppBenchmarks"
if _OPTIONS["ios"] then
kind "WindowedApp"
else
kind "ConsoleApp"
end
includedirs {"../../src"}
links {
"BulletDynamics","BulletCollision", "LinearMath"
}
language "C++"
files {
"**.cpp",
"**.h",
}

View File

@@ -25,7 +25,7 @@ IF (USE_GLUT)
main.cpp main.cpp
Box2dDemo.cpp Box2dDemo.cpp
Box2dDemo.h Box2dDemo.h
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ELSE() ELSE()
ADD_EXECUTABLE(AppBox2dDemo ADD_EXECUTABLE(AppBox2dDemo
@@ -63,7 +63,7 @@ ELSE (USE_GLUT)
Win32Box2dDemo.cpp Win32Box2dDemo.cpp
Box2dDemo.cpp Box2dDemo.cpp
Box2dDemo.h Box2dDemo.h
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ENDIF (USE_GLUT) ENDIF (USE_GLUT)

View File

@@ -23,7 +23,7 @@ IF (WIN32)
ADD_EXECUTABLE(AppCcdPhysicsDemo ADD_EXECUTABLE(AppCcdPhysicsDemo
main.cpp main.cpp
CcdPhysicsDemo.cpp CcdPhysicsDemo.cpp
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ELSE() ELSE()
ADD_EXECUTABLE(AppCcdPhysicsDemo ADD_EXECUTABLE(AppCcdPhysicsDemo

View File

@@ -32,7 +32,7 @@ SET(CharacterDemo_SRCS
IF (WIN32) IF (WIN32)
ADD_EXECUTABLE(AppCharacterDemo ADD_EXECUTABLE(AppCharacterDemo
${CharacterDemo_SRCS} ${CharacterDemo_SRCS}
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ELSE() ELSE()
ADD_EXECUTABLE(AppCharacterDemo ADD_EXECUTABLE(AppCharacterDemo

View File

@@ -21,7 +21,7 @@ OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY}
IF (WIN32) IF (WIN32)
ADD_EXECUTABLE(AppCollisionDemo ADD_EXECUTABLE(AppCollisionDemo
CollisionDemo.cpp CollisionDemo.cpp
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ELSE() ELSE()
ADD_EXECUTABLE(AppCollisionDemo ADD_EXECUTABLE(AppCollisionDemo

View File

@@ -167,7 +167,7 @@ void CollisionDemo::displayCallback(void) {
convexConvex.getClosestPoints(input, gjkOutput, 0); convexConvex.getClosestPoints(input, gjkOutput, 0);
} }
btScalar m[16]; ATTRIBUTE_ALIGNED16(btScalar) m[16];
int i; int i;
//m_ele = 21.2; //m_ele = 21.2;
@@ -257,7 +257,7 @@ void CollisionDemo::displayCallback(void) {
if (mystate!=2 || i==myiter) if (mystate!=2 || i==myiter)
{ {
btScalar m[16]; ATTRIBUTE_ALIGNED16(btScalar) m[16];
input.m_transformA.getOpenGLMatrix( m ); input.m_transformA.getOpenGLMatrix( m );
//m_shapeDrawer->drawOpenGL(m,shapePtr[0],btVector3(108./255.,131./255.,158./255),btIDebugDraw::DBG_FastWireframe,worldBoundsMin,worldBoundsMax); //m_shapeDrawer->drawOpenGL(m,shapePtr[0],btVector3(108./255.,131./255.,158./255),btIDebugDraw::DBG_FastWireframe,worldBoundsMin,worldBoundsMax);

View File

@@ -24,7 +24,7 @@ IF (USE_GLUT)
CollisionInterfaceDemo.cpp CollisionInterfaceDemo.cpp
CollisionInterfaceDemo.h CollisionInterfaceDemo.h
main.cpp main.cpp
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ELSE() ELSE()
ADD_EXECUTABLE(AppCollisionInterfaceDemo ADD_EXECUTABLE(AppCollisionInterfaceDemo
@@ -65,7 +65,7 @@ ELSE (USE_GLUT)
CollisionInterfaceDemo.h CollisionInterfaceDemo.h
Win32CollisionInterfaceDemo.cpp Win32CollisionInterfaceDemo.cpp
../OpenGL/Win32AppMain.cpp ../OpenGL/Win32AppMain.cpp
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ENDIF (USE_GLUT) ENDIF (USE_GLUT)

View File

@@ -104,7 +104,7 @@ btSimplexSolverInterface& gGjkSimplexSolver = sGjkSimplexSolver;
struct btDrawingResult : public btCollisionWorld::ContactResultCallback struct btDrawingResult : public btCollisionWorld::ContactResultCallback
{ {
virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1)
{ {
glBegin(GL_LINES); glBegin(GL_LINES);

View File

@@ -198,7 +198,7 @@ public:
void drawCube (const btTransform& T) void drawCube (const btTransform& T)
{ {
btScalar m[16]; ATTRIBUTE_ALIGNED16(btScalar) m[16];
T.getOpenGLMatrix (&m[0]); T.getOpenGLMatrix (&m[0]);
glPushMatrix (); glPushMatrix ();
#ifdef BT_USE_DOUBLE_PRECISION #ifdef BT_USE_DOUBLE_PRECISION

View File

@@ -25,7 +25,7 @@ IF (USE_GLUT)
ADD_EXECUTABLE(AppConcaveDemo ADD_EXECUTABLE(AppConcaveDemo
ConcavePhysicsDemo.cpp ConcavePhysicsDemo.cpp
main.cpp main.cpp
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ELSE() ELSE()
ADD_EXECUTABLE(AppConcaveDemo ADD_EXECUTABLE(AppConcaveDemo
@@ -68,7 +68,7 @@ ELSE (USE_GLUT)
ConcavePhysicsDemo.cpp ConcavePhysicsDemo.cpp
ConcaveDemo.h ConcaveDemo.h
Win32ConcaveDemo.cpp Win32ConcaveDemo.cpp
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ENDIF (USE_GLUT) ENDIF (USE_GLUT)

View File

@@ -75,20 +75,20 @@ inline btScalar calculateCombinedRestitution(float restitution0,float restitutio
static bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) static bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1)
{ {
float friction0 = colObj0->getFriction(); float friction0 = colObj0Wrap->getCollisionObject()->getFriction();
float friction1 = colObj1->getFriction(); float friction1 = colObj1Wrap->getCollisionObject()->getFriction();
float restitution0 = colObj0->getRestitution(); float restitution0 = colObj0Wrap->getCollisionObject()->getRestitution();
float restitution1 = colObj1->getRestitution(); float restitution1 = colObj1Wrap->getCollisionObject()->getRestitution();
if (colObj0->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) if (colObj0Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)
{ {
friction0 = 1.0;//partId0,index0 friction0 = 1.0;//partId0,index0
restitution0 = 0.f; restitution0 = 0.f;
} }
if (colObj1->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) if (colObj1Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)
{ {
if (index1&1) if (index1&1)
{ {

View File

@@ -22,7 +22,7 @@ IF (WIN32)
ADD_EXECUTABLE(AppConcaveRayCastDemo ADD_EXECUTABLE(AppConcaveRayCastDemo
ConcaveRaycastDemo.cpp ConcaveRaycastDemo.cpp
main.cpp main.cpp
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ELSE() ELSE()
ADD_EXECUTABLE(AppConcaveRayCastDemo ADD_EXECUTABLE(AppConcaveRayCastDemo

View File

@@ -60,7 +60,7 @@ LINK_LIBRARIES(
ConvexDecompositionDemo.cpp ConvexDecompositionDemo.cpp
ConvexDecompositionDemo.h ConvexDecompositionDemo.h
Win32ConvexDecompositionDemo.cpp Win32ConvexDecompositionDemo.cpp
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ENDIF (USE_GLUT) ENDIF (USE_GLUT)

View File

@@ -80,24 +80,24 @@ void ConvexDecompositionDemo::initPhysics()
///MyContactCallback is just an example to show how to get access to the child shape that collided ///MyContactCallback is just an example to show how to get access to the child shape that collided
bool MyContactCallback ( bool MyContactCallback (
btManifoldPoint& cp, btManifoldPoint& cp,
const btCollisionObject* colObj0, const btCollisionObjectWrapper* colObj0Wrap,
int partId0, int partId0,
int index0, int index0,
const btCollisionObject* colObj1, const btCollisionObjectWrapper* colObj1Wrap,
int partId1, int partId1,
int index1) int index1)
{ {
if (colObj0->getRootCollisionShape()->getShapeType()==COMPOUND_SHAPE_PROXYTYPE) if (colObj0Wrap->getCollisionObject()->getCollisionShape()->getShapeType()==COMPOUND_SHAPE_PROXYTYPE)
{ {
btCompoundShape* compound = (btCompoundShape*)colObj0->getRootCollisionShape(); btCompoundShape* compound = (btCompoundShape*)colObj0Wrap->getCollisionObject()->getCollisionShape();
btCollisionShape* childShape; btCollisionShape* childShape;
childShape = compound->getChildShape(index0); childShape = compound->getChildShape(index0);
} }
if (colObj1->getRootCollisionShape()->getShapeType()==COMPOUND_SHAPE_PROXYTYPE) if (colObj1Wrap->getCollisionObject()->getCollisionShape()->getShapeType()==COMPOUND_SHAPE_PROXYTYPE)
{ {
btCompoundShape* compound = (btCompoundShape*)colObj1->getRootCollisionShape(); btCompoundShape* compound = (btCompoundShape*)colObj1Wrap->getCollisionObject()->getCollisionShape();
btCollisionShape* childShape; btCollisionShape* childShape;
childShape = compound->getChildShape(index1); childShape = compound->getChildShape(index1);
} }

View File

@@ -36,13 +36,14 @@ class btDefaultCollisionConfiguration;
class btTriangleMesh; class btTriangleMesh;
///ConvexDecompositionDemo shows automatic convex decomposition of a concave mesh ///ConvexDecompositionDemo shows automatic convex decomposition of a concave mesh
class ConvexDecompositionDemo : public PlatformDemoApplication ATTRIBUTE_ALIGNED16(class) ConvexDecompositionDemo : public PlatformDemoApplication
{ {
void setupEmptyDynamicsWorld(); void setupEmptyDynamicsWorld();
public: public:
BT_DECLARE_ALIGNED_ALLOCATOR();
//keep the collision shapes, for deletion/cleanup //keep the collision shapes, for deletion/cleanup
btAlignedObjectArray<btCollisionShape*> m_collisionShapes; btAlignedObjectArray<btCollisionShape*> m_collisionShapes;

View File

@@ -26,7 +26,7 @@ IF (WIN32)
ADD_EXECUTABLE(AppConvexHullDistanceDemo ADD_EXECUTABLE(AppConvexHullDistanceDemo
ConvexHullDistanceDemo.cpp ConvexHullDistanceDemo.cpp
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ELSE() ELSE()
ADD_EXECUTABLE(AppConvexHullDistanceDemo ADD_EXECUTABLE(AppConvexHullDistanceDemo
@@ -69,7 +69,7 @@ ELSE (USE_GLUT)
WIN32 WIN32
../OpenGL/Win32AppMain.cpp ../OpenGL/Win32AppMain.cpp
ConvexHullDistanceDemo.cpp ConvexHullDistanceDemo.cpp
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )

View File

@@ -276,7 +276,7 @@ void clientDisplay(void) {
//GL_ShapeDrawer::drawCoordSystem(); //GL_ShapeDrawer::drawCoordSystem();
btScalar m[16]; ATTRIBUTE_ALIGNED16(btScalar) m[16];
int i; int i;
#ifdef USE_GJK #ifdef USE_GJK
btGjkEpaPenetrationDepthSolver epa; btGjkEpaPenetrationDepthSolver epa;
@@ -309,7 +309,7 @@ void clientDisplay(void) {
struct MyContactResultCallback : public btCollisionWorld::ContactResultCallback struct MyContactResultCallback : public btCollisionWorld::ContactResultCallback
{ {
virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1)
{ {
glBegin(GL_LINES); glBegin(GL_LINES);
glColor3f(1, 0, 0); glColor3f(1, 0, 0);

View File

@@ -132,8 +132,8 @@ void DoublePrecisionDemo::displayCallback(void)
for (i=0;i<numManifolds;i++) for (i=0;i<numManifolds;i++)
{ {
btPersistentManifold* contactManifold = collisionWorld->getDispatcher()->getManifoldByIndexInternal(i); btPersistentManifold* contactManifold = collisionWorld->getDispatcher()->getManifoldByIndexInternal(i);
btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0()); const btCollisionObject* obA = static_cast<const btCollisionObject*>(contactManifold->getBody0());
btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1()); const btCollisionObject* obB = static_cast<const btCollisionObject*>(contactManifold->getBody1());
contactManifold->refreshContactPoints(obA->getWorldTransform(),obB->getWorldTransform()); contactManifold->refreshContactPoints(obA->getWorldTransform(),obB->getWorldTransform());
int numContacts = contactManifold->getNumContacts(); int numContacts = contactManifold->getNumContacts();

View File

@@ -210,7 +210,8 @@ void MyConvex::Render(bool only_wireframe, const btVector3& wire_color) const
const float Scale = 1.0f; const float Scale = 1.0f;
glPushMatrix(); glPushMatrix();
btScalar glmat[16]; //4x4 column major matrix for OpenGL. ATTRIBUTE_ALIGNED16(btScalar) glmat[16]; //4x4 column major matrix for OpenGL.
mTransform.getOpenGLMatrix(glmat); mTransform.getOpenGLMatrix(glmat);
#ifndef BT_USE_DOUBLE_PRECISION #ifndef BT_USE_DOUBLE_PRECISION
glMultMatrixf(&(glmat[0])); glMultMatrixf(&(glmat[0]));

View File

@@ -23,7 +23,7 @@ IF (WIN32)
ADD_EXECUTABLE(AppForkLiftDemo ADD_EXECUTABLE(AppForkLiftDemo
ForkLiftDemo.cpp ForkLiftDemo.cpp
main.cpp main.cpp
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
IF (WIN32) IF (WIN32)

View File

@@ -31,7 +31,7 @@ ADD_EXECUTABLE(AppFractureDemo
btFractureBody.cpp btFractureBody.cpp
btFractureDynamicsWorld.cpp btFractureDynamicsWorld.cpp
btFractureDynamicsWorld.h btFractureDynamicsWorld.h
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ELSE() ELSE()
ADD_EXECUTABLE(AppFractureDemo ADD_EXECUTABLE(AppFractureDemo
@@ -82,7 +82,7 @@ ELSE (USE_GLUT)
Win32FractureDemo.cpp Win32FractureDemo.cpp
FractureDemo.cpp FractureDemo.cpp
FractureDemo.h FractureDemo.h
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )

View File

@@ -25,7 +25,7 @@ void btFractureBody::recomputeConnectivity(btCollisionWorld* world)
MyContactResultCallback() :m_connected(false) MyContactResultCallback() :m_connected(false)
{ {
} }
virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1)
{ {
if (cp.getDistance()<=0) if (cp.getDistance()<=0)
m_connected = true; m_connected = true;

View File

@@ -25,7 +25,7 @@ IF (USE_GLUT)
GenericJointDemo.h GenericJointDemo.h
Ragdoll.cpp Ragdoll.cpp
main.cpp main.cpp
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ELSE() ELSE()
ADD_EXECUTABLE(AppGenericJointDemo ADD_EXECUTABLE(AppGenericJointDemo
@@ -70,7 +70,7 @@ ELSE(USE_GLUT)
GenericJointDemo.cpp GenericJointDemo.cpp
GenericJointDemo.h GenericJointDemo.h
Ragdoll.cpp Ragdoll.cpp
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ENDIF (USE_GLUT) ENDIF (USE_GLUT)

View File

@@ -149,7 +149,10 @@ void LinearConvexCastDemo::displayCallback(void)
convexCaster.calcTimeOfImpact( tr[ 0 ], toA, tr[ 1 ], toB, result ); convexCaster.calcTimeOfImpact( tr[ 0 ], toA, tr[ 1 ], toB, result );
btScalar m1[16], m2[16],m3[16]; ATTRIBUTE_ALIGNED16(btScalar) m1[16];
ATTRIBUTE_ALIGNED16(btScalar) m2[16];
ATTRIBUTE_ALIGNED16(btScalar) m3[16];
tr[ 0 ].getOpenGLMatrix( m1 ); tr[ 0 ].getOpenGLMatrix( m1 );
tr[ 1 ].getOpenGLMatrix( m2 ); tr[ 1 ].getOpenGLMatrix( m2 );

View File

@@ -31,7 +31,10 @@ public:
~btHfFluidBuoyantConvexShape (); ~btHfFluidBuoyantConvexShape ();
void generateShape (btScalar radius, btScalar gap); void generateShape (btScalar radius, btScalar gap);
btConvexShape* getConvexShape () { return m_convexShape; } const btConvexShape* getConvexShape () const
{
return m_convexShape;
}
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
virtual void setMargin(btScalar margin); virtual void setMargin(btScalar margin);

View File

@@ -25,50 +25,50 @@ Experimental Buoyancy fluid demo written by John McCutchan
#include "BulletCollision/CollisionDispatch/btCollisionObject.h" #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletDynamics/Dynamics/btRigidBody.h" #include "BulletDynamics/Dynamics/btRigidBody.h"
#include "btHfFluid.h" #include "btHfFluid.h"
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
btHfFluidBuoyantShapeCollisionAlgorithm::btHfFluidBuoyantShapeCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver) btHfFluidBuoyantShapeCollisionAlgorithm::btHfFluidBuoyantShapeCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
: btCollisionAlgorithm(ci), m_convexConvexAlgorithm(NULL, ci, col0, col1, simplexSolver, pdSolver,0,0) : btCollisionAlgorithm(ci), m_convexConvexAlgorithm(NULL, ci, col0Wrap, col1Wrap, simplexSolver, pdSolver,0,0)
{ {
m_collisionObject0 = col0; m_collisionObject0 = col0Wrap->getCollisionObject();
m_collisionObject1 = col1; m_collisionObject1 = col1Wrap->getCollisionObject();
} }
btHfFluidBuoyantShapeCollisionAlgorithm::~btHfFluidBuoyantShapeCollisionAlgorithm() btHfFluidBuoyantShapeCollisionAlgorithm::~btHfFluidBuoyantShapeCollisionAlgorithm()
{ {
} }
void btHfFluidBuoyantShapeCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) void btHfFluidBuoyantShapeCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{ {
btHfFluidBuoyantConvexShape* tmpShape0 = (btHfFluidBuoyantConvexShape*)body0->getCollisionShape(); const btHfFluidBuoyantConvexShape* tmpShape0 = (const btHfFluidBuoyantConvexShape*)body0Wrap->getCollisionShape();
btHfFluidBuoyantConvexShape* tmpShape1 = (btHfFluidBuoyantConvexShape*)body1->getCollisionShape(); const btHfFluidBuoyantConvexShape* tmpShape1 = (const btHfFluidBuoyantConvexShape*)body1Wrap->getCollisionShape();
btConvexShape* convexShape0 = tmpShape0->getConvexShape(); const btConvexShape* convexShape0 = tmpShape0->getConvexShape();
btConvexShape* convexShape1 = tmpShape1->getConvexShape(); const btConvexShape* convexShape1 = tmpShape1->getConvexShape();
body0->setCollisionShape (convexShape0); //body0->setCollisionShape (convexShape0);
body1->setCollisionShape (convexShape1); //body1->setCollisionShape (convexShape1);
m_convexConvexAlgorithm.processCollision (body0, body1, dispatchInfo,resultOut); btCollisionObjectWrapper ob0(body0Wrap,convexShape0,body0Wrap->getCollisionObject(),body0Wrap->getWorldTransform());
btCollisionObjectWrapper ob1(body1Wrap,convexShape1,body1Wrap->getCollisionObject(),body1Wrap->getWorldTransform());
m_convexConvexAlgorithm.processCollision (&ob0, &ob1, dispatchInfo,resultOut);
body0->setCollisionShape (tmpShape0);
body1->setCollisionShape (tmpShape1);
} }
btScalar btHfFluidBuoyantShapeCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) btScalar btHfFluidBuoyantShapeCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{ {
btAssert(0);
btHfFluidBuoyantConvexShape* tmpShape0 = (btHfFluidBuoyantConvexShape*)body0->getCollisionShape(); btHfFluidBuoyantConvexShape* tmpShape0 = (btHfFluidBuoyantConvexShape*)body0->getCollisionShape();
btHfFluidBuoyantConvexShape* tmpShape1 = (btHfFluidBuoyantConvexShape*)body1->getCollisionShape(); btHfFluidBuoyantConvexShape* tmpShape1 = (btHfFluidBuoyantConvexShape*)body1->getCollisionShape();
btConvexShape* convexShape0 = tmpShape0->getConvexShape(); const btConvexShape* convexShape0 = tmpShape0->getConvexShape();
btConvexShape* convexShape1 = tmpShape1->getConvexShape(); const btConvexShape* convexShape1 = tmpShape1->getConvexShape();
body0->setCollisionShape (convexShape0);
body1->setCollisionShape (convexShape1);
btScalar toi = btScalar(0.0f); btScalar toi = btScalar(0.0f);
toi = m_convexConvexAlgorithm.calculateTimeOfImpact (body0, body1, dispatchInfo, resultOut); toi = m_convexConvexAlgorithm.calculateTimeOfImpact (body0, body1, dispatchInfo, resultOut);
body0->setCollisionShape (tmpShape0);
body1->setCollisionShape (tmpShape1);
return toi; return toi;
} }

View File

@@ -38,17 +38,17 @@ class btSimplexSolverInterface;
/// btHfFluidBuoyantShapeCollisionAlgorithm provides collision detection between btHfFluidBuoyantConvexShape and btHfFluidBuoyantConvexShape /// btHfFluidBuoyantShapeCollisionAlgorithm provides collision detection between btHfFluidBuoyantConvexShape and btHfFluidBuoyantConvexShape
class btHfFluidBuoyantShapeCollisionAlgorithm : public btCollisionAlgorithm class btHfFluidBuoyantShapeCollisionAlgorithm : public btCollisionAlgorithm
{ {
btCollisionObject* m_collisionObject0; const btCollisionObject* m_collisionObject0;
btCollisionObject* m_collisionObject1; const btCollisionObject* m_collisionObject1;
btConvexConvexAlgorithm m_convexConvexAlgorithm; btConvexConvexAlgorithm m_convexConvexAlgorithm;
public: public:
btHfFluidBuoyantShapeCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver); btHfFluidBuoyantShapeCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver);
virtual ~btHfFluidBuoyantShapeCollisionAlgorithm(); virtual ~btHfFluidBuoyantShapeCollisionAlgorithm();
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@@ -70,15 +70,15 @@ public:
} }
virtual ~CreateFunc() {} virtual ~CreateFunc() {}
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{ {
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btHfFluidBuoyantShapeCollisionAlgorithm)); void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btHfFluidBuoyantShapeCollisionAlgorithm));
if (!m_swapped) if (!m_swapped)
{ {
return new(mem) btHfFluidBuoyantShapeCollisionAlgorithm(ci,body0,body1, m_simplexSolver, m_pdSolver); return new(mem) btHfFluidBuoyantShapeCollisionAlgorithm(ci,body0Wrap,body1Wrap, m_simplexSolver, m_pdSolver);
} else } else
{ {
return new(mem) btHfFluidBuoyantShapeCollisionAlgorithm(ci,body0,body1, m_simplexSolver, m_pdSolver); return new(mem) btHfFluidBuoyantShapeCollisionAlgorithm(ci,body0Wrap,body1Wrap, m_simplexSolver, m_pdSolver);
} }
} }
}; };

View File

@@ -25,54 +25,69 @@ Experimental Buoyancy fluid demo written by John McCutchan
#include "BulletCollision/CollisionDispatch/btCollisionObject.h" #include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletDynamics/Dynamics/btRigidBody.h" #include "BulletDynamics/Dynamics/btRigidBody.h"
#include "btHfFluid.h" #include "btHfFluid.h"
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
btHfFluidRigidCollisionAlgorithm::~btHfFluidRigidCollisionAlgorithm() btHfFluidRigidCollisionAlgorithm::~btHfFluidRigidCollisionAlgorithm()
{ {
} }
btHfFluidRigidCollisionAlgorithm::btHfFluidRigidCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped) btHfFluidRigidCollisionAlgorithm::btHfFluidRigidCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap, bool isSwapped)
: btCollisionAlgorithm(ci), m_isSwapped(isSwapped), : btCollisionAlgorithm(ci), m_isSwapped(isSwapped),
m_convexTrianglecallback(ci.m_dispatcher1, col0, col1, !isSwapped) // we flip the isSwapped because we are hf fluid vs. convex and callback expects convex vs. concave m_convexTrianglecallback(ci.m_dispatcher1, col0Wrap, col1Wrap, !isSwapped) // we flip the isSwapped because we are hf fluid vs. convex and callback expects convex vs. concave
{ {
m_manifoldPtr = m_convexTrianglecallback.m_manifoldPtr; m_manifoldPtr = m_convexTrianglecallback.m_manifoldPtr;
if (m_isSwapped) if (m_isSwapped)
{ {
m_hfFluid = static_cast<btHfFluid*>(col1); m_hfFluid = static_cast<const btHfFluid*>(col1Wrap->getCollisionObject());
m_rigidCollisionObject = static_cast<btCollisionObject*>(col0); m_rigidCollisionObject = static_cast<const btCollisionObject*>(col0Wrap->getCollisionObject());
m_manifoldPtr->setBodies(m_hfFluid,m_rigidCollisionObject); m_manifoldPtr->setBodies(m_hfFluid,m_rigidCollisionObject);
} else { } else {
m_hfFluid = static_cast<btHfFluid*>(col0); m_hfFluid = static_cast<const btHfFluid*>(col0Wrap->getCollisionObject());
m_rigidCollisionObject = static_cast<btCollisionObject*>(col1); m_rigidCollisionObject = static_cast<const btCollisionObject*>(col1Wrap->getCollisionObject());
m_manifoldPtr->setBodies(m_rigidCollisionObject,m_hfFluid); m_manifoldPtr->setBodies(m_rigidCollisionObject,m_hfFluid);
} }
} }
void btHfFluidRigidCollisionAlgorithm::processGround (const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) void btHfFluidRigidCollisionAlgorithm::processGround (const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{ {
btAssert(0);
//needs fixing after btCollisionObjectWrapper introduction
#if 0
btScalar triangleMargin = m_rigidCollisionObject->getCollisionShape()->getMargin(); btScalar triangleMargin = m_rigidCollisionObject->getCollisionShape()->getMargin();
resultOut->setPersistentManifold(m_manifoldPtr); resultOut->setPersistentManifold(m_manifoldPtr);
// to perform the convex shape vs. ground terrain: // to perform the convex shape vs. ground terrain:
// we pull the convex shape out of the buoyant shape and replace it temporarily // we pull the convex shape out of the buoyant shape and replace it temporarily
btHfFluidBuoyantConvexShape* tmpShape = (btHfFluidBuoyantConvexShape*)m_rigidCollisionObject->getCollisionShape(); btHfFluidBuoyantConvexShape* tmpShape = (btHfFluidBuoyantConvexShape*)m_rigidCollisionObject->getCollisionShape();
btConvexShape* convexShape = ((btHfFluidBuoyantConvexShape*)tmpShape)->getConvexShape(); const btConvexShape* convexShape = ((const btHfFluidBuoyantConvexShape*)tmpShape)->getConvexShape();
m_rigidCollisionObject->setCollisionShape (convexShape); //m_rigidCollisionObject->setCollisionShape (convexShape);
m_convexTrianglecallback.setTimeStepAndCounters (triangleMargin, dispatchInfo, resultOut); m_convexTrianglecallback.setTimeStepAndCounters (triangleMargin, dispatchInfo, resultOut);
m_hfFluid->foreachGroundTriangle (&m_convexTrianglecallback, m_convexTrianglecallback.getAabbMin(),m_convexTrianglecallback.getAabbMax()); m_hfFluid->foreachGroundTriangle (&m_convexTrianglecallback, m_convexTrianglecallback.getAabbMin(),m_convexTrianglecallback.getAabbMax());
resultOut->refreshContactPoints(); resultOut->refreshContactPoints();
#endif
// restore the buoyant shape // restore the buoyant shape
m_rigidCollisionObject->setCollisionShape (tmpShape); //m_rigidCollisionObject->setCollisionShape (tmpShape);
} }
btScalar btHfFluidRigidCollisionAlgorithm::processFluid (const btDispatcherInfo& dispatchInfo, btScalar density, btScalar floatyness) btScalar btHfFluidRigidCollisionAlgorithm::processFluid (const btDispatcherInfo& dispatchInfo, btScalar density, btScalar floatyness)
{ {
btAssert(0);
//needs fixing after btCollisionObjectWrapper introduction
#if 0
btRigidBody* rb = btRigidBody::upcast(m_rigidCollisionObject); btRigidBody* rb = btRigidBody::upcast(m_rigidCollisionObject);
btHfFluidColumnRigidBodyCallback columnCallback (rb, dispatchInfo.m_debugDraw, density, floatyness); btHfFluidColumnRigidBodyCallback columnCallback (rb, dispatchInfo.m_debugDraw, density, floatyness);
m_hfFluid->foreachFluidColumn (&columnCallback, m_convexTrianglecallback.getAabbMin(), m_convexTrianglecallback.getAabbMax()); m_hfFluid->foreachFluidColumn (&columnCallback, m_convexTrianglecallback.getAabbMin(), m_convexTrianglecallback.getAabbMax());
return columnCallback.getVolume (); return columnCallback.getVolume ();
#endif
return 0.f;
} }
void btHfFluidRigidCollisionAlgorithm::applyFluidFriction (btScalar mu, btScalar submerged_percentage) void btHfFluidRigidCollisionAlgorithm::applyFluidFriction (btScalar mu, btScalar submerged_percentage)
{ {
btAssert(0);
//needs fixing after btCollisionObjectWrapper introduction
#if 0
btRigidBody* rb = btRigidBody::upcast(m_rigidCollisionObject); btRigidBody* rb = btRigidBody::upcast(m_rigidCollisionObject);
btScalar dt = btScalar(1.0f/60.0f); btScalar dt = btScalar(1.0f/60.0f);
@@ -103,10 +118,15 @@ void btHfFluidRigidCollisionAlgorithm::applyFluidFriction (btScalar mu, btScalar
rb->applyCentralImpulse (dt * scaled_mu * -rb->getLinearVelocity()); rb->applyCentralImpulse (dt * scaled_mu * -rb->getLinearVelocity());
rb->applyTorqueImpulse (dt * scaled_mu * -rb->getAngularVelocity()); rb->applyTorqueImpulse (dt * scaled_mu * -rb->getAngularVelocity());
#endif #endif
#endif
} }
void btHfFluidRigidCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) void btHfFluidRigidCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{ {
btAssert(0);
//needs fixing after btCollisionObjectWrapper introduction
#if 0
processGround (dispatchInfo, resultOut); processGround (dispatchInfo, resultOut);
btHfFluidBuoyantConvexShape* buoyantShape = (btHfFluidBuoyantConvexShape*)m_rigidCollisionObject->getCollisionShape(); btHfFluidBuoyantConvexShape* buoyantShape = (btHfFluidBuoyantConvexShape*)m_rigidCollisionObject->getCollisionShape();
btRigidBody* rb = btRigidBody::upcast(m_rigidCollisionObject); btRigidBody* rb = btRigidBody::upcast(m_rigidCollisionObject);
@@ -125,6 +145,8 @@ void btHfFluidRigidCollisionAlgorithm::processCollision (btCollisionObject* body
applyFluidFriction (mu, submerged_percentage); applyFluidFriction (mu, submerged_percentage);
} }
} }
#endif
} }
btScalar btHfFluidRigidCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) btScalar btHfFluidRigidCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)

View File

@@ -35,8 +35,8 @@ class btHfFluidRigidCollisionAlgorithm : public btCollisionAlgorithm
{ {
btPersistentManifold* m_manifoldPtr; btPersistentManifold* m_manifoldPtr;
btHfFluid* m_hfFluid; const btHfFluid* m_hfFluid;
btCollisionObject* m_rigidCollisionObject; const btCollisionObject* m_rigidCollisionObject;
///for rigid versus fluid (instead of fluid versus rigid), we use this swapped boolean ///for rigid versus fluid (instead of fluid versus rigid), we use this swapped boolean
bool m_isSwapped; bool m_isSwapped;
@@ -48,11 +48,11 @@ class btHfFluidRigidCollisionAlgorithm : public btCollisionAlgorithm
btScalar processFluid (const btDispatcherInfo& dispatchInfo, btScalar density, btScalar floatyness); btScalar processFluid (const btDispatcherInfo& dispatchInfo, btScalar density, btScalar floatyness);
public: public:
btHfFluidRigidCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped); btHfFluidRigidCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap, bool isSwapped);
virtual ~btHfFluidRigidCollisionAlgorithm(); virtual ~btHfFluidRigidCollisionAlgorithm();
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@@ -64,15 +64,15 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc struct CreateFunc :public btCollisionAlgorithmCreateFunc
{ {
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1) virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{ {
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btHfFluidRigidCollisionAlgorithm)); void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btHfFluidRigidCollisionAlgorithm));
if (!m_swapped) if (!m_swapped)
{ {
return new(mem) btHfFluidRigidCollisionAlgorithm(ci,body0,body1,false); return new(mem) btHfFluidRigidCollisionAlgorithm(ci,body0Wrap,body1Wrap,false);
} else } else
{ {
return new(mem) btHfFluidRigidCollisionAlgorithm(ci,body0,body1,true); return new(mem) btHfFluidRigidCollisionAlgorithm(ci,body0Wrap,body1Wrap,true);
} }
} }
}; };

View File

@@ -190,7 +190,7 @@ void btHfFluidRigidDynamicsWorld::drawHfFluidBuoyantConvexShape (btIDebugDraw* d
} }
}; };
btConvexShape* convexShape = ((btHfFluidBuoyantConvexShape*)object->getCollisionShape())->getConvexShape(); const btConvexShape* convexShape = ((const btHfFluidBuoyantConvexShape*)object->getCollisionShape())->getConvexShape();
debugDrawObject(object->getWorldTransform(),(btCollisionShape*)convexShape,color); debugDrawObject(object->getWorldTransform(),(btCollisionShape*)convexShape,color);
} }
} }

View File

@@ -162,7 +162,7 @@ void HfFluidDemo_GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape*
if (shape->getShapeType() == HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE) if (shape->getShapeType() == HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE)
{ {
btConvexShape* convexShape = ((btHfFluidBuoyantConvexShape*)shape)->getConvexShape(); const btConvexShape* convexShape = ((btHfFluidBuoyantConvexShape*)shape)->getConvexShape();
btTransform I; btTransform I;
I.setIdentity(); I.setIdentity();
btScalar mat[16]; btScalar mat[16];

View File

@@ -11,7 +11,7 @@ LINK_LIBRARIES(
IF (WIN32) IF (WIN32)
ADD_EXECUTABLE(AppHelloWorld ADD_EXECUTABLE(AppHelloWorld
HelloWorld.cpp HelloWorld.cpp
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ELSE() ELSE()
ADD_EXECUTABLE(AppHelloWorld ADD_EXECUTABLE(AppHelloWorld
@@ -22,8 +22,8 @@ ENDIF()
IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)
SET_TARGET_PROPERTIES(AppHelloWorld PROPERTIES DEBUG_POSTFIX "_Debug") SET_TARGET_PROPERTIES(AppHelloWorld PROPERTIES DEBUG_POSTFIX "_Debug")
SET_TARGET_PROPERTIES(AppHelloWorld PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel") SET_TARGET_PROPERTIES(AppHelloWorld PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel")
SET_TARGET_PROPERTIES(AppHelloWorld PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo") SET_TARGET_PROPERTIES(AppHelloWorld PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo")
ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)

View File

@@ -0,0 +1,22 @@
project "AppHelloWorld"
if _OPTIONS["ios"] then
kind "WindowedApp"
else
kind "ConsoleApp"
end
includedirs {"../../src"}
links {
"BulletDynamics","BulletCollision", "LinearMath"
}
language "C++"
files {
"**.cpp",
"**.h",
}

View File

@@ -73,27 +73,27 @@ inline btScalar calculateCombinedRestitution(float restitution0,float restitutio
/////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////
static bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) static bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1)
{ {
if (enable) if (enable)
{ {
btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1); btAdjustInternalEdgeContacts(cp,colObj1Wrap,colObj0Wrap, partId1,index1);
//btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_BACKFACE_MODE); //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_BACKFACE_MODE);
//btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_DOUBLE_SIDED+BT_TRIANGLE_CONCAVE_DOUBLE_SIDED); //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_DOUBLE_SIDED+BT_TRIANGLE_CONCAVE_DOUBLE_SIDED);
} }
float friction0 = colObj0->getFriction(); float friction0 = colObj0Wrap->getCollisionObject()->getFriction();
float friction1 = colObj1->getFriction(); float friction1 = colObj1Wrap->getCollisionObject()->getFriction();
float restitution0 = colObj0->getRestitution(); float restitution0 = colObj0Wrap->getCollisionObject()->getRestitution();
float restitution1 = colObj1->getRestitution(); float restitution1 = colObj1Wrap->getCollisionObject()->getRestitution();
if (colObj0->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) if (colObj0Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)
{ {
friction0 = 1.0;//partId0,index0 friction0 = 1.0;//partId0,index0
restitution0 = 0.f; restitution0 = 0.f;
} }
if (colObj1->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) if (colObj1Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)
{ {
if (index1&1) if (index1&1)
{ {

View File

@@ -1,29 +1,48 @@
# This is basically the overall name of the project in Visual Studio this is the name of the Solution File # This is basically the overall name of the project in Visual Studio this is the name of the Solution File
# For every executable you have with a main method you should have an add_executable line below. # For every executable you have with a main method you should have an add_executable line below.
# For every add executable line you should list every .cpp and .h file you have associated with that executable. # For every add executable line you should list every .cpp and .h file you have associated with that executable.
# This is the variable for Windows. I use this to define the root of my directory structure. # This is the variable for Windows. I use this to define the root of my directory structure.
SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut) SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut)
# You shouldn't have to modify anything below this line # You shouldn't have to modify anything below this line
######################################################## ########################################################
INCLUDE_DIRECTORIES( INCLUDE_DIRECTORIES(
${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL ${BULLET_PHYSICS_SOURCE_DIR}/src ${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL
) )
LINK_LIBRARIES( LINK_LIBRARIES(
OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} OpenGLSupport BulletDynamics BulletCollision LinearMath ${GLUT_glut_LIBRARY} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}
) )
ADD_EXECUTABLE(AppMovingConcaveDemo
ConcavePhysicsDemo.cpp
) ADD_EXECUTABLE(AppMovingConcaveDemo
ConcavePhysicsDemo.cpp
)
IF (WIN32)
IF (NOT INTERNAL_CREATE_MSVC_RELATIVE_PATH_PROJECTFILES)
IF (CMAKE_CL_64)
ADD_CUSTOM_COMMAND(
TARGET AppMovingConcaveDemo
POST_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR}
)
ELSE(CMAKE_CL_64)
ADD_CUSTOM_COMMAND(
TARGET AppMovingConcaveDemo
POST_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR}
)
ENDIF(CMAKE_CL_64)
ENDIF (NOT INTERNAL_CREATE_MSVC_RELATIVE_PATH_PROJECTFILES)
ENDIF(WIN32)
IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES) IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)
SET_TARGET_PROPERTIES(AppMovingConcaveDemo PROPERTIES DEBUG_POSTFIX "_Debug") SET_TARGET_PROPERTIES(AppMovingConcaveDemo PROPERTIES DEBUG_POSTFIX "_Debug")

View File

@@ -16,6 +16,7 @@ subject to the following restrictions:
#include "btBulletDynamicsCommon.h" #include "btBulletDynamicsCommon.h"
#include "ConcaveDemo.h" #include "ConcaveDemo.h"
#include "LinearMath/btDefaultMotionState.h" #include "LinearMath/btDefaultMotionState.h"
#include "LinearMath/btIDebugDraw.h" #include "LinearMath/btIDebugDraw.h"
#include "LinearMath/btQuickprof.h" #include "LinearMath/btQuickprof.h"
@@ -32,7 +33,7 @@ subject to the following restrictions:
#include "GlutStuff.h" #include "GlutStuff.h"
GLDebugDrawer debugDrawer; GLDebugDrawer debugDrawer1;
//***************************THE FAMOUS BUNNY TRIMESH********************************************// //***************************THE FAMOUS BUNNY TRIMESH********************************************//
@@ -1431,20 +1432,20 @@ inline btScalar calculateCombinedRestitution(float restitution0,float restitutio
bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1)
{ {
float friction0 = colObj0->getFriction(); float friction0 = colObj0Wrap->getCollisionObject()->getFriction();
float friction1 = colObj1->getFriction(); float friction1 = colObj1Wrap->getCollisionObject()->getFriction();
float restitution0 = colObj0->getRestitution(); float restitution0 = colObj0Wrap->getCollisionObject()->getRestitution();
float restitution1 = colObj1->getRestitution(); float restitution1 = colObj1Wrap->getCollisionObject()->getRestitution();
if (colObj0->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) if (colObj0Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)
{ {
friction0 = 1.0;//partId0,index0 friction0 = 1.0;//partId0,index0
restitution0 = 0.f; restitution0 = 0.f;
} }
if (colObj1->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) if (colObj1Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)
{ {
if (index1&1) if (index1&1)
{ {

View File

@@ -24,6 +24,7 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h" #include "BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h"
#include "BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h" #include "BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h"
#include "BulletCollision/CollisionShapes/btMaterial.h" #include "BulletCollision/CollisionShapes/btMaterial.h"
#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
// Create a custom material, just because we can // Create a custom material, just because we can
class CustomMaterial : public btMaterial class CustomMaterial : public btMaterial
@@ -72,30 +73,30 @@ inline btScalar calculateCombinedRestitution(float restitution0,float restitutio
static bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) static bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1)
{ {
// Apply material properties // Apply material properties
if (colObj0->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE) if (colObj0Wrap->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE)
{ {
const btCollisionShape* parent0 = colObj0->getRootCollisionShape(); const btCollisionShape* parent0 = colObj0Wrap->getCollisionObject()->getCollisionShape();
if(parent0 != 0 && parent0->getShapeType() == MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE) if(parent0 != 0 && parent0->getShapeType() == MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE)
{ {
btMultimaterialTriangleMeshShape* shape = (btMultimaterialTriangleMeshShape*)parent0; btMultimaterialTriangleMeshShape* shape = (btMultimaterialTriangleMeshShape*)parent0;
const btMaterial * props = shape->getMaterialProperties(partId0, index0); const btMaterial * props = shape->getMaterialProperties(partId0, index0);
cp.m_combinedFriction = calculateCombinedFriction(props->m_friction, colObj1->getFriction()); cp.m_combinedFriction = calculateCombinedFriction(props->m_friction, colObj1Wrap->getCollisionObject()->getFriction());
cp.m_combinedRestitution = props->m_restitution * colObj1->getRestitution(); cp.m_combinedRestitution = props->m_restitution * colObj1Wrap->getCollisionObject()->getRestitution();
} }
} }
else if (colObj1->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE) else if (colObj1Wrap->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE)
{ {
const btCollisionShape* parent1 = colObj1->getRootCollisionShape(); const btCollisionShape* parent1 = colObj1Wrap->getCollisionObject()->getCollisionShape();
if(parent1 != 0 && parent1->getShapeType() == MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE) if(parent1 != 0 && parent1->getShapeType() == MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE)
{ {
btMultimaterialTriangleMeshShape* shape = (btMultimaterialTriangleMeshShape*)parent1; btMultimaterialTriangleMeshShape* shape = (btMultimaterialTriangleMeshShape*)parent1;
const btMaterial * props = shape->getMaterialProperties(partId1, index1); const btMaterial * props = shape->getMaterialProperties(partId1, index1);
cp.m_combinedFriction = calculateCombinedFriction(props->m_friction, colObj0->getFriction()); cp.m_combinedFriction = calculateCombinedFriction(props->m_friction, colObj0Wrap->getCollisionObject()->getFriction());
cp.m_combinedRestitution = props->m_restitution * colObj0->getRestitution(); cp.m_combinedRestitution = props->m_restitution * colObj0Wrap->getCollisionObject()->getRestitution();
} }
} }

View File

@@ -75,7 +75,7 @@ struct btDebugCastResult : public btConvexCast::CastResult
btVector3 worldBoundsMax(1000,1000,1000); btVector3 worldBoundsMax(1000,1000,1000);
btScalar m[16]; ATTRIBUTE_ALIGNED16(btScalar) m[16];
btTransform hitTrans; btTransform hitTrans;
btTransformUtil::integrateTransform(m_fromTrans,m_linVel,m_angVel,fraction,hitTrans); btTransformUtil::integrateTransform(m_fromTrans,m_linVel,m_angVel,fraction,hitTrans);
hitTrans.getOpenGLMatrix(m); hitTrans.getOpenGLMatrix(m);

View File

@@ -755,7 +755,7 @@ void DemoApplication::mouseFunc(int button, int state, int x, int y)
{ {
btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject); btRigidBody* body = (btRigidBody*)btRigidBody::upcast(rayCallback.m_collisionObject);
if (body) if (body)
{ {
//other exclusions? //other exclusions?

View File

@@ -460,7 +460,7 @@ bool GL_DialogDynamicsWorld::mouseFunc(int button, int state, int x, int y)
btScalar maxPickingClamp = mousePickClamping; btScalar maxPickingClamp = mousePickClamping;
btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject); btRigidBody* body = (btRigidBody*)btRigidBody::upcast(rayCallback.m_collisionObject);
if (body) if (body)
{ {
bool doPick = true; bool doPick = true;

View File

@@ -719,7 +719,7 @@ void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, cons
{ {
btSphereShape sc(multiSphereShape->getSphereRadius(i)); btSphereShape sc(multiSphereShape->getSphereRadius(i));
childTransform.setOrigin(multiSphereShape->getSpherePosition(i)); childTransform.setOrigin(multiSphereShape->getSpherePosition(i));
btScalar childMat[16]; ATTRIBUTE_ALIGNED16(btScalar) childMat[16];
childTransform.getOpenGLMatrix(childMat); childTransform.getOpenGLMatrix(childMat);
drawOpenGL(childMat,&sc,color,debugMode,worldBoundsMin,worldBoundsMax); drawOpenGL(childMat,&sc,color,debugMode,worldBoundsMin,worldBoundsMax);
} }

View File

@@ -19,10 +19,12 @@ subject to the following restrictions:
#include "DemoApplication.h" #include "DemoApplication.h"
class GlutDemoApplication : public DemoApplication ATTRIBUTE_ALIGNED16(class) GlutDemoApplication : public DemoApplication
{ {
public: public:
BT_DECLARE_ALIGNED_ALLOCATOR();
void specialKeyboard(int key, int x, int y); void specialKeyboard(int key, int x, int y);
virtual void swapBuffers(); virtual void swapBuffers();

View File

@@ -20,13 +20,14 @@ subject to the following restrictions:
#include "DemoApplication.h" #include "DemoApplication.h"
class Win32DemoApplication : public DemoApplication ATTRIBUTE_ALIGNED16(class) Win32DemoApplication : public DemoApplication
{ {
protected: protected:
public: public:
BT_DECLARE_ALIGNED_ALLOCATOR();
virtual void swapBuffers(); virtual void swapBuffers();

View File

@@ -48,7 +48,7 @@ IF (USE_GLUT)
../main.cpp ../main.cpp
../SerializeDemo.cpp ../SerializeDemo.cpp
../SerializeDemo.h ../SerializeDemo.h
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.cpp ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.cpp
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.h ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.h
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLInclude.h ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLInclude.h
@@ -109,7 +109,7 @@ ELSE (USE_GLUT)
../Win32SerializeDemo.cpp ../Win32SerializeDemo.cpp
../SerializeDemo.cpp ../SerializeDemo.cpp
../SerializeDemo.h ../SerializeDemo.h
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.cpp ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.cpp
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.h ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLUtils.h
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLInclude.h ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOpenCLInclude.h

View File

@@ -34,7 +34,7 @@ IF (USE_GLUT)
main.cpp main.cpp
SerializeDemo.cpp SerializeDemo.cpp
SerializeDemo.h SerializeDemo.h
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ELSE() ELSE()
ADD_EXECUTABLE(AppSerializeDemo ADD_EXECUTABLE(AppSerializeDemo
@@ -73,7 +73,7 @@ ELSE (USE_GLUT)
Win32SerializeDemo.cpp Win32SerializeDemo.cpp
SerializeDemo.cpp SerializeDemo.cpp
SerializeDemo.h SerializeDemo.h
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ENDIF (USE_GLUT) ENDIF (USE_GLUT)

View File

@@ -24,7 +24,7 @@ IF (USE_GLUT)
ADD_EXECUTABLE(AppSoftBodyDemo ADD_EXECUTABLE(AppSoftBodyDemo
main.cpp main.cpp
SoftDemo.cpp SoftDemo.cpp
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ELSE() ELSE()
ADD_EXECUTABLE(AppSoftBodyDemo ADD_EXECUTABLE(AppSoftBodyDemo

View File

@@ -52,7 +52,7 @@ static btRigidBody* staticBody = 0;
static float waveheight = 5.f; static float waveheight = 5.f;
const float TRIANGLE_SIZE=8.f; const float TRIANGLE_SIZE=8.f;
unsigned int current_demo=7; unsigned int current_demo=20;
#define DEMO_MODE_TIMEOUT 15.f //15 seconds for each demo #define DEMO_MODE_TIMEOUT 15.f //15 seconds for each demo

View File

@@ -26,7 +26,7 @@ BulletMultiThreaded BulletDynamics BulletCollision LinearMath
IF (WIN32) IF (WIN32)
ADD_EXECUTABLE(AppThreadingDemo ADD_EXECUTABLE(AppThreadingDemo
main.cpp main.cpp
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ELSE() ELSE()
ADD_EXECUTABLE(AppThreadingDemo ADD_EXECUTABLE(AppThreadingDemo

View File

@@ -59,7 +59,12 @@ btThreadSupportInterface* createThreadSupport(int numThreads)
struct SampleArgs struct SampleArgs
{ {
SampleArgs()
:m_fakeWork(1)
{
}
btCriticalSection* m_cs; btCriticalSection* m_cs;
float m_fakeWork;
}; };
struct SampleThreadLocalStorage struct SampleThreadLocalStorage
@@ -86,6 +91,9 @@ void SampleThreadFunc(void* userPtr,void* lsMemory)
{ {
printf("thread %d processed number %d\n",localStorage->threadId, count); printf("thread %d processed number %d\n",localStorage->threadId, count);
} }
//do some fake work
for (int i=0;i<1000000;i++)
args->m_fakeWork = 1.21*args->m_fakeWork;
workLeft = count>0; workLeft = count>0;
} }
printf("finished\n"); printf("finished\n");
@@ -110,7 +118,7 @@ void* SamplelsMemoryFunc()
int main(int argc,char** argv) int main(int argc,char** argv)
{ {
int numThreads = 4; int numThreads = 8;
btThreadSupportInterface* threadSupport = createThreadSupport(numThreads); btThreadSupportInterface* threadSupport = createThreadSupport(numThreads);

View File

@@ -22,7 +22,7 @@ LINK_LIBRARIES(
IF (WIN32) IF (WIN32)
ADD_EXECUTABLE(AppUserCollisionAlgorithm ADD_EXECUTABLE(AppUserCollisionAlgorithm
UserCollisionAlgorithm.cpp UserCollisionAlgorithm.cpp
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ELSE() ELSE()
ADD_EXECUTABLE(AppUserCollisionAlgorithm ADD_EXECUTABLE(AppUserCollisionAlgorithm

View File

@@ -27,7 +27,7 @@ ADD_EXECUTABLE(AppVoronoiFractureDemo
main.cpp main.cpp
VoronoiFractureDemo.cpp VoronoiFractureDemo.cpp
VoronoiFractureDemo.h VoronoiFractureDemo.h
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ELSE() ELSE()
ADD_EXECUTABLE(AppVoronoiFractureDemo ADD_EXECUTABLE(AppVoronoiFractureDemo
@@ -74,7 +74,7 @@ ELSE (USE_GLUT)
Win32VoronoiFractureDemo.cpp Win32VoronoiFractureDemo.cpp
VoronoiFractureDemo.cpp VoronoiFractureDemo.cpp
VoronoiFractureDemo.h VoronoiFractureDemo.h
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )

View File

@@ -16,7 +16,7 @@ function createDemos( demos, incdirs, linknames)
links { "opengl32" } links { "opengl32" }
includedirs{ "../Glut" } includedirs{ "../Glut" }
libdirs {"../Glut"} libdirs {"../Glut"}
files { "../msvc/bullet.rc" } files { "../build/bullet.rc" }
configuration {"Windows", "x32"} configuration {"Windows", "x32"}
links {"glew32s","glut32"} links {"glew32s","glut32"}
@@ -65,7 +65,6 @@ end
"GenericJointDemo", "GenericJointDemo",
"GimpactTestDemo", "GimpactTestDemo",
"GjkConvexCastDemo", "GjkConvexCastDemo",
"HelloWorld",
"InternalEdgeDemo", "InternalEdgeDemo",
"MovingConcaveDemo", "MovingConcaveDemo",
"MultiMaterialDemo", "MultiMaterialDemo",

View File

@@ -164,7 +164,7 @@ public:
float cpercent = 5; float cpercent = 5;
float ppercent = 15; float ppercent = 15;
unsigned int maxv = 16; unsigned int maxv = 16;
float skinWidth = 0.0; float skinWidth = 0.0f;
ConvexDecomposition::DecompDesc desc; ConvexDecomposition::DecompDesc desc;

View File

@@ -4,7 +4,7 @@ rem premake4 --no-pedemos vs2008
rem premake4 --no-bulletlibs --no-pelibs vs2008 rem premake4 --no-bulletlibs --no-pelibs vs2008
rem premake4 --with-nacl vs2008 rem premake4 --with-nacl vs2008
..\..\..\msvc\premake4 vs2008 ..\..\..\build\premake4 vs2008
mkdir vs2008\cache mkdir vs2008\cache
pause pause

View File

@@ -1,5 +1,5 @@
..\..\..\msvc\premake4 vs2010 ..\..\..\build\premake4 vs2010
mkdir vs2010\cache mkdir vs2010\cache
pause pause

View File

@@ -267,9 +267,7 @@ void bt3dGridBroadphaseOCL::allocateBuffers()
m_dPairsChanged = clCreateBuffer(m_cxMainContext, CL_MEM_READ_WRITE, memSize, NULL, &ciErrNum); m_dPairsChanged = clCreateBuffer(m_cxMainContext, CL_MEM_READ_WRITE, memSize, NULL, &ciErrNum);
GRID3DOCL_CHECKERROR(ciErrNum, CL_SUCCESS); GRID3DOCL_CHECKERROR(ciErrNum, CL_SUCCESS);
m_dPairsContiguous = clCreateBuffer(m_cxMainContext, CL_MEM_READ_WRITE, memSize, NULL, &ciErrNum);
GRID3DOCL_CHECKERROR(ciErrNum, CL_SUCCESS);
memSize = 3 * 4 * sizeof(float); memSize = 3 * 4 * sizeof(float);
m_dBpParams = clCreateBuffer(m_cxMainContext, CL_MEM_READ_WRITE, memSize, NULL, &ciErrNum); m_dBpParams = clCreateBuffer(m_cxMainContext, CL_MEM_READ_WRITE, memSize, NULL, &ciErrNum);
GRID3DOCL_CHECKERROR(ciErrNum, CL_SUCCESS); GRID3DOCL_CHECKERROR(ciErrNum, CL_SUCCESS);

View File

@@ -92,7 +92,6 @@ public:
protected: protected:
cl_mem m_dPairScanChanged; cl_mem m_dPairScanChanged;
cl_mem m_dPairsChanged; cl_mem m_dPairsChanged;
cl_mem m_dPairsContiguous;
cl_mem m_dBpParams; cl_mem m_dBpParams;
adl::Device* m_deviceHost; adl::Device* m_deviceHost;

View File

@@ -63,8 +63,7 @@ btGridBroadphaseCl::btGridBroadphaseCl( btOverlappingPairCache* overlappingPairC
maxSmallProxySize,maxSmallProxiesPerCell, maxSmallProxySize,maxSmallProxiesPerCell,
context,device,queue,deviceCL) context,device,queue,deviceCL)
{ {
m_computeAabbKernel = m_deviceCL->getKernel(COMPUTE_AABB_KERNEL_PATH,"computeAabb","",spComputeAabbSource);
m_countOverlappingPairs = m_deviceCL->getKernel(COMPUTE_AABB_KERNEL_PATH,"countOverlappingpairs","",spComputeAabbSource); m_countOverlappingPairs = m_deviceCL->getKernel(COMPUTE_AABB_KERNEL_PATH,"countOverlappingpairs","",spComputeAabbSource);
m_squeezePairCaches = m_deviceCL->getKernel(COMPUTE_AABB_KERNEL_PATH,"squeezePairCaches","",spComputeAabbSource); m_squeezePairCaches = m_deviceCL->getKernel(COMPUTE_AABB_KERNEL_PATH,"squeezePairCaches","",spComputeAabbSource);

View File

@@ -35,7 +35,6 @@ class btGridBroadphaseCl : public bt3dGridBroadphaseOCL
{ {
protected: protected:
adl::Kernel* m_computeAabbKernel;
adl::Kernel* m_countOverlappingPairs; adl::Kernel* m_countOverlappingPairs;
adl::Kernel* m_squeezePairCaches; adl::Kernel* m_squeezePairCaches;

View File

@@ -881,8 +881,8 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile
startTransform.deSerializeDouble(colObjData->m_worldTransform); startTransform.deSerializeDouble(colObjData->m_worldTransform);
btCollisionShape* shape = (btCollisionShape*)*shapePtr; btCollisionShape* shape = (btCollisionShape*)*shapePtr;
btCollisionObject* body = createCollisionObject(startTransform,shape,colObjData->m_name); btCollisionObject* body = createCollisionObject(startTransform,shape,colObjData->m_name);
body->setFriction(colObjData->m_friction); body->setFriction(btScalar(colObjData->m_friction));
body->setRestitution(colObjData->m_restitution); body->setRestitution(btScalar(colObjData->m_restitution));
#ifdef USE_INTERNAL_EDGE_UTILITY #ifdef USE_INTERNAL_EDGE_UTILITY
if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)

View File

@@ -8,7 +8,7 @@ LINK_LIBRARIES(
) )
IF (WIN32) IF (WIN32)
SET(ADDITIONAL_SRC SET(ADDITIONAL_SRC
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc ${BULLET_PHYSICS_SOURCE_DIR}/build/bullet.rc
) )
ENDIF() ENDIF()

47
Test/Info.plist Normal file
View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFiles</key>
<array/>
<key>CFBundleIdentifier</key>
<string>Apple.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

28
Test/README.txt Normal file
View File

@@ -0,0 +1,28 @@
1) Add a .cpp and .h file for your test function. The function should conform to:
#ifdef __cplusplus
extern "C" {
#endif
#include "Utils.h"
#include "main.h"
#include "vector.h"
// Your test function
int MyTestFunc(void);
#ifdef __cplusplus
}
#endif
The rest of the program doesn't care or know what you do in MyTestFunc, except that MyTestFunc should return non-zero in case of failure in MyTestFunc. There are some handy functions in Utils.h that you might want to use. Please use vlog instead of printf to print stuff, and random_number32/64() in place of rand(), so I can multithread later if it comes to that. There are some read-only globals that you may wish to respond to, declared in Utils.h:
gReportAverageTimes if you do timing, report times as averages instead of best times if non-zero
gExitOnError if non-zero, return non-zero immediately if you encounter an error
gAppName (const char*) the name of the application
As a convenience, vector.h has some cross platform vector types declared and will correctly include various vector headers according to compiler flag.
2) Add an entry to gTestList in TestList.cpp for your test function, so the rest of the app knows to call it

97
Test/Source/TestList.cpp Normal file
View File

@@ -0,0 +1,97 @@
//
// TestList.c
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#include <stdlib.h>
#include "TestList.h"
#include "Test_qtmul.h"
#include "Test_qtmulQV3.h"
#include "Test_qtmulV3Q.h"
#include "Test_qtdot.h"
#include "Test_qtnorm.h"
#include "Test_v3dot.h"
#include "Test_v3sdiv.h"
#include "Test_v3norm.h"
#include "Test_v3cross.h"
#include "Test_v3triple.h"
#include "Test_v3interp.h"
#include "Test_v3lerp.h"
#include "Test_v3skew.h"
#include "Test_v3div.h"
#include "Test_v3rotate.h"
#include "Test_maxdot.h"
#include "Test_mindot.h"
#include "Test_dot3.h"
#include "Test_3x3transpose.h"
#include "Test_3x3transposeTimes.h"
#include "Test_3x3timesTranspose.h"
#include "Test_3x3mulM.h"
#include "Test_3x3mulM1M2.h"
#include "Test_3x3mulMV.h"
#include "Test_3x3mulVM.h"
#include "Test_3x3setRot.h"
#include "Test_3x3getRot.h"
#include "Test_btDbvt.h"
#include "Test_quat_aos_neon.h"
#include "LinearMath/btScalar.h"
#define ENTRY( _name, _func ) { _name, _func }
//
// Test functions have the form int (*TestFunc)( void )
// They return a non-zero result in case of failure.
//
// Please see handy stuff in Utils.h, vector.h when writing your test code.
//
#if defined (BT_USE_NEON) || defined (BT_USE_SSE_IN_API)
TestDesc gTestList[] =
{
ENTRY( "maxdot", Test_maxdot ),
ENTRY( "mindot", Test_mindot ),
ENTRY( "qtmul", Test_qtmul ),
ENTRY( "qtmulQV3", Test_qtmulQV3 ),
ENTRY( "qtmulV3Q", Test_qtmulV3Q ),
ENTRY( "qtdot", Test_qtdot ),
ENTRY( "qtnorm", Test_qtnorm ),
ENTRY( "v3dot", Test_v3dot ),
ENTRY( "v3sdiv", Test_v3sdiv ),
ENTRY( "v3norm", Test_v3norm ),
ENTRY( "v3cross", Test_v3cross ),
ENTRY( "v3triple", Test_v3triple ),
ENTRY( "v3interp", Test_v3interp ),
ENTRY( "v3lerp", Test_v3lerp ),
ENTRY( "v3skew", Test_v3skew ),
ENTRY( "v3div", Test_v3div ),
ENTRY( "v3rotate", Test_v3rotate ),
ENTRY( "dot3", Test_dot3 ),
ENTRY( "3x3transpose", Test_3x3transpose ),
ENTRY( "3x3transposeTimes", Test_3x3transposeTimes ),
ENTRY( "3x3timesTranspose", Test_3x3timesTranspose ),
ENTRY( "3x3mulM", Test_3x3mulM ),
ENTRY( "3x3mulM1M2", Test_3x3mulM1M2 ),
ENTRY( "3x3mulMV", Test_3x3mulMV ),
ENTRY( "3x3mulVM", Test_3x3mulMV ),
ENTRY( "3x3setRot", Test_3x3setRot ),
ENTRY( "3x3getRot", Test_3x3getRot ),
ENTRY( "btDbvt", Test_btDbvt ),
ENTRY("quat_aos_neon", Test_quat_aos_neon),
{ NULL, NULL }
};
#else
TestDesc gTestList[]={{NULL,NULL}};
#endif

28
Test/Source/TestList.h Normal file
View File

@@ -0,0 +1,28 @@
//
// TestList.h
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#ifndef BulletTest_TestList_h
#define BulletTest_TestList_h
#ifdef __cplusplus
extern "C" {
#endif
typedef struct TestDesc
{
const char *name;
int (*test_func)(void); // return 0 for success, non-zero for failure
}TestDesc;
extern TestDesc gTestList[];
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,158 @@
//
// Test_3x3getRot.cpp
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#include "LinearMath/btScalar.h"
#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
#include "Test_3x3getRot.h"
#include "vector.h"
#include "Utils.h"
#include "main.h"
#include <math.h>
#include <string.h>
#include <LinearMath/btMatrix3x3.h>
#define LOOPCOUNT 1000
#define ARRAY_SIZE 128
static inline btSimdFloat4 rand_f4(void)
{
return btAssign128( RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, BT_NAN ); // w channel NaN
}
static inline btSimdFloat4 qtNAN_f4(void)
{
return btAssign128( BT_NAN, BT_NAN, BT_NAN, BT_NAN );
}
static void M3x3getRot_ref( const btMatrix3x3 &m, btQuaternion &q )
{
btVector3 m_el[3] = { m[0], m[1], m[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));
temp[3]=(s * btScalar(0.5));
s = btScalar(0.5) / 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].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));
temp[i] = s * btScalar(0.5);
s = btScalar(0.5) / 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]);
}
static int operator!= ( const btQuaternion &a, const btQuaternion &b )
{
if( fabs(a.x() - b.x()) +
fabs(a.y() - b.y()) +
fabs(a.z() - b.z()) +
fabs(a.w() - b.w()) > FLT_EPSILON * 4)
return 1;
return 0;
}
int Test_3x3getRot(void)
{
// Init an array flanked by guard pages
btMatrix3x3 in1[ARRAY_SIZE];
btQuaternion out[ARRAY_SIZE];
btQuaternion out2[ARRAY_SIZE];
// Init the data
size_t i, j;
for( i = 0; i < ARRAY_SIZE; i++ )
{
in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() );
out[i] = btQuaternion(qtNAN_f4());
out2[i] = btQuaternion(qtNAN_f4());
M3x3getRot_ref(in1[i], out[i]);
in1[i].getRotation(out2[i]);
if( out[i] != out2[i] )
{
vlog( "Error - M3x3getRot result error! ");
vlog( "failure @ %ld\n", i);
vlog( "\ncorrect = (%10.7f, %10.7f, %10.7f, %10.7f) "
"\ntested = (%10.7f, %10.7f, %10.7f, %10.7f) \n",
out[i].x(), out[i].y(), out[i].z(), out[i].w(),
out2[i].x(), out2[i].y(), out2[i].z(), out2[i].w());
return -1;
}
}
uint64_t scalarTime, vectorTime;
uint64_t startTime, bestTime, currentTime;
bestTime = ~(bestTime&0);//-1ULL;
scalarTime = 0;
for (j = 0; j < LOOPCOUNT; j++)
{
startTime = ReadTicks();
for( i = 0; i < ARRAY_SIZE; i++ )
M3x3getRot_ref(in1[i], out[i]);
currentTime = ReadTicks() - startTime;
scalarTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
scalarTime = bestTime;
else
scalarTime /= LOOPCOUNT;
bestTime = ~(bestTime&0);//-1ULL;
vectorTime = 0;
for (j = 0; j < LOOPCOUNT; j++)
{
startTime = ReadTicks();
for( i = 0; i < ARRAY_SIZE; i++ )
{
in1[i].getRotation(out2[i]);
}
currentTime = ReadTicks() - startTime;
vectorTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
vectorTime = bestTime;
else
vectorTime /= LOOPCOUNT;
vlog( "Timing:\n" );
vlog( "\t scalar\t vector\n" );
vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE );
return 0;
}
#endif//BT_USE_SSE

View File

@@ -0,0 +1,22 @@
//
// Test_3x3getRot.h
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#ifndef BulletTest_Test_3x3getRot_h
#define BulletTest_Test_3x3getRot_h
#ifdef __cplusplus
extern "C" {
#endif
int Test_3x3getRot(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,169 @@
//
// Test_3x3mulM.cpp
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#include "LinearMath/btScalar.h"
#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
#include "Test_3x3mulM.h"
#include "vector.h"
#include "Utils.h"
#include "main.h"
#include <math.h>
#include <string.h>
#include <LinearMath/btMatrix3x3.h>
#define LOOPCOUNT 1000
#define ARRAY_SIZE 128
static inline btSimdFloat4 rand_f4(void)
{
return btAssign128( RANDF_01, RANDF_01, RANDF_01, BT_NAN ); // w channel NaN
}
static btMatrix3x3 M3x3mulM_ref( btMatrix3x3 &in, const btMatrix3x3 &m )
{
btVector3 m_el[3] = { in[0], in[1], in[2] };
in.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 in;
}
static SIMD_FORCE_INLINE bool fuzzyEqualSlow(const btVector3& ref, const btVector3& other)
{
const btScalar epsilon = SIMD_EPSILON;
return ((btFabs(ref.m_floats[3]-other.m_floats[3])<=epsilon) &&
(btFabs(ref.m_floats[2]-other.m_floats[2])<=epsilon) &&
(btFabs(ref.m_floats[1]-other.m_floats[1])<=epsilon) &&
(btFabs(ref.m_floats[0]-other.m_floats[0])<=epsilon));
}
static int operator!= ( const btMatrix3x3 &a, const btMatrix3x3 &b )
{
if( a.getRow(0) != b.getRow(0) )
{
if (!fuzzyEqualSlow(a.getRow(0),b.getRow(0)))
{
return 1;
}
}
if( a.getRow(1) != b.getRow(1) )
{
if( !fuzzyEqualSlow(a.getRow(1),b.getRow(1)) )
return 1;
}
if( a.getRow(2) != b.getRow(2) )
{
if( !fuzzyEqualSlow(a.getRow(2),b.getRow(2)) )
{
return 1;
}
}
return 0;
}
int Test_3x3mulM(void)
{
// Init an array flanked by guard pages
btMatrix3x3 in1[ARRAY_SIZE];
btMatrix3x3 in2[ARRAY_SIZE];
btMatrix3x3 in3[ARRAY_SIZE];
btMatrix3x3 out[ARRAY_SIZE];
btMatrix3x3 out2[ARRAY_SIZE];
// Init the data
size_t i, j;
for( i = 0; i < ARRAY_SIZE; i++ )
{
in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() );
in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() );
in3[i] = in1[i];
out[i] = M3x3mulM_ref(in1[i], in2[i]);
out2[i] = (in3[i] *= in2[i]);
if( out[i] != out2[i] )
{
vlog( "Error - M3x3mulM result error! ");
vlog( "failure @ %ld\n", i);
btVector3 m0, m1, m2;
m0 = out[i].getRow(0);
m1 = out[i].getRow(1);
m2 = out[i].getRow(2);
vlog( "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) "
"\n (%10.4f, %10.4f, %10.4f, %10.4f) "
"\n (%10.4f, %10.4f, %10.4f, %10.4f) \n",
m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3],
m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3],
m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]);
m0 = out2[i].getRow(0);
m1 = out2[i].getRow(1);
m2 = out2[i].getRow(2);
vlog( "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) "
"\n (%10.4f, %10.4f, %10.4f, %10.4f) "
"\n (%10.4f, %10.4f, %10.4f, %10.4f) \n",
m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3],
m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3],
m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]);
return -1;
}
}
uint64_t scalarTime, vectorTime;
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
scalarTime = 0;
for (j = 0; j < LOOPCOUNT; j++)
{
startTime = ReadTicks();
for( i = 0; i < ARRAY_SIZE; i++ )
out[i] = M3x3mulM_ref(in1[i], in2[i]);
currentTime = ReadTicks() - startTime;
scalarTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
scalarTime = bestTime;
else
scalarTime /= LOOPCOUNT;
bestTime = -1LL;
vectorTime = 0;
for (j = 0; j < LOOPCOUNT; j++)
{
startTime = ReadTicks();
for( i = 0; i < ARRAY_SIZE; i++ )
out2[i] = (in3[i] *= in2[i]);
currentTime = ReadTicks() - startTime;
vectorTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
vectorTime = bestTime;
else
vectorTime /= LOOPCOUNT;
vlog( "Timing:\n" );
vlog( "\t scalar\t vector\n" );
vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE );
return 0;
}
#endif //BT_USE_SSE

View File

@@ -0,0 +1,22 @@
//
// Test_3x3mulM.h
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#ifndef BulletTest_Test_3x3mulM_h
#define BulletTest_Test_3x3mulM_h
#ifdef __cplusplus
extern "C" {
#endif
int Test_3x3mulM(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,164 @@
//
// Test_3x3mulM1M2.cpp
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#include "LinearMath/btScalar.h"
#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
#include "Test_3x3mulM1M2.h"
#include "vector.h"
#include "Utils.h"
#include "main.h"
#include <math.h>
#include <string.h>
#include <LinearMath/btMatrix3x3.h>
#define LOOPCOUNT 1000
#define ARRAY_SIZE 128
static inline btSimdFloat4 rand_f4(void)
{
return btAssign128( RANDF_01, RANDF_01, RANDF_01, BT_NAN ); // w channel NaN
}
static btMatrix3x3 M3x3mulM1M2_ref( const btMatrix3x3 &m1, const btMatrix3x3 &m2 )
{
return btMatrix3x3(
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]));
}
static bool fuzzyEqualSlow(const btVector3& ref, const btVector3& other)
{
const btScalar epsilon = SIMD_EPSILON;
return ((btFabs(ref.m_floats[3]-other.m_floats[3])<=epsilon) &&
(btFabs(ref.m_floats[2]-other.m_floats[2])<=epsilon) &&
(btFabs(ref.m_floats[1]-other.m_floats[1])<=epsilon) &&
(btFabs(ref.m_floats[0]-other.m_floats[0])<=epsilon));
}
static int operator!= ( const btMatrix3x3 &a, const btMatrix3x3 &b )
{
if( a.getRow(0) != b.getRow(0) )
{
if (!fuzzyEqualSlow(a.getRow(0),b.getRow(0)))
{
return 1;
}
}
if( a.getRow(1) != b.getRow(1) )
{
if( !fuzzyEqualSlow(a.getRow(1),b.getRow(1)) )
return 1;
}
if( a.getRow(2) != b.getRow(2) )
{
if( !fuzzyEqualSlow(a.getRow(2),b.getRow(2)) )
{
return 1;
}
}
return 0;
}
int Test_3x3mulM1M2(void)
{
// Init an array flanked by guard pages
btMatrix3x3 in1[ARRAY_SIZE];
btMatrix3x3 in2[ARRAY_SIZE];
btMatrix3x3 out[ARRAY_SIZE];
btMatrix3x3 out2[ARRAY_SIZE];
// Init the data
size_t i, j;
for( i = 0; i < ARRAY_SIZE; i++ )
{
in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() );
in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() );
out[i] = M3x3mulM1M2_ref(in1[i], in2[i]);
out2[i] = (in1[i] * in2[i]);
if( out[i] != out2[i] )
{
vlog( "Error - M3x3mulM1M2 result error! ");
vlog( "failure @ %ld\n", i);
btVector3 m0, m1, m2;
m0 = out[i].getRow(0);
m1 = out[i].getRow(1);
m2 = out[i].getRow(2);
vlog( "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) "
"\n (%10.4f, %10.4f, %10.4f, %10.4f) "
"\n (%10.4f, %10.4f, %10.4f, %10.4f) \n",
m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3],
m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3],
m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]);
m0 = out2[i].getRow(0);
m1 = out2[i].getRow(1);
m2 = out2[i].getRow(2);
vlog( "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) "
"\n (%10.4f, %10.4f, %10.4f, %10.4f) "
"\n (%10.4f, %10.4f, %10.4f, %10.4f) \n",
m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3],
m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3],
m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]);
return -1;
}
}
uint64_t scalarTime, vectorTime;
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
scalarTime = 0;
for (j = 0; j < LOOPCOUNT; j++)
{
startTime = ReadTicks();
for( i = 0; i < ARRAY_SIZE; i++ )
out[i] = M3x3mulM1M2_ref(in1[i], in2[i]);
currentTime = ReadTicks() - startTime;
scalarTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
scalarTime = bestTime;
else
scalarTime /= LOOPCOUNT;
bestTime = -1LL;
vectorTime = 0;
for (j = 0; j < LOOPCOUNT; j++)
{
startTime = ReadTicks();
for( i = 0; i < ARRAY_SIZE; i++ )
out2[i] = (in1[i] * in2[i]);
currentTime = ReadTicks() - startTime;
vectorTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
vectorTime = bestTime;
else
vectorTime /= LOOPCOUNT;
vlog( "Timing:\n" );
vlog( "\t scalar\t vector\n" );
vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE );
return 0;
}
#endif //BT_USE_SSE

View File

@@ -0,0 +1,22 @@
//
// Test_3x3mulM1M2.h
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#ifndef BulletTest_Test_3x3mulM1M2_h
#define BulletTest_Test_3x3mulM1M2_h
#ifdef __cplusplus
extern "C" {
#endif
int Test_3x3mulM1M2(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,112 @@
//
// Test_3x3mulMV.cpp
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#include "LinearMath/btScalar.h"
#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
#include "Test_3x3mulMV.h"
#include "vector.h"
#include "Utils.h"
#include "main.h"
#include <math.h>
#include <string.h>
#include <LinearMath/btMatrix3x3.h>
#define LOOPCOUNT 1000
#define ARRAY_SIZE 128
static inline btSimdFloat4 rand_f4(void)
{
return btAssign128(RANDF_01, RANDF_01, RANDF_01, BT_NAN ); // w channel NaN
}
static btVector3 M3x3mulMV_ref( const btMatrix3x3 &m, const btVector3 &v )
{
return btVector3(m[0].dot(v), m[1].dot(v), m[2].dot(v));
}
int Test_3x3mulMV(void)
{
// Init an array flanked by guard pages
btMatrix3x3 in1[ARRAY_SIZE];
btVector3 in2[ARRAY_SIZE];
btVector3 out[ARRAY_SIZE];
btVector3 out2[ARRAY_SIZE];
// Init the data
size_t i, j;
for( i = 0; i < ARRAY_SIZE; i++ )
{
in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() );
in2[i] = btVector3(rand_f4());
out[i] = M3x3mulMV_ref(in1[i], in2[i]);
out2[i] = (in1[i] * in2[i]);
if( fabsf(out[i].m_floats[0] - out2[i].m_floats[0]) +
fabsf(out[i].m_floats[1] - out2[i].m_floats[1]) +
fabsf(out[i].m_floats[2] - out2[i].m_floats[2]) +
fabsf(out[i].m_floats[3] - out2[i].m_floats[3]) > FLT_EPSILON*4 )
{
vlog( "Error - M3x3mulMV result error! ");
vlog( "failure @ %ld\n", i);
vlog( "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) "
"\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) \n",
out[i].m_floats[0], out[i].m_floats[1], out[i].m_floats[2], out[i].m_floats[3],
out2[i].m_floats[0], out2[i].m_floats[1], out2[i].m_floats[2], out2[i].m_floats[3]);
return 1;
}
}
uint64_t scalarTime, vectorTime;
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
scalarTime = 0;
for (j = 0; j < LOOPCOUNT; j++)
{
startTime = ReadTicks();
for( i = 0; i < ARRAY_SIZE; i++ )
out[i] = M3x3mulMV_ref(in1[i], in2[i]);
currentTime = ReadTicks() - startTime;
scalarTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
scalarTime = bestTime;
else
scalarTime /= LOOPCOUNT;
bestTime = -1LL;
vectorTime = 0;
for (j = 0; j < LOOPCOUNT; j++)
{
startTime = ReadTicks();
for( i = 0; i < ARRAY_SIZE; i++ )
out2[i] = (in1[i] * in2[i]);
currentTime = ReadTicks() - startTime;
vectorTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
vectorTime = bestTime;
else
vectorTime /= LOOPCOUNT;
vlog( "Timing:\n" );
vlog( "\t scalar\t vector\n" );
vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE );
return 0;
}
#endif //BT_USE_SSE

View File

@@ -0,0 +1,23 @@
//
// Test_3x3mulMV.h
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#ifndef BulletTest_Test_3x3mulMV_h
#define BulletTest_Test_3x3mulMV_h
#ifdef __cplusplus
extern "C" {
#endif
int Test_3x3mulMV(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,112 @@
//
// Test_3x3mulVM.cpp
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#include "LinearMath/btScalar.h"
#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
#include "Test_3x3mulVM.h"
#include "vector.h"
#include "Utils.h"
#include "main.h"
#include <math.h>
#include <string.h>
#include <LinearMath/btMatrix3x3.h>
#define LOOPCOUNT 1000
#define ARRAY_SIZE 128
static inline btSimdFloat4 rand_f4(void)
{
return btAssign128( RANDF_01, RANDF_01, RANDF_01, BT_NAN ); // w channel NaN
}
static btVector3 M3x3mulVM_ref( const btVector3 &v, const btMatrix3x3 &m)
{
return btVector3(m.tdotx(v), m.tdoty(v), m.tdotz(v));
}
int Test_3x3mulVM(void)
{
// Init an array flanked by guard pages
btVector3 in1[ARRAY_SIZE];
btMatrix3x3 in2[ARRAY_SIZE];
btVector3 out[ARRAY_SIZE];
btVector3 out2[ARRAY_SIZE];
// Init the data
size_t i, j;
for( i = 0; i < ARRAY_SIZE; i++ )
{
in1[i] = btVector3(rand_f4());
in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() );
out[i] = M3x3mulVM_ref(in1[i], in2[i]);
out2[i] = (in1[i] * in2[i]);
if( fabsf(out[i].m_floats[0] - out2[i].m_floats[0]) +
fabsf(out[i].m_floats[1] - out2[i].m_floats[1]) +
fabsf(out[i].m_floats[2] - out2[i].m_floats[2]) +
fabsf(out[i].m_floats[3] - out2[i].m_floats[3]) > FLT_EPSILON*4 )
{
vlog( "Error - M3x3mulVM result error! ");
vlog( "failure @ %ld\n", i);
vlog( "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) "
"\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) \n",
out[i].m_floats[0], out[i].m_floats[1], out[i].m_floats[2], out[i].m_floats[3],
out2[i].m_floats[0], out2[i].m_floats[1], out2[i].m_floats[2], out2[i].m_floats[3]);
return 1;
}
}
uint64_t scalarTime, vectorTime;
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
scalarTime = 0;
for (j = 0; j < LOOPCOUNT; j++)
{
startTime = ReadTicks();
for( i = 0; i < ARRAY_SIZE; i++ )
out[i] = M3x3mulVM_ref(in1[i], in2[i]);
currentTime = ReadTicks() - startTime;
scalarTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
scalarTime = bestTime;
else
scalarTime /= LOOPCOUNT;
bestTime = -1LL;
vectorTime = 0;
for (j = 0; j < LOOPCOUNT; j++)
{
startTime = ReadTicks();
for( i = 0; i < ARRAY_SIZE; i++ )
out2[i] = (in1[i] * in2[i]);
currentTime = ReadTicks() - startTime;
vectorTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
vectorTime = bestTime;
else
vectorTime /= LOOPCOUNT;
vlog( "Timing:\n" );
vlog( "\t scalar\t vector\n" );
vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE );
return 0;
}
#endif //BT_USE_SSE

View File

@@ -0,0 +1,22 @@
//
// Test_3x3mulVM.h
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#ifndef BulletTest_Test_3x3mulVM_h
#define BulletTest_Test_3x3mulVM_h
#ifdef __cplusplus
extern "C" {
#endif
int Test_3x3mulVM(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,171 @@
//
// Test_3x3setRot.cpp
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#include "LinearMath/btScalar.h"
#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
#include "Test_3x3setRot.h"
#include "vector.h"
#include "Utils.h"
#include "main.h"
#include <math.h>
#include <string.h>
#include <LinearMath/btMatrix3x3.h>
#define LOOPCOUNT 1000
#define ARRAY_SIZE 128
static inline btSimdFloat4 rand_f4(void)
{
return btAssign128( RANDF_01, RANDF_01, RANDF_01, BT_NAN ); // w channel NaN
}
static inline btSimdFloat4 qtrand_f4(void)
{
return btAssign128( RANDF_01, RANDF_01, RANDF_01, RANDF_01 );
}
static btMatrix3x3 M3x3setRot_ref( btMatrix3x3 &m, const btQuaternion &q )
{
btScalar d = q.length2();
btScalar s = btScalar(2.0) / d;
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;
m.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));
return m;
}
static int operator!= ( const btMatrix3x3 &a, const btMatrix3x3 &b )
{
int i;
btVector3 av3, bv3;
for(i=0; i<3; i++)
{
av3 = a.getRow(i);
bv3 = b.getRow(i);
if( fabs(av3.m_floats[0] - bv3.m_floats[0]) +
fabs(av3.m_floats[1] - bv3.m_floats[1]) +
fabs(av3.m_floats[2] - bv3.m_floats[2]) > FLT_EPSILON * 4)
return 1;
}
return 0;
}
int Test_3x3setRot(void)
{
// Init an array flanked by guard pages
btMatrix3x3 in1[ARRAY_SIZE];
btQuaternion in2[ARRAY_SIZE];
btMatrix3x3 in3[ARRAY_SIZE];
btMatrix3x3 out[ARRAY_SIZE];
btMatrix3x3 out2[ARRAY_SIZE];
// Init the data
size_t i, j;
for( i = 0; i < ARRAY_SIZE; i++ )
{
in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() );
in2[i] = btQuaternion(qtrand_f4());
in3[i] = in1[i];
out[i] = M3x3setRot_ref(in1[i], in2[i]);
in3[i].setRotation(in2[i]);
out2[i] = in3[i];
if( out[i] != out2[i] )
{
vlog( "Error - M3x3setRot result error! ");
vlog( "failure @ %ld\n", i);
btVector3 m0, m1, m2;
m0 = out[i].getRow(0);
m1 = out[i].getRow(1);
m2 = out[i].getRow(2);
vlog( "\ncorrect = (%10.7f, %10.7f, %10.7f, %10.7f) "
"\n (%10.7f, %10.7f, %10.7f, %10.7f) "
"\n (%10.7f, %10.7f, %10.7f, %10.7f) \n",
m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3],
m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3],
m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]);
m0 = out2[i].getRow(0);
m1 = out2[i].getRow(1);
m2 = out2[i].getRow(2);
vlog( "\ntested = (%10.7f, %10.7f, %10.7f, %10.7f) "
"\n (%10.7f, %10.7f, %10.7f, %10.7f) "
"\n (%10.7f, %10.7f, %10.7f, %10.7f) \n",
m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3],
m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3],
m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]);
return -1;
}
}
uint64_t scalarTime, vectorTime;
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
scalarTime = 0;
for (j = 0; j < LOOPCOUNT; j++)
{
startTime = ReadTicks();
for( i = 0; i < ARRAY_SIZE; i++ )
out[i] = M3x3setRot_ref(in1[i], in2[i]);
currentTime = ReadTicks() - startTime;
scalarTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
scalarTime = bestTime;
else
scalarTime /= LOOPCOUNT;
bestTime = -1LL;
vectorTime = 0;
for (j = 0; j < LOOPCOUNT; j++)
{
startTime = ReadTicks();
for( i = 0; i < ARRAY_SIZE; i++ )
{
in3[i].setRotation(in2[i]);
out2[i] = in3[i];
}
currentTime = ReadTicks() - startTime;
vectorTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
vectorTime = bestTime;
else
vectorTime /= LOOPCOUNT;
vlog( "Timing:\n" );
vlog( "\t scalar\t vector\n" );
vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE );
return 0;
}
#endif //BT_USE_SSE

View File

@@ -0,0 +1,22 @@
//
// Test_3x3setRot.h
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#ifndef BulletTest_Test_3x3setRot_h
#define BulletTest_Test_3x3setRot_h
#ifdef __cplusplus
extern "C" {
#endif
int Test_3x3setRot(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,117 @@
//
// Test_3x3timesTranspose.cpp
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#include "LinearMath/btScalar.h"
#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
#include "Test_3x3timesTranspose.h"
#include "vector.h"
#include "Utils.h"
#include "main.h"
#include <math.h>
#include <string.h>
#include <LinearMath/btMatrix3x3.h>
#define LOOPCOUNT 1000
#define ARRAY_SIZE 128
static inline btSimdFloat4 rand_f4(void)
{
return btAssign128( RANDF, RANDF, RANDF, BT_NAN ); // w channel NaN
}
static btMatrix3x3 timesTranspose( const btMatrix3x3 &in, const btMatrix3x3 &m )
{
btVector3 m_el[3] = { in[0], in[1], in[2] };
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]));
}
static int operator!= ( const btMatrix3x3 &a, const btMatrix3x3 &b )
{
if( a.getRow(0) != b.getRow(0) )
return 1;
if( a.getRow(1) != b.getRow(1) )
return 1;
if( a.getRow(2) != b.getRow(2) )
return 1;
return 0;
}
int Test_3x3timesTranspose(void)
{
// Init an array flanked by guard pages
btMatrix3x3 in1[ARRAY_SIZE];
btMatrix3x3 in2[ARRAY_SIZE];
btMatrix3x3 out[ARRAY_SIZE];
btMatrix3x3 out2[ARRAY_SIZE];
// Init the data
size_t i, j;
for( i = 0; i < ARRAY_SIZE; i++ )
{
in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() );
in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() );
out[i] = timesTranspose(in1[i], in2[i]);
out2[i] = in1[i].timesTranspose(in2[i]);
if( out[i] != out2[i] )
{
printf( "failure @ %ld\n", i);
return -1;
}
}
uint64_t scalarTime, vectorTime;
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
scalarTime = 0;
for (j = 0; j < LOOPCOUNT; j++) {
startTime = ReadTicks();
for( i = 0; i < ARRAY_SIZE; i++ )
out[i] = timesTranspose(in1[i], in2[i]);
currentTime = ReadTicks() - startTime;
scalarTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
scalarTime = bestTime;
else
scalarTime /= LOOPCOUNT;
bestTime = -1LL;
vectorTime = 0;
for (j = 0; j < LOOPCOUNT; j++) {
startTime = ReadTicks();
for( i = 0; i < ARRAY_SIZE; i++ )
out[i] = in1[i].timesTranspose(in2[i]);
currentTime = ReadTicks() - startTime;
vectorTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
vectorTime = bestTime;
else
vectorTime /= LOOPCOUNT;
vlog( "Timing:\n" );
vlog( "\t scalar\t vector\n" );
vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE );
return 0;
}
#endif //BT_USE_SSE

View File

@@ -0,0 +1,22 @@
//
// Test_3x3timesTranspose.h
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#ifndef BulletTest_Test_3x3timesTranspose_h
#define BulletTest_Test_3x3timesTranspose_h
#ifdef __cplusplus
extern "C" {
#endif
int Test_3x3timesTranspose(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,116 @@
//
// Test_3x3transpose.cpp
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#include "LinearMath/btScalar.h"
#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
#include "Test_3x3transpose.h"
#include "vector.h"
#include "Utils.h"
#include "main.h"
#include <math.h>
#include <string.h>
#include <LinearMath/btMatrix3x3.h>
#define LOOPCOUNT 1000
#define ARRAY_SIZE 1024
static inline btSimdFloat4 rand_f4(void)
{
return btAssign128( RANDF, RANDF, RANDF, BT_NAN ); // w channel NaN
}
static btMatrix3x3 Transpose( btMatrix3x3 &in )
{
btVector3 row0 = in.getRow(0);
btVector3 row1 = in.getRow(1);
btVector3 row2 = in.getRow(2);
btVector3 col0 = btAssign128(row0.x(), row1.x(), row2.x(), 0 );
btVector3 col1 = btAssign128(row0.y(), row1.y(), row2.y(), 0 );
btVector3 col2 = btAssign128(row0.z(), row1.z(), row2.z(), 0);
return btMatrix3x3( col0, col1, col2);
}
static int operator!= ( const btMatrix3x3 &a, const btMatrix3x3 &b )
{
if( a.getRow(0) != b.getRow(0) )
return 1;
if( a.getRow(1) != b.getRow(1) )
return 1;
if( a.getRow(2) != b.getRow(2) )
return 1;
return 0;
}
int Test_3x3transpose(void)
{
// Init an array flanked by guard pages
btMatrix3x3 in[ARRAY_SIZE];
btMatrix3x3 out[ARRAY_SIZE];
btMatrix3x3 out2[ARRAY_SIZE];
// Init the data
size_t i, j;
for( i = 0; i < ARRAY_SIZE; i++ )
{
in[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() );
out[i] = Transpose(in[i]);
out2[i] = in[i].transpose();
if( out[i] != out2[i] )
{
printf( "failure @ %ld\n", i);
return -1;
}
}
uint64_t scalarTime, vectorTime;
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
scalarTime = 0;
for (j = 0; j < LOOPCOUNT; j++) {
startTime = ReadTicks();
for( i = 0; i < ARRAY_SIZE; i++ )
out[i] = Transpose(in[i]);
currentTime = ReadTicks() - startTime;
scalarTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
scalarTime = bestTime;
else
scalarTime /= LOOPCOUNT;
bestTime = -1LL;
vectorTime = 0;
for (j = 0; j < LOOPCOUNT; j++) {
startTime = ReadTicks();
for( i = 0; i < ARRAY_SIZE; i++ )
out[i] = in[i].transpose();
currentTime = ReadTicks() - startTime;
vectorTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
vectorTime = bestTime;
else
vectorTime /= LOOPCOUNT;
vlog( "Timing:\n" );
vlog( "\t scalar\t vector\n" );
vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE );
return 0;
}
#endif //BT_USE_SSE

View File

@@ -0,0 +1,22 @@
//
// Test_3x3transpose.h
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#ifndef BulletTest_Test_3x3transpose_h
#define BulletTest_Test_3x3transpose_h
#ifdef __cplusplus
extern "C" {
#endif
int Test_3x3transpose(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,168 @@
//
// Test_3x3transposeTimes.cpp
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#include "LinearMath/btScalar.h"
#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
#include "Test_3x3transposeTimes.h"
#include "vector.h"
#include "Utils.h"
#include "main.h"
#include <math.h>
#include <string.h>
#include <LinearMath/btMatrix3x3.h>
#define LOOPCOUNT 1000
#define ARRAY_SIZE 128
static inline btSimdFloat4 rand_f4(void)
{
return btAssign128( RANDF_01, RANDF_01, RANDF_01, BT_NAN ); // w channel NaN
}
static btMatrix3x3 TransposeTimesReference( const btMatrix3x3 &in, const btMatrix3x3 &m )
{
btVector3 m_el[3] = { in[0], in[1], in[2] };
btSimdFloat4 r0 = btAssign128(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(),
0.0f );
btSimdFloat4 r1 = btAssign128( 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(),
0.0f );
btSimdFloat4 r2 = btAssign128( 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].z(),
0.0f );
return btMatrix3x3( r0, r1, r2 );
}
static int operator!= ( const btMatrix3x3 &a, const btMatrix3x3 &b )
{
if( a.getRow(0) != b.getRow(0) )
return 1;
if( a.getRow(1) != b.getRow(1) )
return 1;
if( a.getRow(2) != b.getRow(2) )
return 1;
return 0;
}
int Test_3x3transposeTimes(void)
{
// Init an array flanked by guard pages
btMatrix3x3 in1[ARRAY_SIZE];
btMatrix3x3 in2[ARRAY_SIZE];
btMatrix3x3 out[ARRAY_SIZE];
btMatrix3x3 out2[ARRAY_SIZE];
float maxRelativeError = 0.f;
// Init the data
size_t i, j;
for( i = 0; i < ARRAY_SIZE; i++ )
{
in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() );
in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() );
out[i] = TransposeTimesReference(in1[i], in2[i]);
out2[i] = in1[i].transposeTimes(in2[i]);
if( out[i] != out2[i] )
{
float relativeError = 0.f;
for (int column=0;column<3;column++)
for (int row=0;row<3;row++)
relativeError = btMax(relativeError,btFabs(out2[i][row][column] - out[i][row][column]) / out[i][row][column]);
if (relativeError>1e-6)
{
vlog( "failure @ %ld\n", i);
btVector3 m0, m1, m2;
m0 = out[i].getRow(0);
m1 = out[i].getRow(1);
m2 = out[i].getRow(2);
vlog( "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) "
"\n (%10.4f, %10.4f, %10.4f, %10.4f) "
"\n (%10.4f, %10.4f, %10.4f, %10.4f) \n",
m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3],
m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3],
m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]);
m0 = out2[i].getRow(0);
m1 = out2[i].getRow(1);
m2 = out2[i].getRow(2);
vlog( "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) "
"\n (%10.4f, %10.4f, %10.4f, %10.4f) "
"\n (%10.4f, %10.4f, %10.4f, %10.4f) \n",
m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3],
m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3],
m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]);
return -1;
} else
{
if (relativeError>maxRelativeError)
maxRelativeError = relativeError;
}
}
}
if (maxRelativeError)
{
printf("Warning: maxRelativeError = %e\n",maxRelativeError);
}
uint64_t scalarTime, vectorTime;
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
scalarTime = 0;
for (j = 0; j < LOOPCOUNT; j++) {
startTime = ReadTicks();
for( i = 0; i < ARRAY_SIZE; i++ )
out[i] = TransposeTimesReference(in1[i], in2[i]);
currentTime = ReadTicks() - startTime;
scalarTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
scalarTime = bestTime;
else
scalarTime /= LOOPCOUNT;
bestTime = -1LL;
vectorTime = 0;
for (j = 0; j < LOOPCOUNT; j++) {
startTime = ReadTicks();
for( i = 0; i < ARRAY_SIZE; i++ )
out[i] = in1[i].transposeTimes(in2[i]);
currentTime = ReadTicks() - startTime;
vectorTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
vectorTime = bestTime;
else
vectorTime /= LOOPCOUNT;
vlog( "Timing:\n" );
vlog( "\t scalar\t vector\n" );
vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE );
return 0;
}
#endif //BT_USE_SSE

View File

@@ -0,0 +1,22 @@
//
// Test_3x3transposeTimes.h
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#ifndef BulletTest_Test_3x3transposeTimes_h
#define BulletTest_Test_3x3transposeTimes_h
#ifdef __cplusplus
extern "C" {
#endif
int Test_3x3transposeTimes(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,495 @@
//
// Test_btDbvt.cpp
// BulletTest
//
// Copyright (c) 2011 Apple Inc., Inc.
//
#include "LinearMath/btScalar.h"
#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
#include "Test_btDbvt.h"
#include "vector.h"
#include "Utils.h"
#include "main.h"
#include <math.h>
#include <string.h>
#include <BulletCollision/BroadphaseCollision/btDbvt.h>
// reference code for testing purposes
SIMD_FORCE_INLINE bool Intersect_ref( btDbvtAabbMm& a, btDbvtAabbMm& b)
{
return( (a.tMins().x()<=b.tMaxs().x())&&
(a.tMaxs().x()>=b.tMins().x())&&
(a.tMins().y()<=b.tMaxs().y())&&
(a.tMaxs().y()>=b.tMins().y())&&
(a.tMins().z()<=b.tMaxs().z())&&
(a.tMaxs().z()>=b.tMins().z()));
}
SIMD_FORCE_INLINE btScalar Proximity_ref( btDbvtAabbMm& a,
btDbvtAabbMm& b)
{
const btVector3 d=(a.tMins()+a.tMaxs())-(b.tMins()+b.tMaxs());
return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z()));
}
SIMD_FORCE_INLINE int Select_ref( btDbvtAabbMm& o,
btDbvtAabbMm& a,
btDbvtAabbMm& b)
{
return(Proximity_ref(o,a)<Proximity_ref(o,b)?0:1);
}
SIMD_FORCE_INLINE void Merge_ref( btDbvtAabbMm& a,
btDbvtAabbMm& b,
btDbvtAabbMm& r)
{
//
//Changing '3' into '4' to compare with the vector code which changes all 4 floats.
//Erwin: don't do this because the 4th component is ignore and not computed on non-vector code (there is no NEON version and scalar is just 3 components)
//
for(int i=0;i<3;++i)
{
if(a.tMins().m_floats[i]<b.tMins().m_floats[i])
r.tMins().m_floats[i] = a.tMins().m_floats[i];
else
r.tMins().m_floats[i] = b.tMins().m_floats[i];
if(a.tMaxs().m_floats[i]>b.tMaxs().m_floats[i])
r.tMaxs().m_floats[i]=a.tMaxs().m_floats[i];
else
r.tMaxs().m_floats[i]=b.tMaxs().m_floats[i];
}
}
/*
[0] float32_t 0.0318338
[1] float32_t 0.0309355
[2] float32_t 0.93264
[3] float32_t 0.88788
[0] float32_t 0.59133
[1] float32_t 0.478779
[2] float32_t 0.833354
[3] float32_t 0.186335
[0] float32_t 0.242578
[1] float32_t 0.0134696
[2] float32_t 0.383139
[3] float32_t 0.414653
[0] float32_t 0.067769
[1] float32_t 0.993127
[2] float32_t 0.484308
[3] float32_t 0.765338
*/
#define LOOPCOUNT 1000
#define NUM_CYCLES 10000
#define DATA_SIZE 1024
int Test_btDbvt(void)
{
btDbvtAabbMm a[DATA_SIZE], b[DATA_SIZE], c[DATA_SIZE];
btDbvtAabbMm a_ref[DATA_SIZE], b_ref[DATA_SIZE], c_ref[DATA_SIZE];
int i;
bool Intersect_Test_Res[DATA_SIZE], Intersect_Ref_Res[DATA_SIZE];
int Select_Test_Res[DATA_SIZE], Select_Ref_Res[DATA_SIZE];
for (i = 0; i < DATA_SIZE; i++)
{
a[i].tMins().m_floats[0] = (float)rand() / (float)RAND_MAX;
a[i].tMins().m_floats[1] = (float)rand() / (float)RAND_MAX;
a[i].tMins().m_floats[2] = (float)rand() / (float)RAND_MAX;
a[i].tMins().m_floats[3] = (float)rand() / (float)RAND_MAX;
a[i].tMaxs().m_floats[0] = (float)rand() / (float)RAND_MAX;
a[i].tMaxs().m_floats[1] = (float)rand() / (float)RAND_MAX;
a[i].tMaxs().m_floats[2] = (float)rand() / (float)RAND_MAX;
a[i].tMaxs().m_floats[3] = (float)rand() / (float)RAND_MAX;
b[i].tMins().m_floats[0] = (float)rand() / (float)RAND_MAX;
b[i].tMins().m_floats[1] = (float)rand() / (float)RAND_MAX;
b[i].tMins().m_floats[2] = (float)rand() / (float)RAND_MAX;
b[i].tMins().m_floats[3] = (float)rand() / (float)RAND_MAX;
b[i].tMaxs().m_floats[0] = (float)rand() / (float)RAND_MAX;
b[i].tMaxs().m_floats[1] = (float)rand() / (float)RAND_MAX;
b[i].tMaxs().m_floats[2] = (float)rand() / (float)RAND_MAX;
b[i].tMaxs().m_floats[3] = (float)rand() / (float)RAND_MAX;
c[i].tMins().m_floats[0] = (float)rand() / (float)RAND_MAX;
c[i].tMins().m_floats[1] = (float)rand() / (float)RAND_MAX;
c[i].tMins().m_floats[2] = (float)rand() / (float)RAND_MAX;
c[i].tMins().m_floats[3] = (float)rand() / (float)RAND_MAX;
c[i].tMaxs().m_floats[0] = (float)rand() / (float)RAND_MAX;
c[i].tMaxs().m_floats[1] = (float)rand() / (float)RAND_MAX;
c[i].tMaxs().m_floats[2] = (float)rand() / (float)RAND_MAX;
c[i].tMaxs().m_floats[3] = (float)rand() / (float)RAND_MAX;
a_ref[i].tMins().m_floats[0] = a[i].tMins().m_floats[0];
a_ref[i].tMins().m_floats[1] = a[i].tMins().m_floats[1];
a_ref[i].tMins().m_floats[2] = a[i].tMins().m_floats[2];
a_ref[i].tMins().m_floats[3] = a[i].tMins().m_floats[3];
a_ref[i].tMaxs().m_floats[0] = a[i].tMaxs().m_floats[0];
a_ref[i].tMaxs().m_floats[1] = a[i].tMaxs().m_floats[1];
a_ref[i].tMaxs().m_floats[2] = a[i].tMaxs().m_floats[2];
a_ref[i].tMaxs().m_floats[3] = a[i].tMaxs().m_floats[3];
b_ref[i].tMins().m_floats[0] = b[i].tMins().m_floats[0];
b_ref[i].tMins().m_floats[1] = b[i].tMins().m_floats[1];
b_ref[i].tMins().m_floats[2] = b[i].tMins().m_floats[2];
b_ref[i].tMins().m_floats[3] = b[i].tMins().m_floats[3];
b_ref[i].tMaxs().m_floats[0] = b[i].tMaxs().m_floats[0];
b_ref[i].tMaxs().m_floats[1] = b[i].tMaxs().m_floats[1];
b_ref[i].tMaxs().m_floats[2] = b[i].tMaxs().m_floats[2];
b_ref[i].tMaxs().m_floats[3] = b[i].tMaxs().m_floats[3];
c_ref[i].tMins().m_floats[0] = c[i].tMins().m_floats[0];
c_ref[i].tMins().m_floats[1] = c[i].tMins().m_floats[1];
c_ref[i].tMins().m_floats[2] = c[i].tMins().m_floats[2];
c_ref[i].tMins().m_floats[3] = c[i].tMins().m_floats[3];
c_ref[i].tMaxs().m_floats[0] = c[i].tMaxs().m_floats[0];
c_ref[i].tMaxs().m_floats[1] = c[i].tMaxs().m_floats[1];
c_ref[i].tMaxs().m_floats[2] = c[i].tMaxs().m_floats[2];
c_ref[i].tMaxs().m_floats[3] = c[i].tMaxs().m_floats[3];
}
#if 1
for (i = 0; i < DATA_SIZE; i++)
{
Intersect_Test_Res[i] = Intersect(a[i], b[i]);
Intersect_Ref_Res[i] = Intersect_ref(a_ref[i], b_ref[i]);
if(Intersect_Test_Res[i] != Intersect_Ref_Res[i])
{
printf("Diff on %d\n", i);
printf("a_mx_f[0] = %.3f, a_mx_f[1] = %.3f, a_mx_f[2] = %.3f, a_mx_f[3] = %.3f\n", a[i].tMaxs().m_floats[0], a[i].tMaxs().m_floats[1], a[i].tMaxs().m_floats[2], a[i].tMaxs().m_floats[3]);
printf("a_mi_f[0] = %.3f, a_mi_f[1] = %.3f, a_mi_f[2] = %.3f, a_mi_f[3] = %.3f\n", a[i].tMins().m_floats[0], a[i].tMins().m_floats[1], a[i].tMins().m_floats[2], a[i].tMins().m_floats[3]);
printf("b_mx_f[0] = %.3f, b_mx_f[1] = %.3f, b_mx_f[2] = %.3f, b_mx_f[3] = %.3f\n", b[i].tMaxs().m_floats[0], b[i].tMaxs().m_floats[1], b[i].tMaxs().m_floats[2], b[i].tMaxs().m_floats[3]);
printf("b_mi_f[0] = %.3f, b_mi_f[1] = %.3f, b_mi_f[2] = %.3f, b_mi_f[3] = %.3f\n", b[i].tMins().m_floats[0], b[i].tMins().m_floats[1], b[i].tMins().m_floats[2], b[i].tMins().m_floats[3]);
printf("a_mx_f_ref[0] = %.3f, a_mx_f_ref[1] = %.3f, a_mx_f_ref[2] = %.3f, a_mx_f_ref[3] = %.3f\n", a_ref[i].tMaxs().m_floats[0], a_ref[i].tMaxs().m_floats[1], a_ref[i].tMaxs().m_floats[2], a_ref[i].tMaxs().m_floats[3]);
printf("a_mi_f_ref[0] = %.3f, a_mi_f_ref[1] = %.3f, a_mi_f_ref[2] = %.3f, a_mi_f_ref[3] = %.3f\n", a_ref[i].tMins().m_floats[0], a_ref[i].tMins().m_floats[1], a_ref[i].tMins().m_floats[2], a_ref[i].tMins().m_floats[3]);
printf("b_mx_f_ref[0] = %.3f, b_mx_f_ref[1] = %.3f, b_mx_f_ref[2] = %.3f, b_mx_f_ref[3] = %.3f\n", b_ref[i].tMaxs().m_floats[0], b_ref[i].tMaxs().m_floats[1], b_ref[i].tMaxs().m_floats[2], b_ref[i].tMaxs().m_floats[3]);
printf("b_mi_f_ref[0] = %.3f, b_mi_f_ref[1] = %.3f, b_mi_f_ref[2] = %.3f, b_mi_f_ref[3] = %.3f\n", b_ref[i].tMins().m_floats[0], b_ref[i].tMins().m_floats[1], b_ref[i].tMins().m_floats[2], b_ref[i].tMins().m_floats[3]);
}
}
#endif
uint64_t scalarTime;
uint64_t vectorTime;
size_t j;
////////////////////////////////////
//
// Time and Test Intersect
//
////////////////////////////////////
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
scalarTime = 0;
for (j = 0; j < NUM_CYCLES; j++)
{
startTime = ReadTicks();
for (i = 0; i < DATA_SIZE; i++)
{
Intersect_Ref_Res[i] = Intersect_ref(a_ref[i], b_ref[i]);
}
currentTime = ReadTicks() - startTime;
scalarTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
scalarTime = bestTime;
else
scalarTime /= NUM_CYCLES;
}
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
vectorTime = 0;
for (j = 0; j < NUM_CYCLES; j++)
{
startTime = ReadTicks();
for (i = 0; i < DATA_SIZE; i++)
{
Intersect_Test_Res[i] = Intersect(a[i], b[i]);
}
currentTime = ReadTicks() - startTime;
vectorTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
vectorTime = bestTime;
else
vectorTime /= NUM_CYCLES;
}
vlog( "Intersect Timing:\n" );
vlog( " \t scalar\t vector\n" );
vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, TicksToCycles( vectorTime ) / LOOPCOUNT );
//printf("scalar = %llu, vector = %llu\n", scalarTime, vectorTime);
for (i = 0; i < DATA_SIZE; i++)
{
if(Intersect_Test_Res[i] != Intersect_Ref_Res[i])
{
printf("Intersect fail at %d\n", i);
return 1;
}
}
////////////////////////////////////
//
// Time and Test Merge
//
////////////////////////////////////
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
scalarTime = 0;
for (j = 0; j < NUM_CYCLES; j++)
{
startTime = ReadTicks();
for (i = 0; i < DATA_SIZE; i++)
{
Merge_ref(a_ref[i], b_ref[i], c_ref[i]);
}
currentTime = ReadTicks() - startTime;
scalarTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
scalarTime = bestTime;
else
scalarTime /= NUM_CYCLES;
}
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
vectorTime = 0;
for (j = 0; j < NUM_CYCLES; j++)
{
startTime = ReadTicks();
for (i = 0; i < DATA_SIZE; i++)
{
Merge(a[i], b[i], c[i]);
}
currentTime = ReadTicks() - startTime;
vectorTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
vectorTime = bestTime;
else
vectorTime /= NUM_CYCLES;
}
vlog( "Merge Timing:\n" );
vlog( " \t scalar\t vector\n" );
vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, TicksToCycles( vectorTime ) / LOOPCOUNT );
//printf("scalar = %llu, vector = %llu\n", scalarTime, vectorTime);
/*
c [0] float32_t 0.00455523
[1] float32_t 0.559712
[2] float32_t 0.0795838
[3] float32_t 0.10182
c_ref
[0] float32_t 0.00455523
[1] float32_t 0.559712
[2] float32_t 0.0795838
[3] float32_t 0.552081
c [0] float32_t 0.829904
[1] float32_t 0.692891
[2] float32_t 0.961654
[3] float32_t 0.666956
c_ref
[0] float32_t 0.829904
[1] float32_t 0.692891
[2] float32_t 0.961654
[3] float32_t 0.522878
*/
for (i = 0; i < DATA_SIZE; i++)
{
//ignore 4th component because it is not computed in all code-paths
if( (fabs(c[i].tMaxs().m_floats[0] - c_ref[i].tMaxs().m_floats[0]) > 0.001) ||
(fabs(c[i].tMaxs().m_floats[1] - c_ref[i].tMaxs().m_floats[1]) > 0.001) ||
(fabs(c[i].tMaxs().m_floats[2] - c_ref[i].tMaxs().m_floats[2]) > 0.001) ||
// (fabs(c[i].tMaxs().m_floats[3] - c_ref[i].tMaxs().m_floats[3]) > 0.001) ||
(fabs(c[i].tMins().m_floats[0] - c_ref[i].tMins().m_floats[0]) > 0.001) ||
(fabs(c[i].tMins().m_floats[1] - c_ref[i].tMins().m_floats[1]) > 0.001) ||
(fabs(c[i].tMins().m_floats[2] - c_ref[i].tMins().m_floats[2]) > 0.001)
//|| (fabs(c[i].tMins().m_floats[3] - c_ref[i].tMins().m_floats[3]) > 0.001)
)
//if((c[i].tMaxs().m_floats[0] != c_ref[i].tMaxs().m_floats[0]) || (c[i].tMaxs().m_floats[1] != c_ref[i].tMaxs().m_floats[1]) || (c[i].tMaxs().m_floats[2] != c_ref[i].tMaxs().m_floats[2]) || (c[i].tMaxs().m_floats[3] != c_ref[i].tMaxs().m_floats[3]) || (c[i].tMins().m_floats[0] != c_ref[i].tMins().m_floats[0]) || (c[i].tMins().m_floats[1] != c_ref[i].tMins().m_floats[1]) || (c[i].tMins().m_floats[2] != c_ref[i].tMins().m_floats[2]) || (c[i].tMins().m_floats[3] != c_ref[i].tMins().m_floats[3]))
{
printf("Merge fail at %d with test = %d, ref = %d\n", i, Select_Test_Res[i], Select_Ref_Res[i]);
printf("a_mx_f[0] = %.3f, a_mx_f[1] = %.3f, a_mx_f[2] = %.3f, a_mx_f[3] = %.3f\n", a[i].tMaxs().m_floats[0], a[i].tMaxs().m_floats[1], a[i].tMaxs().m_floats[2], a[i].tMaxs().m_floats[3]);
printf("a_mi_f[0] = %.3f, a_mi_f[1] = %.3f, a_mi_f[2] = %.3f, a_mi_f[3] = %.3f\n", a[i].tMins().m_floats[0], a[i].tMins().m_floats[1], a[i].tMins().m_floats[2], a[i].tMins().m_floats[3]);
printf("b_mx_f[0] = %.3f, b_mx_f[1] = %.3f, b_mx_f[2] = %.3f, b_mx_f[3] = %.3f\n", b[i].tMaxs().m_floats[0], b[i].tMaxs().m_floats[1], b[i].tMaxs().m_floats[2], b[i].tMaxs().m_floats[3]);
printf("b_mi_f[0] = %.3f, b_mi_f[1] = %.3f, b_mi_f[2] = %.3f, b_mi_f[3] = %.3f\n", b[i].tMins().m_floats[0], b[i].tMins().m_floats[1], b[i].tMins().m_floats[2], b[i].tMins().m_floats[3]);
printf("c_mx_f[0] = %.3f, c_mx_f[1] = %.3f, c_mx_f[2] = %.3f, c_mx_f[3] = %.3f\n", c[i].tMaxs().m_floats[0], c[i].tMaxs().m_floats[1], c[i].tMaxs().m_floats[2], c[i].tMaxs().m_floats[3]);
printf("c_mi_f[0] = %.3f, c_mi_f[1] = %.3f, c_mi_f[2] = %.3f, c_mi_f[3] = %.3f\n", c[i].tMins().m_floats[0], c[i].tMins().m_floats[1], c[i].tMins().m_floats[2], c[i].tMins().m_floats[3]);
printf("a_mx_f_ref[0] = %.3f, a_mx_f_ref[1] = %.3f, a_mx_f_ref[2] = %.3f, a_mx_f_ref[3] = %.3f\n", a_ref[i].tMaxs().m_floats[0], a_ref[i].tMaxs().m_floats[1], a_ref[i].tMaxs().m_floats[2], a_ref[i].tMaxs().m_floats[3]);
printf("a_mi_f_ref[0] = %.3f, a_mi_f_ref[1] = %.3f, a_mi_f_ref[2] = %.3f, a_mi_f_ref[3] = %.3f\n", a_ref[i].tMins().m_floats[0], a_ref[i].tMins().m_floats[1], a_ref[i].tMins().m_floats[2], a_ref[i].tMins().m_floats[3]);
printf("b_mx_f_ref[0] = %.3f, b_mx_f_ref[1] = %.3f, b_mx_f_ref[2] = %.3f, b_mx_f_ref[3] = %.3f\n", b_ref[i].tMaxs().m_floats[0], b_ref[i].tMaxs().m_floats[1], b_ref[i].tMaxs().m_floats[2], b_ref[i].tMaxs().m_floats[3]);
printf("b_mi_f_ref[0] = %.3f, b_mi_f_ref[1] = %.3f, b_mi_f_ref[2] = %.3f, b_mi_f_ref[3] = %.3f\n", b_ref[i].tMins().m_floats[0], b_ref[i].tMins().m_floats[1], b_ref[i].tMins().m_floats[2], b_ref[i].tMins().m_floats[3]);
printf("c_mx_f_ref[0] = %.3f, c_mx_f_ref[1] = %.3f, c_mx_f_ref[2] = %.3f, c_mx_f_ref[3] = %.3f\n", c_ref[i].tMaxs().m_floats[0], c_ref[i].tMaxs().m_floats[1], c_ref[i].tMaxs().m_floats[2], c_ref[i].tMaxs().m_floats[3]);
printf("c_mi_f_ref[0] = %.3f, c_mi_f_ref[1] = %.3f, c_mi_f_ref[2] = %.3f, c_mi_f_ref[3] = %.3f\n", c_ref[i].tMins().m_floats[0], c_ref[i].tMins().m_floats[1], c_ref[i].tMins().m_floats[2], c_ref[i].tMins().m_floats[3]);
return 1;
}
}
////////////////////////////////////
//
// Time and Test Select
//
////////////////////////////////////
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
scalarTime = 0;
for (j = 0; j < NUM_CYCLES; j++)
{
startTime = ReadTicks();
for (i = 0; i < DATA_SIZE; i++)
{
Select_Ref_Res[i] = Select_ref(a_ref[i], b_ref[i], c_ref[i]);
}
currentTime = ReadTicks() - startTime;
scalarTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
scalarTime = bestTime;
else
scalarTime /= NUM_CYCLES;
}
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
vectorTime = 0;
for (j = 0; j < NUM_CYCLES; j++)
{
startTime = ReadTicks();
for (i = 0; i < DATA_SIZE; i++)
{
Select_Test_Res[i] = Select(a[i], b[i], c[i]);
}
currentTime = ReadTicks() - startTime;
vectorTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
vectorTime = bestTime;
else
vectorTime /= NUM_CYCLES;
}
vlog( "Select Timing:\n" );
vlog( " \t scalar\t vector\n" );
vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, TicksToCycles( vectorTime ) / LOOPCOUNT );
//printf("scalar = %llu, vector = %llu\n", scalarTime, vectorTime);
for (i = 0; i < DATA_SIZE; i++)
{
Select_Ref_Res[i] = Select_ref(a_ref[i], b_ref[i], c_ref[i]);
Select_Test_Res[i] = Select(a[i], b[i], c[i]);
if(Select_Test_Res[i] != Select_Ref_Res[i])
{
printf("Select fail at %d with test = %d, ref = %d\n", i, Select_Test_Res[i], Select_Ref_Res[i]);
printf("a_mx_f[0] = %.3f, a_mx_f[1] = %.3f, a_mx_f[2] = %.3f, a_mx_f[3] = %.3f\n", a[i].tMaxs().m_floats[0], a[i].tMaxs().m_floats[1], a[i].tMaxs().m_floats[2], a[i].tMaxs().m_floats[3]);
printf("a_mi_f[0] = %.3f, a_mi_f[1] = %.3f, a_mi_f[2] = %.3f, a_mi_f[3] = %.3f\n", a[i].tMins().m_floats[0], a[i].tMins().m_floats[1], a[i].tMins().m_floats[2], a[i].tMins().m_floats[3]);
printf("b_mx_f[0] = %.3f, b_mx_f[1] = %.3f, b_mx_f[2] = %.3f, b_mx_f[3] = %.3f\n", b[i].tMaxs().m_floats[0], b[i].tMaxs().m_floats[1], b[i].tMaxs().m_floats[2], b[i].tMaxs().m_floats[3]);
printf("b_mi_f[0] = %.3f, b_mi_f[1] = %.3f, b_mi_f[2] = %.3f, b_mi_f[3] = %.3f\n", b[i].tMins().m_floats[0], b[i].tMins().m_floats[1], b[i].tMins().m_floats[2], b[i].tMins().m_floats[3]);
printf("c_mx_f[0] = %.3f, c_mx_f[1] = %.3f, c_mx_f[2] = %.3f, c_mx_f[3] = %.3f\n", c[i].tMaxs().m_floats[0], c[i].tMaxs().m_floats[1], c[i].tMaxs().m_floats[2], c[i].tMaxs().m_floats[3]);
printf("c_mi_f[0] = %.3f, c_mi_f[1] = %.3f, c_mi_f[2] = %.3f, c_mi_f[3] = %.3f\n", c[i].tMins().m_floats[0], c[i].tMins().m_floats[1], c[i].tMins().m_floats[2], c[i].tMins().m_floats[3]);
printf("a_mx_f_ref[0] = %.3f, a_mx_f_ref[1] = %.3f, a_mx_f_ref[2] = %.3f, a_mx_f_ref[3] = %.3f\n", a_ref[i].tMaxs().m_floats[0], a_ref[i].tMaxs().m_floats[1], a_ref[i].tMaxs().m_floats[2], a_ref[i].tMaxs().m_floats[3]);
printf("a_mi_f_ref[0] = %.3f, a_mi_f_ref[1] = %.3f, a_mi_f_ref[2] = %.3f, a_mi_f_ref[3] = %.3f\n", a_ref[i].tMins().m_floats[0], a_ref[i].tMins().m_floats[1], a_ref[i].tMins().m_floats[2], a_ref[i].tMins().m_floats[3]);
printf("b_mx_f_ref[0] = %.3f, b_mx_f_ref[1] = %.3f, b_mx_f_ref[2] = %.3f, b_mx_f_ref[3] = %.3f\n", b_ref[i].tMaxs().m_floats[0], b_ref[i].tMaxs().m_floats[1], b_ref[i].tMaxs().m_floats[2], b_ref[i].tMaxs().m_floats[3]);
printf("b_mi_f_ref[0] = %.3f, b_mi_f_ref[1] = %.3f, b_mi_f_ref[2] = %.3f, b_mi_f_ref[3] = %.3f\n", b_ref[i].tMins().m_floats[0], b_ref[i].tMins().m_floats[1], b_ref[i].tMins().m_floats[2], b_ref[i].tMins().m_floats[3]);
printf("c_mx_f_ref[0] = %.3f, c_mx_f_ref[1] = %.3f, c_mx_f_ref[2] = %.3f, c_mx_f_ref[3] = %.3f\n", c_ref[i].tMaxs().m_floats[0], c_ref[i].tMaxs().m_floats[1], c_ref[i].tMaxs().m_floats[2], c_ref[i].tMaxs().m_floats[3]);
printf("c_mi_f_ref[0] = %.3f, c_mi_f_ref[1] = %.3f, c_mi_f_ref[2] = %.3f, c_mi_f_ref[3] = %.3f\n", c_ref[i].tMins().m_floats[0], c_ref[i].tMins().m_floats[1], c_ref[i].tMins().m_floats[2], c_ref[i].tMins().m_floats[3]);
return 1;
}
}
return 0;
}
#endif

View File

@@ -0,0 +1,21 @@
//
// Test_btDbvt.h
// BulletTest
//
// Copyright (c) 2011 Apple Inc., Inc.
//
#ifndef BulletTest_Test_btDbvt_h
#define BulletTest_Test_btDbvt_h
#ifdef __cplusplus
extern "C" {
#endif
int Test_btDbvt(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,153 @@
//
// Test_v3dot.cpp
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#include "LinearMath/btScalar.h"
#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
#include "Test_dot3.h"
#include "vector.h"
#include "Utils.h"
#include "main.h"
#include <math.h>
#include <string.h>
#include <LinearMath/btVector3.h>
// reference code for testing purposes
static btVector3 dot3_ref( const btVector3 &, const btVector3 &, const btVector3 &, const btVector3 &);
static btVector3 dot3_ref( const btVector3 &v, const btVector3 &v1, const btVector3 &v2, const btVector3 &v3)
{
return btVector3( v.dot(v1), v.dot(v2), v.dot(v3));
}
/*
SIMD_FORCE_INLINE int operator!=(const btVector3 &s, const btVector3 &v)
{
#ifdef __SSE__
__m128 test = _mm_cmpneq_ps( s.mVec128, v.mVec128 );
return (_mm_movemask_ps( test ) & 7) != 0;
#elif defined __ARM_NEON_H
uint32x4_t test = vandq_u32( vceqq_f32( s.mVec128, v.mVec128 ), (uint32x4_t){-1,-1,-1,0});
uint32x2_t t = vpadd_u32( vget_low_u32(test), vget_high_u32(test));
t = vpadd_u32(t, t);
return -3 != (int32_t) vget_lane_u32(t, 0);
#else
return s.m_floats[0] != v.m_floats[0] ||
s.m_floats[1] != v.m_floats[1] ||
s.m_floats[2] != v.m_floats[2];
#endif
}
*/
#define LOOPCOUNT 1000
#define NUM_CYCLES 10000
int Test_dot3(void)
{
btVector3 v, v1, v2, v3;
#define DATA_SIZE 1024
btVector3 vec3_arr[DATA_SIZE];
btVector3 vec3_arr1[DATA_SIZE];
btVector3 vec3_arr2[DATA_SIZE];
btVector3 vec3_arr3[DATA_SIZE];
btVector3 res_arr[DATA_SIZE];
uint64_t scalarTime;
uint64_t vectorTime;
size_t j, k;
btVector3 correct, test;
for( k = 0; k < DATA_SIZE; k++ )
{
vec3_arr[k] = btVector3( btAssign128( RANDF, RANDF, RANDF, BT_NAN));
vec3_arr1[k] = btVector3( btAssign128( RANDF, RANDF, RANDF, BT_NAN));
vec3_arr2[k] = btVector3( btAssign128( RANDF, RANDF, RANDF, BT_NAN ));
vec3_arr3[k] = btVector3( btAssign128( RANDF, RANDF, RANDF, BT_NAN));
correct = dot3_ref(vec3_arr[k], vec3_arr1[k], vec3_arr2[k], vec3_arr3[k]);
test = vec3_arr[k].dot3( vec3_arr1[k], vec3_arr2[k], vec3_arr3[k]);
if( correct != test )
{
vlog( "Error (%ld) - dot3 result error! *{%a, %a, %a, %a} != {%a, %a, %a, %a} \n", k,
correct.x(), correct.y(), correct.z(), correct.w(),
test.x(), test.y(), test.z(), test.w() );
return 1;
}
}
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
scalarTime = 0;
for (j = 0; j < NUM_CYCLES; j++)
{
startTime = ReadTicks();
for( k = 0; k+4 <= LOOPCOUNT; k+=4 )
{
size_t k32 = (k & (DATA_SIZE-1));
res_arr[k32] = dot3_ref( vec3_arr[k32], vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); k32++;
res_arr[k32] = dot3_ref( vec3_arr[k32], vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); k32++;
res_arr[k32] = dot3_ref( vec3_arr[k32], vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); k32++;
res_arr[k32] = dot3_ref( vec3_arr[k32], vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]);
}
currentTime = ReadTicks() - startTime;
scalarTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
scalarTime = bestTime;
else
scalarTime /= NUM_CYCLES;
}
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
vectorTime = 0;
for (j = 0; j < NUM_CYCLES; j++)
{
startTime = ReadTicks();
for( k = 0; k+4 <= LOOPCOUNT; k+=4 )
{
size_t k32 = (k & (DATA_SIZE-1));
res_arr[k32] = vec3_arr[k32].dot3( vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); k32++;
res_arr[k32] = vec3_arr[k32].dot3( vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); k32++;
res_arr[k32] = vec3_arr[k32].dot3( vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); k32++;
res_arr[k32] = vec3_arr[k32].dot3( vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]);
}
currentTime = ReadTicks() - startTime;
vectorTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
vectorTime = bestTime;
else
vectorTime /= NUM_CYCLES;
}
vlog( "Timing:\n" );
vlog( " \t scalar\t vector\n" );
vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, TicksToCycles( vectorTime ) / LOOPCOUNT );
return 0;
}
#endif //BT_USE_SSE

View File

@@ -0,0 +1,22 @@
//
// Test_mindot.h
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#ifndef BulletTest_Test_dot3_h
#define BulletTest_Test_dot3_h
#ifdef __cplusplus
extern "C" {
#endif
int Test_dot3(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,281 @@
//
// Test_maxdot.cpp
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#include "LinearMath/btScalar.h"
#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
#include "Test_maxdot.h"
#include "vector.h"
#include "Utils.h"
#include "main.h"
#include <math.h>
#include <string.h>
#include <LinearMath/btVector3.h>
// reference code for testing purposes
static long maxdot_ref( const btSimdFloat4 *vertices,
float *vec,
size_t count,
float *dotResult );
#ifdef __arm__
#define MAX_LOG2_SIZE 9
#else
#define MAX_LOG2_SIZE 10
#endif
#define MAX_SIZE (1U << MAX_LOG2_SIZE)
#define LOOPCOUNT 10
int Test_maxdot(void)
{
// Init an array flanked by guard pages
btSimdFloat4 *data = (btSimdFloat4*) GuardCalloc( 1, MAX_SIZE * sizeof(btSimdFloat4), NULL );
float *fp = (float*) data;
long correct, test;
btVector3 localScaling( 0.1f, 0.2f, 0.3f);
size_t size;
// Init the data
size_t i;
for( i = 0; i < MAX_SIZE; i++ )
{
fp[4*i] = (int32_t) RANDF_16;
fp[4*i+1] = (int32_t) RANDF_16;
fp[4*i+2] = (int32_t) RANDF_16;
fp[4*i+3] = BT_NAN; // w channel NaN
}
float correctDot, testDot;
fp = (float*) localScaling;
float maxRelativeError = 0.f;
for( size = 1; size <= MAX_SIZE; size++ )
{
float *in = (float*)(data + MAX_SIZE - size);
size_t position;
for( position = 0; position < size; position++ )
{
float *biggest = in + position * 4;
float old[4] = { biggest[0], biggest[1], biggest[2], biggest[3] };
biggest[0] += LARGE_FLOAT17;
biggest[1] += LARGE_FLOAT17;
biggest[2] += LARGE_FLOAT17;
biggest[3] += LARGE_FLOAT17;
correctDot = BT_NAN;
testDot = BT_NAN;
correct = maxdot_ref( (btSimdFloat4*) in, (float*) &localScaling, size, &correctDot);
test = localScaling.maxDot( (btVector3*) in, size, testDot);
if( test < 0 || test >= size )
{
vlog( "Error @ %ld: index out of bounds! *%ld vs %ld \n", size, correct, test);
continue;
}
if( correct != test )
{
vlog( "Error @ %ld: index misreported! *%ld vs %ld (*%f, %f)\n", size, correct, test,
fp[0] * in[4*correct] + fp[1] * in[4*correct+1] + fp[2] * in[4*correct+2],
fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2] );
return 1;
}
if( test != position )
{
vlog( "Biggest not found where it is supposed to be: *%ld vs %ld (*%f, %f)\n", position, test,
fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2],
fp[0] * in[4*position] + fp[1] * in[4*position+1] + fp[2] * in[4*position+2] );
return 1;
}
if( correctDot != testDot )
{
float relativeError = btFabs((testDot - correctDot) / correctDot);
if (relativeError>1e-6)
{
vlog( "Error @ %ld: dotpr misreported! *%f vs %f (*%f, %f)\n", size, correctDot, testDot,
fp[0] * in[4*correct] + fp[1] * in[4*correct+1] + fp[2] * in[4*correct+2],
fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2] );
return 1;
} else
{
if (maxRelativeError < relativeError)
{
maxRelativeError = relativeError;
#ifdef VERBOSE_WARNING
sprintf(errStr,"Warning @ %ld: dotpr misreported! *%f vs %f (*%f, %f)\n", size, correctDot, testDot,
fp[0] * in[4*correct] + fp[1] * in[4*correct+1] + fp[2] * in[4*correct+2],
fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2]);
#endif //VERBOSE_WARNING
}
}
}
memcpy( biggest, old, 16 );
}
}
if (maxRelativeError)
{
printf("Warning: relative error = %e\n", maxRelativeError);
#ifdef VERBOSE_WARNING
vlog(errStr);
#endif
}
uint64_t scalarTimes[33 + (MAX_LOG2_SIZE-5)];
uint64_t vectorTimes[33 + (MAX_LOG2_SIZE-5)];
size_t j, k;
float *in = (float*) data;
for( size = 1; size <= 32; size++ )
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
scalarTimes[size] = 0;
for (j = 0; j < 100; j++) {
startTime = ReadTicks();
for( k = 0; k < LOOPCOUNT; k++ )
correct += maxdot_ref( (btSimdFloat4*) in, (float*) &localScaling, size, &correctDot);
currentTime = ReadTicks() - startTime;
scalarTimes[size] += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
scalarTimes[size] = bestTime;
else
scalarTimes[size] /= 100;
}
uint64_t *timep = &scalarTimes[33];
for( size = 64; size <= MAX_SIZE; size *= 2 )
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
timep[0] =0;
for (j = 0; j < 100; j++) {
startTime = ReadTicks();
for( k = 0; k < LOOPCOUNT; k++ )
correct += maxdot_ref( (btSimdFloat4*) in, (float*) &localScaling, size, &correctDot);
currentTime = ReadTicks() - startTime;
timep[0] += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
timep[0] = bestTime;
else
timep[0] /= 100;
timep++;
}
for( size = 1; size <= 32; size++ )
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
vectorTimes[size] = 0;
for (j = 0; j < 100; j++) {
startTime = ReadTicks();
for( k = 0; k < LOOPCOUNT; k++ )
test += localScaling.maxDot( (btVector3*) in, size, testDot);
currentTime = ReadTicks() - startTime;
vectorTimes[size] += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
vectorTimes[size] = bestTime;
else
vectorTimes[size] /= 100;
}
timep = &vectorTimes[33];
for( size = 64; size <= MAX_SIZE; size *= 2 )
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
timep[0] =0;
for (j = 0; j < 100; j++) {
startTime = ReadTicks();
for( k = 0; k < LOOPCOUNT; k++ )
test += localScaling.maxDot( (btVector3*) in, size, testDot);
currentTime = ReadTicks() - startTime;
timep[0] += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
timep[0] = bestTime;
else
timep[0] /= 100;
timep++;
}
vlog( "Timing:\n" );
vlog( " size\t scalar\t vector\n" );
for( size = 1; size <= 32; size++ )
vlog( "%5lu\t%10.2f\t%10.2f\n", size, TicksToCycles( scalarTimes[size] ) / LOOPCOUNT, TicksToCycles( vectorTimes[size] ) / LOOPCOUNT );
size_t index = 33;
for( size = 64; size <= MAX_SIZE; size *= 2 )
{
vlog( "%5lu\t%10.2f\t%10.2f\n", size, TicksToCycles( scalarTimes[index] ) / LOOPCOUNT, TicksToCycles( vectorTimes[index] ) / LOOPCOUNT );
index++;
}
// Useless check to make sure that the timing loops are not optimized away
if( test != correct )
vlog( "Error: Test != correct: *%ld vs. %ld\n", correct, test);
GuardFree(data);
return 0;
}
static long maxdot_ref( const btSimdFloat4 *vertices,
float *vec,
size_t count,
float *dotResult )
{
const float *dp = (const float*) vertices;
float maxDot = -BT_INFINITY;
long i = 0;
long ptIndex = -1;
for( i = 0; i < count; i++ )
{
float dot = vec[0] * dp[0] + vec[1] * dp[1] + vec[2] * dp[2]; dp += 4;
if( dot > maxDot )
{
maxDot = dot;
ptIndex = i;
}
}
*dotResult = maxDot;
return ptIndex;
}
#endif //BT_USE_SSE

View File

@@ -0,0 +1,22 @@
//
// Test_maxdot.h
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#ifndef BulletTest_Test_maxdot_h
#define BulletTest_Test_maxdot_h
#ifdef __cplusplus
extern "C" {
#endif
int Test_maxdot(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,269 @@
//
// Test_mindot.cpp
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#include "LinearMath/btScalar.h"
#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
#include "Test_mindot.h"
#include "vector.h"
#include "Utils.h"
#include "main.h"
#include <math.h>
#include <string.h>
#include <LinearMath/btVector3.h>
// reference code for testing purposes
static long mindot_ref( const btSimdFloat4 *vertices,
float *vec,
size_t count,
float *dotResult );
#ifdef __arm__
#define MAX_LOG2_SIZE 9
#else
#define MAX_LOG2_SIZE 9
#endif
#define MAX_SIZE (1U << MAX_LOG2_SIZE)
#define LOOPCOUNT 100
int Test_mindot(void)
{
// Init an array flanked by guard pages
btSimdFloat4 *data = (btSimdFloat4*) GuardCalloc( 1, MAX_SIZE * sizeof(btSimdFloat4), NULL );
float *fp = (float*) data;
long correct, test;
btVector3 localScaling( 0.1f, 0.2f, 0.3f);
size_t size;
// Init the data
size_t i;
for( i = 0; i < MAX_SIZE; i++ )
{
fp[4*i] = (int32_t) RANDF_16;
fp[4*i+1] = (int32_t) RANDF_16;
fp[4*i+2] = (int32_t) RANDF_16;
fp[4*i+3] = BT_NAN; // w channel NaN
}
float correctDot, testDot;
fp = (float*) localScaling;
float maxRelativeError = 0.f;
for( size = 1; size <= MAX_SIZE; size++ )
{
float *in = (float*)(data + MAX_SIZE - size);
size_t position;
for( position = 0; position < size; position++ )
{
float *biggest = in + position * 4;
float old[4] = { biggest[0], biggest[1], biggest[2], biggest[3] };
biggest[0] -= LARGE_FLOAT17;
biggest[1] -= LARGE_FLOAT17;
biggest[2] -= LARGE_FLOAT17;
biggest[3] -= LARGE_FLOAT17;
correctDot = BT_NAN;
testDot = BT_NAN;
correct = mindot_ref( (btSimdFloat4*) in, (float*) &localScaling, size, &correctDot);
test = localScaling.minDot( (btVector3*) in, size, testDot);
if( test < 0 || test >= size )
{
vlog( "Error @ %ld: index out of bounds! *%ld vs %ld \n", size, correct, test);
continue;
}
if( correct != test )
{
vlog( "Error @ %ld: index misreported! *%ld vs %ld (*%f, %f)\n", size, correct, test,
fp[0] * in[4*correct] + fp[1] * in[4*correct+1] + fp[2] * in[4*correct+2],
fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2] );
return 1;
}
if( test != position )
{
vlog( "Biggest not found where it is supposed to be: *%ld vs %ld (*%f, %f)\n", position, test,
fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2],
fp[0] * in[4*position] + fp[1] * in[4*position+1] + fp[2] * in[4*position+2] );
return 1;
}
if( correctDot != testDot )
{
float relativeError = btFabs((testDot - correctDot) / correctDot);
if (relativeError>1e6)
{
vlog( "Error @ %ld: dotpr misreported! *%f vs %f (*%f, %f)\n", size, correctDot, testDot,
fp[0] * in[4*correct] + fp[1] * in[4*correct+1] + fp[2] * in[4*correct+2],
fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2] );
return 1;
} else
{
if (maxRelativeError < relativeError)
{
maxRelativeError = relativeError;
}
}
}
memcpy( biggest, old, 16 );
}
}
if (maxRelativeError)
{
printf("Warning: relative error = %e\n", maxRelativeError);
}
uint64_t scalarTimes[33 + (MAX_LOG2_SIZE-5)];
uint64_t vectorTimes[33 + (MAX_LOG2_SIZE-5)];
size_t j, k;
float *in = (float*) data;
for( size = 1; size <= 32; size++ )
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
scalarTimes[size] = 0;
for (j = 0; j < 100; j++) {
startTime = ReadTicks();
for( k = 0; k < LOOPCOUNT; k++ )
correct += mindot_ref( (btSimdFloat4*) in, (float*) &localScaling, size, &correctDot);
currentTime = ReadTicks() - startTime;
scalarTimes[size] += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
scalarTimes[size] = bestTime;
else
scalarTimes[size] /= 100;
}
uint64_t *timep = &scalarTimes[33];
for( size = 64; size <= MAX_SIZE; size *= 2 )
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
timep[0] =0;
for (j = 0; j < 100; j++) {
startTime = ReadTicks();
for( k = 0; k < LOOPCOUNT; k++ )
correct += mindot_ref( (btSimdFloat4*) in, (float*) &localScaling, size, &correctDot);
currentTime = ReadTicks() - startTime;
timep[0] += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
timep[0] = bestTime;
else
timep[0] /= 100;
timep++;
}
for( size = 1; size <= 32; size++ )
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
vectorTimes[size] = 0;
for (j = 0; j < 100; j++) {
startTime = ReadTicks();
for( k = 0; k < LOOPCOUNT; k++ )
test += localScaling.minDot( (btVector3*) in, size, testDot);
currentTime = ReadTicks() - startTime;
vectorTimes[size] += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
vectorTimes[size] = bestTime;
else
vectorTimes[size] /= 100;
}
timep = &vectorTimes[33];
for( size = 64; size <= MAX_SIZE; size *= 2 )
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
timep[0] =0;
for (j = 0; j < 100; j++) {
startTime = ReadTicks();
for( k = 0; k < LOOPCOUNT; k++ )
test += localScaling.minDot( (btVector3*) in, size, testDot);
currentTime = ReadTicks() - startTime;
timep[0] += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
timep[0] = bestTime;
else
timep[0] /= 100;
timep++;
}
vlog( "Timing:\n" );
vlog( " size\t scalar\t vector\n" );
for( size = 1; size <= 32; size++ )
vlog( "%5lu\t%10.2f\t%10.2f\n", size, TicksToCycles( scalarTimes[size] ) / LOOPCOUNT, TicksToCycles( vectorTimes[size] ) / LOOPCOUNT );
size_t index = 33;
for( size = 64; size <= MAX_SIZE; size *= 2 )
{
vlog( "%5lu\t%10.2f\t%10.2f\n", size, TicksToCycles( scalarTimes[index] ) / LOOPCOUNT, TicksToCycles( vectorTimes[index] ) / LOOPCOUNT );
index++;
}
// Useless check to make sure that the timing loops are not optimized away
if( test != correct )
vlog( "Error: Test != correct: *%ld vs. %ld\n", correct, test);
GuardFree(data);
return 0;
}
static long mindot_ref( const btSimdFloat4 *vertices,
float *vec,
size_t count,
float *dotResult )
{
const float *dp = (const float*) vertices;
float minDot = BT_INFINITY;
long i = 0;
long ptIndex = -1;
for( i = 0; i < count; i++ )
{
float dot = vec[0] * dp[0] + vec[1] * dp[1] + vec[2] * dp[2]; dp += 4;
if( dot < minDot )
{
minDot = dot;
ptIndex = i;
}
}
*dotResult = minDot;
return ptIndex;
}
#endif //BT_USE_SSE

View File

@@ -0,0 +1,22 @@
//
// Test_mindot.h
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#ifndef BulletTest_Test_mindot_h
#define BulletTest_Test_mindot_h
#ifdef __cplusplus
extern "C" {
#endif
int Test_mindot(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,162 @@
//
// Test_qtdot.cpp
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#include "LinearMath/btScalar.h"
#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
#include "Test_qtdot.h"
#include "vector.h"
#include "Utils.h"
#include "main.h"
#include <math.h>
#include <string.h>
#include <LinearMath/btQuaternion.h>
#define BT_OP(a, b) (a.dot(b))
// reference code for testing purposes
static inline btScalar qtdot_ref(btQuaternion& q1, btQuaternion& q2);
static inline btScalar qtdot_ref(btQuaternion& q1, btQuaternion& q2)
{
return
q1.x() * q2.x() +
q1.y() * q2.y() +
q1.z() * q2.z() +
q1.w() * q2.w();
}
#define LOOPCOUNT 1024
#define NUM_CYCLES 1000
int Test_qtdot(void)
{
btQuaternion q1, q2;
float x, y, z, w, vNaN;
vNaN = BT_NAN; // w channel NaN
// Init the data
x = RANDF_01;
y = RANDF_01;
z = RANDF_01;
w = RANDF_01;
q1.setValue(x,y,z,w);
x = RANDF_01;
y = RANDF_01;
z = RANDF_01;
w = RANDF_01;
q2.setValue(x,y,z,w);
btScalar correct_res, test_res;
{
correct_res = vNaN;
test_res = vNaN;
correct_res = qtdot_ref(q1, q2);
test_res = BT_OP(q1,q2);
if( fabsf(correct_res - test_res) > FLT_EPSILON*4 )
{
vlog( "Error - qtdot result error! "
"\ncorrect = %10.4f "
"\ntested = %10.4f \n",
correct_res, test_res);
return 1;
}
}
#define DATA_SIZE LOOPCOUNT
btQuaternion qt_arr1[DATA_SIZE];
btQuaternion qt_arr2[DATA_SIZE];
btScalar res_arr[DATA_SIZE];
uint64_t scalarTime;
uint64_t vectorTime;
size_t j, k;
for( k = 0; k < DATA_SIZE; k++ )
{
x = RANDF_01;
y = RANDF_01;
z = RANDF_01;
w = RANDF_01;
qt_arr1[k].setValue(x,y,z,w);
x = RANDF_01;
y = RANDF_01;
z = RANDF_01;
w = RANDF_01;
qt_arr2[k].setValue(x,y,z,w);
}
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
scalarTime = 0;
for (j = 0; j < NUM_CYCLES; j++)
{
startTime = ReadTicks();
for( k = 0; k+4 <= LOOPCOUNT; k+=4 )
{
size_t km = (k & (DATA_SIZE-1));
res_arr[km] = qtdot_ref(qt_arr1[km], qt_arr2[km]);km++;
res_arr[km] = qtdot_ref(qt_arr1[km], qt_arr2[km]);km++;
res_arr[km] = qtdot_ref(qt_arr1[km], qt_arr2[km]);km++;
res_arr[km] = qtdot_ref(qt_arr1[km], qt_arr2[km]);
}
currentTime = ReadTicks() - startTime;
scalarTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
scalarTime = bestTime;
else
scalarTime /= NUM_CYCLES;
}
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
vectorTime = 0;
for (j = 0; j < NUM_CYCLES; j++)
{
startTime = ReadTicks();
for( k = 0; k+4 <= LOOPCOUNT; k+=4 )
{
size_t km = (k & (DATA_SIZE-1));
res_arr[km] = BT_OP(qt_arr1[km], qt_arr2[km]);km++;
res_arr[km] = BT_OP(qt_arr1[km], qt_arr2[km]);km++;
res_arr[km] = BT_OP(qt_arr1[km], qt_arr2[km]);km++;
res_arr[km] = BT_OP(qt_arr1[km], qt_arr2[km]);km++;
}
currentTime = ReadTicks() - startTime;
vectorTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
vectorTime = bestTime;
else
vectorTime /= NUM_CYCLES;
}
vlog( "Timing:\n" );
vlog( " \t scalar\t vector\n" );
vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT,
TicksToCycles( vectorTime ) / LOOPCOUNT );
return 0;
}
#endif //BT_USE_SSE

View File

@@ -0,0 +1,22 @@
//
// Test_qtdot.h
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#ifndef BulletTest_Test_qtdot_h
#define BulletTest_Test_qtdot_h
#ifdef __cplusplus
extern "C" {
#endif
int Test_qtdot(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,183 @@
//
// Test_qtmul.cpp
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#include "LinearMath/btScalar.h"
#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
#include "Test_qtmul.h"
#include "vector.h"
#include "Utils.h"
#include "main.h"
#include <math.h>
#include <string.h>
#include <LinearMath/btQuaternion.h>
#define BT_OP(a, b) ((a) *= (b))
// reference code for testing purposes
static inline btQuaternion& qtmul_ref(btQuaternion& q1, btQuaternion& q2);
static inline btQuaternion& qtmul_ref(btQuaternion& q1, btQuaternion& q2)
{
float x,y,z,w;
x = q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(),
y = q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z(),
z = q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x(),
w = q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z();
q1.setValue(x, y, z, w);
return q1;
}
#define LOOPCOUNT 1024
#define NUM_CYCLES 1000
int Test_qtmul(void)
{
btQuaternion q1, q2, q3;
float x, y, z, w, vNaN;
// Init the data
x = RANDF_01;
y = RANDF_01;
z = RANDF_01;
w = RANDF_01;
vNaN = BT_NAN; // w channel NaN
q1.setValue(x,y,z,w);
x = RANDF_01;
y = RANDF_01;
z = RANDF_01;
w = RANDF_01;
q2.setValue(x,y,z,w);
q3 = q1;
btQuaternion correct_res, test_res;
{
float vNaN = BT_NAN;
correct_res.setValue(vNaN, vNaN, vNaN, vNaN);
test_res.setValue(vNaN, vNaN, vNaN, vNaN);
correct_res = qtmul_ref(q1, q2);
test_res = BT_OP(q3,q2);
if( fabsf(correct_res.x() - test_res.x()) +
fabsf(correct_res.y() - test_res.y()) +
fabsf(correct_res.z() - test_res.z()) +
fabsf(correct_res.w() - test_res.w()) > FLT_EPSILON*10 )
{
vlog( "Error - qtmul result error! "
"\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) "
"\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) \n",
correct_res.x(), correct_res.y(),
correct_res.z(), correct_res.w(),
test_res.x(), test_res.y(),
test_res.z(), test_res.w());
return 1;
}
}
#define DATA_SIZE LOOPCOUNT
btQuaternion qt_arr1[DATA_SIZE];
btQuaternion qt_arr2[DATA_SIZE];
uint64_t scalarTime;
uint64_t vectorTime;
size_t j, k;
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
scalarTime = 0;
for (j = 0; j < NUM_CYCLES; j++)
{
for( k = 0; k < DATA_SIZE; k++ )
{
x = RANDF_01;
y = RANDF_01;
z = RANDF_01;
w = RANDF_01;
qt_arr1[k].setValue(x,y,z,w);
x = RANDF_01;
y = RANDF_01;
z = RANDF_01;
w = RANDF_01;
qt_arr2[k].setValue(x,y,z,w);
}
startTime = ReadTicks();
for( k = 0; k < LOOPCOUNT; k++ )
{
qt_arr1[k] = qtmul_ref(qt_arr1[k], qt_arr2[k]);
}
currentTime = ReadTicks() - startTime;
scalarTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
scalarTime = bestTime;
else
scalarTime /= NUM_CYCLES;
}
{
uint64_t startTime, bestTime, currentTime;
bestTime = -1LL;
vectorTime = 0;
for (j = 0; j < NUM_CYCLES; j++)
{
for( k = 0; k < DATA_SIZE; k++ )
{
x = RANDF_01;
y = RANDF_01;
z = RANDF_01;
w = RANDF_01;
qt_arr1[k].setValue(x,y,z,w);
x = RANDF_01;
y = RANDF_01;
z = RANDF_01;
w = RANDF_01;
qt_arr2[k].setValue(x,y,z,w);
}
startTime = ReadTicks();
for( k = 0; k < LOOPCOUNT; k++ )
{
qt_arr1[k] = BT_OP(qt_arr1[k], qt_arr2[k]);
}
currentTime = ReadTicks() - startTime;
vectorTime += currentTime;
if( currentTime < bestTime )
bestTime = currentTime;
}
if( 0 == gReportAverageTimes )
vectorTime = bestTime;
else
vectorTime /= NUM_CYCLES;
}
vlog( "Timing:\n" );
vlog( " \t scalar\t vector\n" );
vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT,
TicksToCycles( vectorTime ) / LOOPCOUNT );
return 0;
}
#endif //BT_USE_SSE

View File

@@ -0,0 +1,22 @@
//
// Test_qtmul.h
// BulletTest
//
// Copyright (c) 2011 Apple Inc.
//
#ifndef BulletTest_Test_qtmul_h
#define BulletTest_Test_qtmul_h
#ifdef __cplusplus
extern "C" {
#endif
int Test_qtmul(void);
#ifdef __cplusplus
}
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More