ReactOS 0.4.15-dev-7934-g1dc8d80
vector.c
Go to the documentation of this file.
1/*
2 * Copyright 2007 Vijay Kiran Kamuju
3 * Copyright 2007 David Adam
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20#include <math.h>
21
22#include "d3drmdef.h"
23
24#include "wine/test.h"
25
26#define PI (4.0f*atanf(1.0f))
27#define admit_error 0.000001f
28
29#define expect_mat( expectedmat, gotmat)\
30{ \
31 int i,j; \
32 BOOL equal = TRUE; \
33 for (i=0; i<4; i++)\
34 {\
35 for (j=0; j<4; j++)\
36 {\
37 if (fabs(expectedmat[i][j]-gotmat[i][j])>admit_error)\
38 {\
39 equal = FALSE;\
40 }\
41 }\
42 }\
43 ok(equal, "Expected matrix=\n(%f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f\n)\n\n" \
44 "Got matrix=\n(%f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f\n %f,%f,%f,%f)\n", \
45 expectedmat[0][0],expectedmat[0][1],expectedmat[0][2],expectedmat[0][3], \
46 expectedmat[1][0],expectedmat[1][1],expectedmat[1][2],expectedmat[1][3], \
47 expectedmat[2][0],expectedmat[2][1],expectedmat[2][2],expectedmat[2][3], \
48 expectedmat[3][0],expectedmat[3][1],expectedmat[3][2],expectedmat[3][3], \
49 gotmat[0][0],gotmat[0][1],gotmat[0][2],gotmat[0][3], \
50 gotmat[1][0],gotmat[1][1],gotmat[1][2],gotmat[1][3], \
51 gotmat[2][0],gotmat[2][1],gotmat[2][2],gotmat[2][3], \
52 gotmat[3][0],gotmat[3][1],gotmat[3][2],gotmat[3][3] ); \
53}
54
55#define expect_quat(expectedquat,gotquat) \
56 ok( (fabs(U1(expectedquat.v).x-U1(gotquat.v).x)<admit_error) && \
57 (fabs(U2(expectedquat.v).y-U2(gotquat.v).y)<admit_error) && \
58 (fabs(U3(expectedquat.v).z-U3(gotquat.v).z)<admit_error) && \
59 (fabs(expectedquat.s-gotquat.s)<admit_error), \
60 "Expected Quaternion %f %f %f %f , Got Quaternion %f %f %f %f\n", \
61 expectedquat.s,U1(expectedquat.v).x,U2(expectedquat.v).y,U3(expectedquat.v).z, \
62 gotquat.s,U1(gotquat.v).x,U2(gotquat.v).y,U3(gotquat.v).z);
63
64#define expect_vec(expectedvec,gotvec) \
65 ok( ((fabs(U1(expectedvec).x-U1(gotvec).x)<admit_error)&&(fabs(U2(expectedvec).y-U2(gotvec).y)<admit_error)&&(fabs(U3(expectedvec).z-U3(gotvec).z)<admit_error)), \
66 "Expected Vector= (%f, %f, %f)\n , Got Vector= (%f, %f, %f)\n", \
67 U1(expectedvec).x,U2(expectedvec).y,U3(expectedvec).z, U1(gotvec).x, U2(gotvec).y, U3(gotvec).z);
68
69static void VectorTest(void)
70{
71 D3DVALUE mod,par,theta;
72 D3DVECTOR e,r,u,v,w,axis,casnul,norm,ray,self;
73
74 U1(u).x=2.0f; U2(u).y=2.0f; U3(u).z=1.0f;
75 U1(v).x=4.0f; U2(v).y=4.0f; U3(v).z=0.0f;
76
77
78/*______________________VectorAdd_________________________________*/
79 D3DRMVectorAdd(&r,&u,&v);
80 U1(e).x=6.0f; U2(e).y=6.0f; U3(e).z=1.0f;
81 expect_vec(e,r);
82
83 U1(self).x=9.0f; U2(self).y=18.0f; U3(self).z=27.0f;
84 D3DRMVectorAdd(&self,&self,&u);
85 U1(e).x=11.0f; U2(e).y=20.0f; U3(e).z=28.0f;
86 expect_vec(e,self);
87
88/*_______________________VectorSubtract__________________________*/
90 U1(e).x=-2.0f; U2(e).y=-2.0f; U3(e).z=1.0f;
91 expect_vec(e,r);
92
93 U1(self).x=9.0f; U2(self).y=18.0f; U3(self).z=27.0f;
94 D3DRMVectorSubtract(&self,&self,&u);
95 U1(e).x=7.0f; U2(e).y=16.0f; U3(e).z=26.0f;
96 expect_vec(e,self);
97
98/*_______________________VectorCrossProduct_______________________*/
100 U1(e).x=-4.0f; U2(e).y=4.0f; U3(e).z=0.0f;
101 expect_vec(e,r);
102
103 U1(self).x=9.0f; U2(self).y=18.0f; U3(self).z=27.0f;
104 D3DRMVectorCrossProduct(&self,&self,&u);
105 U1(e).x=-36.0f; U2(e).y=45.0f; U3(e).z=-18.0f;
106 expect_vec(e,self);
107
108/*_______________________VectorDotProduct__________________________*/
110 ok((mod == 16.0f), "Expected 16.0f, Got %f\n", mod);
111
112/*_______________________VectorModulus_____________________________*/
114 ok((mod == 3.0f), "Expected 3.0f, Got %f\n", mod);
115
116/*_______________________VectorNormalize___________________________*/
118 U1(e).x=2.0f/3.0f; U2(e).y=2.0f/3.0f; U3(e).z=1.0f/3.0f;
119 expect_vec(e,u);
120
121/* If u is the NULL vector, MSDN says that the return vector is NULL. In fact, the returned vector is (1,0,0). The following test case prove it. */
122
123 U1(casnul).x=0.0f; U2(casnul).y=0.0f; U3(casnul).z=0.0f;
124 D3DRMVectorNormalize(&casnul);
125 U1(e).x=1.0f; U2(e).y=0.0f; U3(e).z=0.0f;
126 expect_vec(e,casnul);
127
128/*____________________VectorReflect_________________________________*/
129 U1(ray).x=3.0f; U2(ray).y=-4.0f; U3(ray).z=5.0f;
130 U1(norm).x=1.0f; U2(norm).y=-2.0f; U3(norm).z=6.0f;
131 U1(e).x=79.0f; U2(e).y=-160.0f; U3(e).z=487.0f;
132 D3DRMVectorReflect(&r,&ray,&norm);
133 expect_vec(e,r);
134
135/*_______________________VectorRotate_______________________________*/
136 U1(w).x=3.0f; U2(w).y=4.0f; U3(w).z=0.0f;
137 U1(axis).x=0.0f; U2(axis).y=0.0f; U3(axis).z=1.0f;
138 theta=2.0f*PI/3.0f;
139 D3DRMVectorRotate(&r,&w,&axis,theta);
140 U1(e).x=-0.3f-0.4f*sqrtf(3.0f); U2(e).y=0.3f*sqrtf(3.0f)-0.4f; U3(e).z=0.0f;
141 expect_vec(e,r);
142
143/* The same formula gives D3DRMVectorRotate, for theta in [-PI/2;+PI/2] or not. The following test proves this fact.*/
144 theta=-PI/4.0f;
145 D3DRMVectorRotate(&r,&w,&axis,theta);
146 U1(e).x=1.4f/sqrtf(2.0f); U2(e).y=0.2f/sqrtf(2.0f); U3(e).z=0.0f;
147 expect_vec(e,r);
148
149 theta=PI/8.0f;
150 D3DRMVectorRotate(&self,&self,&axis,theta);
151 U1(e).x=0.989950; U2(e).y=0.141421f; U3(e).z=0.0f;
152 expect_vec(e,r);
153
154/*_______________________VectorScale__________________________*/
155 par=2.5f;
156 D3DRMVectorScale(&r,&v,par);
157 U1(e).x=10.0f; U2(e).y=10.0f; U3(e).z=0.0f;
158 expect_vec(e,r);
159
160 U1(self).x=9.0f; U2(self).y=18.0f; U3(self).z=27.0f;
161 D3DRMVectorScale(&self,&self,2);
162 U1(e).x=18.0f; U2(e).y=36.0f; U3(e).z=54.0f;
163 expect_vec(e,self);
164}
165
166static void MatrixTest(void)
167{
170
171 exp[0][0]=-49.0f; exp[0][1]=4.0f; exp[0][2]=22.0f; exp[0][3]=0.0f;
172 exp[1][0]=20.0f; exp[1][1]=-39.0f; exp[1][2]=20.0f; exp[1][3]=0.0f;
173 exp[2][0]=10.0f; exp[2][1]=28.0f; exp[2][2]=-25.0f; exp[2][3]=0.0f;
174 exp[3][0]=0.0f; exp[3][1]=0.0f; exp[3][2]=0.0f; exp[3][3]=1.0f;
175 q.s=1.0f; U1(q.v).x=2.0f; U2(q.v).y=3.0f; U3(q.v).z=4.0f;
176
179}
180
181static void QuaternionTest(void)
182{
183 D3DVECTOR axis;
184 D3DVALUE par,theta;
185 D3DRMQUATERNION q,q1,q1final,q2,q2final,r;
186
187/*_________________QuaternionFromRotation___________________*/
188 U1(axis).x=1.0f; U2(axis).y=1.0f; U3(axis).z=1.0f;
189 theta=2.0f*PI/3.0f;
190 D3DRMQuaternionFromRotation(&r,&axis,theta);
191 q.s=0.5f; U1(q.v).x=0.5f; U2(q.v).y=0.5f; U3(q.v).z=0.5f;
192 expect_quat(q,r);
193
194/*_________________QuaternionSlerp_________________________*/
195/* If the angle of the two quaternions is in ]PI/2;3PI/2[, QuaternionSlerp
196 * interpolates between the first quaternion and the opposite of the second one.
197 * The test proves this fact. */
198 par=0.31f;
199 q1.s=1.0f; U1(q1.v).x=2.0f; U2(q1.v).y=3.0f; U3(q1.v).z=50.0f;
200 q2.s=-4.0f; U1(q2.v).x=6.0f; U2(q2.v).y=7.0f; U3(q2.v).z=8.0f;
201/* The angle between q1 and q2 is in [-PI/2,PI/2]. So, one interpolates between q1 and q2. */
202 q.s = -0.55f; U1(q.v).x=3.24f; U2(q.v).y=4.24f; U3(q.v).z=36.98f;
203 D3DRMQuaternionSlerp(&r,&q1,&q2,par);
204 expect_quat(q,r);
205
206 q1.s=1.0f; U1(q1.v).x=2.0f; U2(q1.v).y=3.0f; U3(q1.v).z=50.0f;
207 q2.s=-94.0f; U1(q2.v).x=6.0f; U2(q2.v).y=7.0f; U3(q2.v).z=-8.0f;
208/* The angle between q1 and q2 is not in [-PI/2,PI/2]. So, one interpolates between q1 and -q2. */
209 q.s=29.83f; U1(q.v).x=-0.48f; U2(q.v).y=-0.10f; U3(q.v).z=36.98f;
210 D3DRMQuaternionSlerp(&r,&q1,&q2,par);
211 expect_quat(q,r);
212
213/* Test the spherical interpolation part */
214 q1.s=0.1f; U1(q1.v).x=0.2f; U2(q1.v).y=0.3f; U3(q1.v).z=0.4f;
215 q2.s=0.5f; U1(q2.v).x=0.6f; U2(q2.v).y=0.7f; U3(q2.v).z=0.8f;
216 q.s = 0.243943f; U1(q.v).x = 0.351172f; U2(q.v).y = 0.458401f; U3(q.v).z = 0.565629f;
217
218 q1final=q1;
219 q2final=q2;
220 D3DRMQuaternionSlerp(&r,&q1,&q2,par);
221 expect_quat(q,r);
222
223/* Test to show that the input quaternions are not changed */
224 expect_quat(q1,q1final);
225 expect_quat(q2,q2final);
226}
227
228static void ColorTest(void)
229{
230 D3DCOLOR color, expected_color, got_color;
232
233/*___________D3DRMCreateColorRGB_________________________*/
234 red=0.8f;
235 green=0.3f;
236 blue=0.55f;
237 expected_color=0xffcc4c8c;
239 ok((expected_color==got_color),"Expected color=%x, Got color=%x\n",expected_color,got_color);
240
241/*___________D3DRMCreateColorRGBA________________________*/
242 red=0.1f;
243 green=0.4f;
244 blue=0.7f;
245 alpha=0.58f;
246 expected_color=0x931966b2;
248 ok((expected_color==got_color),"Expected color=%x, Got color=%x\n",expected_color,got_color);
249
250/* if a component is <0 then, then one considers this component as 0. The following test proves this fact (test only with the red component). */
251 red=-0.88f;
252 green=0.4f;
253 blue=0.6f;
254 alpha=0.41f;
255 expected_color=0x68006699;
257 ok((expected_color==got_color),"Expected color=%x, Got color=%x\n",expected_color,got_color);
258
259/* if a component is >1 then, then one considers this component as 1. The following test proves this fact (test only with the red component). */
260 red=2.37f;
261 green=0.4f;
262 blue=0.6f;
263 alpha=0.41f;
264 expected_color=0x68ff6699;
266 ok((expected_color==got_color),"Expected color=%x, Got color=%x\n",expected_color,got_color);
267
268/*___________D3DRMColorGetAlpha_________________________*/
269 color=0x0e4921bf;
270 expected=14.0f/255.0f;
272 ok((fabs(expected-got)<admit_error),"Expected=%f, Got=%f\n",expected,got);
273
274/*___________D3DRMColorGetBlue__________________________*/
275 color=0xc82a1455;
276 expected=1.0f/3.0f;
278 ok((fabs(expected-got)<admit_error),"Expected=%f, Got=%f\n",expected,got);
279
280/*___________D3DRMColorGetGreen_________________________*/
281 color=0xad971203;
282 expected=6.0f/85.0f;
284 ok((fabs(expected-got)<admit_error),"Expected=%f, Got=%f\n",expected,got);
285
286/*___________D3DRMColorGetRed__________________________*/
287 color=0xb62d7a1c;
288 expected=3.0f/17.0f;
290 ok((fabs(expected-got)<admit_error),"Expected=%f, Got=%f\n",expected,got);
291}
292
294{
295 VectorTest();
296 MatrixTest();
298 ColorTest();
299}
_Tp _STLP_CALL norm(const complex< _Tp > &__z)
Definition: _complex.h:741
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define U3(x)
Definition: wordpad.c:47
#define U2(x)
Definition: wordpad.c:46
D3DVALUE D3DRMMATRIX4D[4][4]
Definition: d3drmdef.h:39
float D3DVALUE
Definition: d3dtypes.h:89
D3DCOLOR WINAPI D3DRMCreateColorRGB(D3DVALUE red, D3DVALUE green, D3DVALUE blue)
Definition: math.c:23
D3DVECTOR *WINAPI D3DRMVectorScale(D3DVECTOR *d, D3DVECTOR *s, D3DVALUE factor)
Definition: math.c:253
void WINAPI D3DRMMatrixFromQuaternion(D3DRMMATRIX4D m, D3DRMQUATERNION *q)
Definition: math.c:78
D3DVECTOR *WINAPI D3DRMVectorNormalize(D3DVECTOR *u)
Definition: math.c:196
D3DVALUE WINAPI D3DRMVectorModulus(D3DVECTOR *v)
Definition: math.c:188
D3DVECTOR *WINAPI D3DRMVectorAdd(D3DVECTOR *d, D3DVECTOR *s1, D3DVECTOR *s2)
Definition: math.c:141
D3DVECTOR *WINAPI D3DRMVectorCrossProduct(D3DVECTOR *d, D3DVECTOR *s1, D3DVECTOR *s2)
Definition: math.c:167
D3DVALUE WINAPI D3DRMColorGetRed(D3DCOLOR color)
Definition: math.c:56
D3DVECTOR *WINAPI D3DRMVectorReflect(D3DVECTOR *r, D3DVECTOR *ray, D3DVECTOR *norm)
Definition: math.c:223
D3DVECTOR *WINAPI D3DRMVectorSubtract(D3DVECTOR *d, D3DVECTOR *s1, D3DVECTOR *s2)
Definition: math.c:154
D3DVALUE WINAPI D3DRMColorGetBlue(D3DCOLOR color)
Definition: math.c:44
D3DRMQUATERNION *WINAPI D3DRMQuaternionFromRotation(D3DRMQUATERNION *q, D3DVECTOR *v, D3DVALUE theta)
Definition: math.c:104
D3DVALUE WINAPI D3DRMColorGetAlpha(D3DCOLOR color)
Definition: math.c:38
D3DRMQUATERNION *WINAPI D3DRMQuaternionSlerp(D3DRMQUATERNION *q, D3DRMQUATERNION *a, D3DRMQUATERNION *b, D3DVALUE alpha)
Definition: math.c:112
D3DVALUE WINAPI D3DRMVectorDotProduct(D3DVECTOR *s1, D3DVECTOR *s2)
Definition: math.c:180
D3DVALUE WINAPI D3DRMColorGetGreen(D3DCOLOR color)
Definition: math.c:50
D3DVECTOR *WINAPI D3DRMVectorRotate(D3DVECTOR *r, D3DVECTOR *v, D3DVECTOR *axis, D3DVALUE theta)
Definition: math.c:233
D3DCOLOR WINAPI D3DRMCreateColorRGBA(D3DVALUE red, D3DVALUE green, D3DVALUE blue, D3DVALUE alpha)
Definition: math.c:28
GLclampf green
Definition: gl.h:1740
const GLdouble * v
Definition: gl.h:2040
GLclampf GLclampf GLclampf alpha
Definition: gl.h:1740
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLclampf GLclampf blue
Definition: gl.h:1740
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLuint color
Definition: glext.h:6243
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
static int mod
Definition: i386-dis.c:1288
_Check_return_ _CRT_JIT_INTRINSIC double __cdecl fabs(_In_ double x)
Definition: fabs.c:17
#define e
Definition: ke_i.h:82
#define red
Definition: linetest.c:67
BOOL expected
Definition: store.c:2063
static const MAT2 mat
Definition: font.c:66
DWORD exp
Definition: msg.c:16058
#define sqrtf(x)
Definition: mymath.h:59
#define U1(x)
Definition: test.h:199
D3DVALUE s
Definition: d3drmdef.h:42
D3DVECTOR v
Definition: d3drmdef.h:43
#define expect_quat(expectedquat, gotquat)
Definition: vector.c:55
#define expect_mat(expectedmat, gotmat)
Definition: vector.c:29
#define admit_error
Definition: vector.c:27
#define expect_vec(expectedvec, gotvec)
Definition: vector.c:64
static void MatrixTest(void)
Definition: vector.c:166
#define PI
Definition: vector.c:26
static void QuaternionTest(void)
Definition: vector.c:181
static void ColorTest(void)
Definition: vector.c:228
static void VectorTest(void)
Definition: vector.c:69