Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Test / Source / Tests / Test_qtmulQV3.cpp
1 //
2 //  Test_qtmulQV3.cpp
3 //  BulletTest
4 //
5 //  Copyright (c) 2011 Apple Inc.
6 //
7
8
9
10 #include "LinearMath/btScalar.h"
11 #if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
12
13 #include "Test_qtmulQV3.h"
14 #include "vector.h"
15 #include "Utils.h"
16 #include "main.h"
17 #include <math.h>
18 #include <string.h>
19
20 #include <LinearMath/btQuaternion.h>
21
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);
25
26 static inline btQuaternion qtmulQV3_ref(const btQuaternion& q, const btVector3& w)
27 {
28         return btQuaternion( 
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()); 
33 }
34
35 #define LOOPCOUNT 1024
36 #define NUM_CYCLES 1000
37
38 static inline btSimdFloat4 rand_f4(void)
39 {
40     return btAssign128( RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, BT_NAN );      // w channel NaN
41 }
42
43 static inline btSimdFloat4 qtrand_f4(void)
44 {
45     return btAssign128( RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, RANDF_m1p1 );
46 }
47
48 static inline btSimdFloat4 qtNAN_f4(void)
49 {
50     return btAssign128( BT_NAN, BT_NAN, BT_NAN, BT_NAN );
51 }
52
53 int Test_qtmulQV3(void)
54 {
55     btQuaternion q;
56         btVector3 v3;
57     
58     // Init the data
59     q = btQuaternion(qtrand_f4()); 
60     v3 = btVector3(rand_f4());
61
62     btQuaternion correct_res, test_res;
63     correct_res = btQuaternion(qtNAN_f4());
64     test_res = btQuaternion(qtNAN_f4());
65          
66     {
67                 correct_res = qtmulQV3_ref(q, v3);
68                 test_res = BT_OP(q, v3);
69            
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 )
74                 {       
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());
82                 
83                         return 1;
84                 }
85         }
86     
87 #define DATA_SIZE LOOPCOUNT
88
89         btQuaternion qt_arrR[DATA_SIZE];
90         btQuaternion qt_arr[DATA_SIZE];
91         btVector3 v3_arr[DATA_SIZE];
92
93     uint64_t scalarTime;
94     uint64_t vectorTime;
95     size_t j, k;
96
97         {
98         uint64_t startTime, bestTime, currentTime;
99         
100         bestTime = -1LL;
101         scalarTime = 0;
102         for (j = 0; j < NUM_CYCLES; j++) 
103                 {
104                         for( k = 0; k < DATA_SIZE; k++ )
105                         {
106                 qt_arr[k] = btQuaternion(qtrand_f4()); 
107                 v3_arr[k] = btVector3(rand_f4());
108                         }
109
110             startTime = ReadTicks();
111             for( k = 0; k < LOOPCOUNT; k++ )
112                         {
113                     qt_arrR[k] = qtmulQV3_ref(qt_arr[k], v3_arr[k]);
114                         }
115                         currentTime = ReadTicks() - startTime;
116             scalarTime += currentTime;
117             if( currentTime < bestTime )
118                 bestTime = currentTime;
119         }
120         if( 0 == gReportAverageTimes )
121             scalarTime = bestTime;        
122         else
123             scalarTime /= NUM_CYCLES;
124     }
125     
126     {
127         uint64_t startTime, bestTime, currentTime;
128         
129         bestTime = -1LL;
130         vectorTime = 0;
131         for (j = 0; j < NUM_CYCLES; j++) 
132                 {
133                         for( k = 0; k < DATA_SIZE; k++ )
134                         {
135                 qt_arr[k] = btQuaternion(qtrand_f4()); 
136                 v3_arr[k] = btVector3(rand_f4());
137                         }
138
139             startTime = ReadTicks();
140             for( k = 0; k < LOOPCOUNT; k++ )
141                         {
142                                 qt_arrR[k] = BT_OP(qt_arr[k], v3_arr[k]);
143                         }
144                         currentTime = ReadTicks() - startTime;
145             vectorTime += currentTime;
146             if( currentTime < bestTime )
147                 bestTime = currentTime;
148         }
149         if( 0 == gReportAverageTimes )
150             vectorTime = bestTime;        
151         else
152             vectorTime /= NUM_CYCLES;
153     }
154
155     vlog( "Timing:\n" );
156     vlog( "     \t    scalar\t    vector\n" );
157     vlog( "    \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, 
158                                                                         TicksToCycles( vectorTime ) / LOOPCOUNT );
159
160     return 0;
161 }
162 #endif //BT_USE_SSE