1 //
2 // Test_v3rotate.cpp
3 // BulletTest
4 //
5 // Copyright (c) 2011 Apple Inc.
6 //
7
8 #include "LinearMath/btScalar.h"
9 #if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON)
10
11 #include "Test_v3rotate.h"
12 #include "vector.h"
13 #include "Utils.h"
14 #include "main.h"
15 #include <math.h>
16 #include <string.h>
17
18 #include <LinearMath/btVector3.h>
19
20 // reference code for testing purposes
21 static inline btVector3& v3rotate_ref(
22 btVector3& v0,
23 btVector3& v1,
24 const btScalar& s);
25
26 #define LOOPCOUNT 2048
27 #define NUM_CYCLES 1000
28
Test_v3rotate(void)29 int Test_v3rotate(void)
30 {
31 btVector3 v1, v2;
32 float s;
33
34 float x, y, z, w;
35
36 // Init the data
37 x = RANDF_01;
38 y = RANDF_01;
39 z = RANDF_01;
40 w = BT_NAN; // w channel NaN
41 v1.setValue(x, y, z);
42 v1.setW(w);
43
44 x = RANDF_01;
45 y = RANDF_01;
46 z = RANDF_01;
47 v2.setValue(x, y, z);
48 v2.setW(w);
49
50 s = RANDF_01 * (float)SIMD_PI;
51
52 btVector3 correct_res, test_res;
53
54 {
55 float vNaN = BT_NAN;
56 correct_res.setValue(vNaN, vNaN, vNaN);
57 test_res.setValue(vNaN, vNaN, vNaN);
58 test_res = v1.rotate(v2, s);
59 correct_res = v3rotate_ref(v1, v2, s);
60
61 if (fabs(correct_res.m_floats[0] - test_res.m_floats[0]) +
62 fabs(correct_res.m_floats[1] - test_res.m_floats[1]) +
63 fabs(correct_res.m_floats[2] - test_res.m_floats[2]) >
64 FLT_EPSILON * 4)
65 {
66 vlog(
67 "Error - v3rotate result error! "
68 "\ncorrect = (%10.4f, %10.4f, %10.4f) "
69 "\ntested = (%10.4f, %10.4f, %10.4f) \n",
70 correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2],
71 test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2]);
72
73 return 1;
74 }
75 }
76
77 #define DATA_SIZE LOOPCOUNT
78
79 btVector3 vec3_arr0[DATA_SIZE];
80 btVector3 vec3_arr1[DATA_SIZE];
81 btScalar s_arr[DATA_SIZE];
82
83 uint64_t scalarTime;
84 uint64_t vectorTime;
85 size_t j, k;
86
87 {
88 uint64_t startTime, bestTime, currentTime;
89
90 bestTime = -1LL;
91 scalarTime = 0;
92 for (j = 0; j < NUM_CYCLES; j++)
93 {
94 for (k = 0; k < DATA_SIZE; k++)
95 {
96 x = RANDF_01;
97 y = RANDF_01;
98 z = RANDF_01;
99 vec3_arr0[k].setValue(x, y, z);
100 vec3_arr0[k].setW(w);
101
102 x = RANDF_01;
103 y = RANDF_01;
104 z = RANDF_01;
105 vec3_arr1[k].setValue(x, y, z);
106 vec3_arr1[k].setW(w);
107
108 s_arr[k] = RANDF_01 * (float)SIMD_PI;
109 }
110
111 startTime = ReadTicks();
112 for (k = 0; k < LOOPCOUNT; k++)
113 {
114 vec3_arr0[k] = v3rotate_ref(vec3_arr0[k], vec3_arr1[k], s_arr[k]);
115 }
116 currentTime = ReadTicks() - startTime;
117 scalarTime += currentTime;
118 if (currentTime < bestTime)
119 bestTime = currentTime;
120 }
121 if (0 == gReportAverageTimes)
122 scalarTime = bestTime;
123 else
124 scalarTime /= NUM_CYCLES;
125 }
126
127 {
128 uint64_t startTime, bestTime, currentTime;
129
130 bestTime = -1LL;
131 vectorTime = 0;
132 for (j = 0; j < NUM_CYCLES; j++)
133 {
134 for (k = 0; k < DATA_SIZE; k++)
135 {
136 x = RANDF_01;
137 y = RANDF_01;
138 z = RANDF_01;
139 vec3_arr0[k].setValue(x, y, z);
140 vec3_arr0[k].setW(w);
141
142 x = RANDF_01;
143 y = RANDF_01;
144 z = RANDF_01;
145 vec3_arr1[k].setValue(x, y, z);
146 vec3_arr1[k].setW(w);
147
148 s_arr[k] = RANDF_01 * (float)SIMD_PI;
149 }
150
151 startTime = ReadTicks();
152 for (k = 0; k < LOOPCOUNT; k++)
153 {
154 vec3_arr0[k] = vec3_arr0[k].rotate(vec3_arr1[k], s_arr[k]);
155 }
156 currentTime = ReadTicks() - startTime;
157 vectorTime += currentTime;
158 if (currentTime < bestTime)
159 bestTime = currentTime;
160 }
161 if (0 == gReportAverageTimes)
162 vectorTime = bestTime;
163 else
164 vectorTime /= NUM_CYCLES;
165 }
166
167 vlog("Timing:\n");
168 vlog(" \t scalar\t vector\n");
169 vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT,
170 TicksToCycles(vectorTime) / LOOPCOUNT);
171
172 return 0;
173 }
174
175 static inline btVector3&
v3rotate_ref(btVector3 & v0,btVector3 & wAxis,const btScalar & _angle)176 v3rotate_ref(
177 btVector3& v0,
178 btVector3& wAxis,
179 const btScalar& _angle)
180 {
181 btVector3 o = wAxis * wAxis.dot(v0);
182 btVector3 _x = v0 - o;
183 btVector3 _y;
184
185 _y = wAxis.cross(v0);
186
187 v0 = o + _x * cosf(_angle) + _y * sinf(_angle);
188
189 return v0;
190 }
191
192 #endif //BT_USE_SSE
193