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:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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++)
|
||||||
|
|||||||
22
Demos/Benchmarks/premake4.lua
Normal file
22
Demos/Benchmarks/premake4.lua
Normal 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",
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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]));
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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 );
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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];
|
||||||
|
|||||||
@@ -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)
|
||||||
22
Demos/HelloWorld/premake4.lua
Normal file
22
Demos/HelloWorld/premake4.lua
Normal 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",
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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?
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
..\..\..\msvc\premake4 vs2010
|
..\..\..\build\premake4 vs2010
|
||||||
|
|
||||||
mkdir vs2010\cache
|
mkdir vs2010\cache
|
||||||
pause
|
pause
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
47
Test/Info.plist
Normal 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
28
Test/README.txt
Normal 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
97
Test/Source/TestList.cpp
Normal 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
28
Test/Source/TestList.h
Normal 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
|
||||||
158
Test/Source/Tests/Test_3x3getRot.cpp
Normal file
158
Test/Source/Tests/Test_3x3getRot.cpp
Normal 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
|
||||||
22
Test/Source/Tests/Test_3x3getRot.h
Normal file
22
Test/Source/Tests/Test_3x3getRot.h
Normal 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
|
||||||
169
Test/Source/Tests/Test_3x3mulM.cpp
Normal file
169
Test/Source/Tests/Test_3x3mulM.cpp
Normal 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
|
||||||
22
Test/Source/Tests/Test_3x3mulM.h
Normal file
22
Test/Source/Tests/Test_3x3mulM.h
Normal 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
|
||||||
164
Test/Source/Tests/Test_3x3mulM1M2.cpp
Normal file
164
Test/Source/Tests/Test_3x3mulM1M2.cpp
Normal 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
|
||||||
22
Test/Source/Tests/Test_3x3mulM1M2.h
Normal file
22
Test/Source/Tests/Test_3x3mulM1M2.h
Normal 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
|
||||||
112
Test/Source/Tests/Test_3x3mulMV.cpp
Normal file
112
Test/Source/Tests/Test_3x3mulMV.cpp
Normal 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
|
||||||
23
Test/Source/Tests/Test_3x3mulMV.h
Normal file
23
Test/Source/Tests/Test_3x3mulMV.h
Normal 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
|
||||||
|
|
||||||
112
Test/Source/Tests/Test_3x3mulVM.cpp
Normal file
112
Test/Source/Tests/Test_3x3mulVM.cpp
Normal 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
|
||||||
22
Test/Source/Tests/Test_3x3mulVM.h
Normal file
22
Test/Source/Tests/Test_3x3mulVM.h
Normal 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
|
||||||
171
Test/Source/Tests/Test_3x3setRot.cpp
Normal file
171
Test/Source/Tests/Test_3x3setRot.cpp
Normal 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
|
||||||
|
|
||||||
22
Test/Source/Tests/Test_3x3setRot.h
Normal file
22
Test/Source/Tests/Test_3x3setRot.h
Normal 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
|
||||||
117
Test/Source/Tests/Test_3x3timesTranspose.cpp
Normal file
117
Test/Source/Tests/Test_3x3timesTranspose.cpp
Normal 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
|
||||||
22
Test/Source/Tests/Test_3x3timesTranspose.h
Normal file
22
Test/Source/Tests/Test_3x3timesTranspose.h
Normal 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
|
||||||
116
Test/Source/Tests/Test_3x3transpose.cpp
Normal file
116
Test/Source/Tests/Test_3x3transpose.cpp
Normal 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
|
||||||
|
|
||||||
22
Test/Source/Tests/Test_3x3transpose.h
Normal file
22
Test/Source/Tests/Test_3x3transpose.h
Normal 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
|
||||||
168
Test/Source/Tests/Test_3x3transposeTimes.cpp
Normal file
168
Test/Source/Tests/Test_3x3transposeTimes.cpp
Normal 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
|
||||||
|
|
||||||
22
Test/Source/Tests/Test_3x3transposeTimes.h
Normal file
22
Test/Source/Tests/Test_3x3transposeTimes.h
Normal 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
|
||||||
495
Test/Source/Tests/Test_btDbvt.cpp
Normal file
495
Test/Source/Tests/Test_btDbvt.cpp
Normal 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
21
Test/Source/Tests/Test_btDbvt.h
Normal file
21
Test/Source/Tests/Test_btDbvt.h
Normal 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
|
||||||
153
Test/Source/Tests/Test_dot3.cpp
Normal file
153
Test/Source/Tests/Test_dot3.cpp
Normal 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
|
||||||
22
Test/Source/Tests/Test_dot3.h
Normal file
22
Test/Source/Tests/Test_dot3.h
Normal 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
|
||||||
281
Test/Source/Tests/Test_maxdot.cpp
Normal file
281
Test/Source/Tests/Test_maxdot.cpp
Normal 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
|
||||||
22
Test/Source/Tests/Test_maxdot.h
Normal file
22
Test/Source/Tests/Test_maxdot.h
Normal 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
|
||||||
269
Test/Source/Tests/Test_mindot.cpp
Normal file
269
Test/Source/Tests/Test_mindot.cpp
Normal 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
|
||||||
22
Test/Source/Tests/Test_mindot.h
Normal file
22
Test/Source/Tests/Test_mindot.h
Normal 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
|
||||||
162
Test/Source/Tests/Test_qtdot.cpp
Normal file
162
Test/Source/Tests/Test_qtdot.cpp
Normal 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
|
||||||
22
Test/Source/Tests/Test_qtdot.h
Normal file
22
Test/Source/Tests/Test_qtdot.h
Normal 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
|
||||||
183
Test/Source/Tests/Test_qtmul.cpp
Normal file
183
Test/Source/Tests/Test_qtmul.cpp
Normal 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
|
||||||
22
Test/Source/Tests/Test_qtmul.h
Normal file
22
Test/Source/Tests/Test_qtmul.h
Normal 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
Reference in New Issue
Block a user