5 // Copyright (c) 2011 Apple Inc.
10 #include "LinearMath/btScalar.h"
11 #if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
13 #include "Test_qtmulQV3.h"
20 #include <LinearMath/btQuaternion.h>
22 #define BT_OP(a, b) ((a) * (b))
23 // reference code for testing purposes
24 static inline btQuaternion qtmulQV3_ref(const btQuaternion& q, const btVector3& w);
26 static inline btQuaternion qtmulQV3_ref(const btQuaternion& q, const btVector3& w)
29 q.w() * w.x() + q.y() * w.z() - q.z() * w.y(),
30 q.w() * w.y() + q.z() * w.x() - q.x() * w.z(),
31 q.w() * w.z() + q.x() * w.y() - q.y() * w.x(),
32 -q.x() * w.x() - q.y() * w.y() - q.z() * w.z());
35 #define LOOPCOUNT 1024
36 #define NUM_CYCLES 1000
38 static inline btSimdFloat4 rand_f4(void)
40 return btAssign128( RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, BT_NAN ); // w channel NaN
43 static inline btSimdFloat4 qtrand_f4(void)
45 return btAssign128( RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, RANDF_m1p1 );
48 static inline btSimdFloat4 qtNAN_f4(void)
50 return btAssign128( BT_NAN, BT_NAN, BT_NAN, BT_NAN );
53 int Test_qtmulQV3(void)
59 q = btQuaternion(qtrand_f4());
60 v3 = btVector3(rand_f4());
62 btQuaternion correct_res, test_res;
63 correct_res = btQuaternion(qtNAN_f4());
64 test_res = btQuaternion(qtNAN_f4());
67 correct_res = qtmulQV3_ref(q, v3);
68 test_res = BT_OP(q, v3);
70 if( fabsf(correct_res.x() - test_res.x()) +
71 fabsf(correct_res.y() - test_res.y()) +
72 fabsf(correct_res.z() - test_res.z()) +
73 fabsf(correct_res.w() - test_res.w()) > FLT_EPSILON*8 )
75 vlog( "Error - qtmulQV3 result error! "
76 "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) "
77 "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) \n",
78 correct_res.x(), correct_res.y(),
79 correct_res.z(), correct_res.w(),
80 test_res.x(), test_res.y(),
81 test_res.z(), test_res.w());
87 #define DATA_SIZE LOOPCOUNT
89 btQuaternion qt_arrR[DATA_SIZE];
90 btQuaternion qt_arr[DATA_SIZE];
91 btVector3 v3_arr[DATA_SIZE];
98 uint64_t startTime, bestTime, currentTime;
102 for (j = 0; j < NUM_CYCLES; j++)
104 for( k = 0; k < DATA_SIZE; k++ )
106 qt_arr[k] = btQuaternion(qtrand_f4());
107 v3_arr[k] = btVector3(rand_f4());
110 startTime = ReadTicks();
111 for( k = 0; k < LOOPCOUNT; k++ )
113 qt_arrR[k] = qtmulQV3_ref(qt_arr[k], v3_arr[k]);
115 currentTime = ReadTicks() - startTime;
116 scalarTime += currentTime;
117 if( currentTime < bestTime )
118 bestTime = currentTime;
120 if( 0 == gReportAverageTimes )
121 scalarTime = bestTime;
123 scalarTime /= NUM_CYCLES;
127 uint64_t startTime, bestTime, currentTime;
131 for (j = 0; j < NUM_CYCLES; j++)
133 for( k = 0; k < DATA_SIZE; k++ )
135 qt_arr[k] = btQuaternion(qtrand_f4());
136 v3_arr[k] = btVector3(rand_f4());
139 startTime = ReadTicks();
140 for( k = 0; k < LOOPCOUNT; k++ )
142 qt_arrR[k] = BT_OP(qt_arr[k], v3_arr[k]);
144 currentTime = ReadTicks() - startTime;
145 vectorTime += currentTime;
146 if( currentTime < bestTime )
147 bestTime = currentTime;
149 if( 0 == gReportAverageTimes )
150 vectorTime = bestTime;
152 vectorTime /= NUM_CYCLES;
156 vlog( " \t scalar\t vector\n" );
157 vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT,
158 TicksToCycles( vectorTime ) / LOOPCOUNT );