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