ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

math.c
Go to the documentation of this file.
00001 /*
00002  * Mathematical operations specific to D3DX9.
00003  *
00004  * Copyright (C) 2008 David Adam
00005  * Copyright (C) 2008 Luis Busquets
00006  * Copyright (C) 2008 Jérôme Gardou
00007  * Copyright (C) 2008 Philip Nilsson
00008  * Copyright (C) 2008 Henri Verbeet
00009  *
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or (at your option) any later version.
00014  *
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00023  */
00024 
00025 #define NONAMELESSUNION
00026 
00027 #include "config.h"
00028 #include "windef.h"
00029 #include "wingdi.h"
00030 #include "d3dx9_36_private.h"
00031 
00032 #include "wine/debug.h"
00033 
00034 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
00035 
00036 static const ID3DXMatrixStackVtbl ID3DXMatrixStack_Vtbl;
00037 
00038 /*_________________D3DXColor____________________*/
00039 
00040 D3DXCOLOR* WINAPI D3DXColorAdjustContrast(D3DXCOLOR *pout, CONST D3DXCOLOR *pc, FLOAT s)
00041 {
00042     pout->r = 0.5f + s * (pc->r - 0.5f);
00043     pout->g = 0.5f + s * (pc->g - 0.5f);
00044     pout->b = 0.5f + s * (pc->b - 0.5f);
00045     pout->a = pc->a;
00046     return pout;
00047 }
00048 
00049 D3DXCOLOR* WINAPI D3DXColorAdjustSaturation(D3DXCOLOR *pout, CONST D3DXCOLOR *pc, FLOAT s)
00050 {
00051     FLOAT grey;
00052 
00053     grey = pc->r * 0.2125f + pc->g * 0.7154f + pc->b * 0.0721f;
00054     pout->r = grey + s * (pc->r - grey);
00055     pout->g = grey + s * (pc->g - grey);
00056     pout->b = grey + s * (pc->b - grey);
00057     pout->a = pc->a;
00058     return pout;
00059 }
00060 
00061 /*_________________Misc__________________________*/
00062 
00063 FLOAT WINAPI D3DXFresnelTerm(FLOAT costheta, FLOAT refractionindex)
00064 {
00065     FLOAT a, d, g, result;
00066 
00067     g = sqrt(refractionindex * refractionindex + costheta * costheta - 1.0f);
00068     a = g + costheta;
00069     d = g - costheta;
00070     result = ( costheta * a - 1.0f ) * ( costheta * a - 1.0f ) / ( ( costheta * d + 1.0f ) * ( costheta * d + 1.0f ) ) + 1.0f;
00071     result = result * 0.5f * d * d / ( a * a );
00072     return result;
00073 }
00074 
00075 /*_________________D3DXMatrix____________________*/
00076 
00077 D3DXMATRIX* WINAPI D3DXMatrixAffineTransformation(D3DXMATRIX *pout, FLOAT scaling, CONST D3DXVECTOR3 *rotationcenter, CONST D3DXQUATERNION *rotation, CONST D3DXVECTOR3 *translation)
00078 {
00079     D3DXMATRIX m1, m2, m3, m4, m5;
00080 
00081     D3DXMatrixScaling(&m1, scaling, scaling, scaling);
00082 
00083     if ( !rotationcenter )
00084     {
00085         D3DXMatrixIdentity(&m2);
00086         D3DXMatrixIdentity(&m4);
00087     }
00088     else
00089     {
00090         D3DXMatrixTranslation(&m2, -rotationcenter->x, -rotationcenter->y, -rotationcenter->z);
00091         D3DXMatrixTranslation(&m4, rotationcenter->x, rotationcenter->y, rotationcenter->z);
00092     }
00093 
00094     if ( !rotation ) D3DXMatrixIdentity(&m3);
00095     else D3DXMatrixRotationQuaternion(&m3, rotation);
00096 
00097     if ( !translation ) D3DXMatrixIdentity(&m5);
00098     else D3DXMatrixTranslation(&m5, translation->x, translation->y, translation->z);
00099 
00100     D3DXMatrixMultiply(&m1, &m1, &m2);
00101     D3DXMatrixMultiply(&m1, &m1, &m3);
00102     D3DXMatrixMultiply(&m1, &m1, &m4);
00103     D3DXMatrixMultiply(pout, &m1, &m5);
00104     return pout;
00105 }
00106 
00107 D3DXMATRIX* WINAPI D3DXMatrixAffineTransformation2D(D3DXMATRIX *pout, FLOAT scaling, CONST D3DXVECTOR2 *protationcenter, FLOAT rotation, CONST D3DXVECTOR2 *ptranslation)
00108 {
00109     D3DXMATRIX m1, m2, m3, m4, m5;
00110     D3DXQUATERNION rot;
00111     D3DXVECTOR3 rot_center, trans;
00112 
00113     rot.w=cos(rotation/2.0f);
00114     rot.x=0.0f;
00115     rot.y=0.0f;
00116     rot.z=sin(rotation/2.0f);
00117 
00118     if ( protationcenter )
00119     {
00120         rot_center.x=protationcenter->x;
00121         rot_center.y=protationcenter->y;
00122         rot_center.z=0.0f;
00123     }
00124     else
00125     {
00126         rot_center.x=0.0f;
00127         rot_center.y=0.0f;
00128         rot_center.z=0.0f;
00129     }
00130 
00131     if ( ptranslation )
00132     {
00133         trans.x=ptranslation->x;
00134         trans.y=ptranslation->y;
00135         trans.z=0.0f;
00136     }
00137     else
00138     {
00139         trans.x=0.0f;
00140         trans.y=0.0f;
00141         trans.z=0.0f;
00142     }
00143 
00144     D3DXMatrixScaling(&m1, scaling, scaling, 1.0f);
00145     D3DXMatrixTranslation(&m2, -rot_center.x, -rot_center.y, -rot_center.z);
00146     D3DXMatrixTranslation(&m4, rot_center.x, rot_center.y, rot_center.z);
00147     D3DXMatrixRotationQuaternion(&m3, &rot);
00148     D3DXMatrixTranslation(&m5, trans.x, trans.y, trans.z);
00149 
00150     D3DXMatrixMultiply(&m1, &m1, &m2);
00151     D3DXMatrixMultiply(&m1, &m1, &m3);
00152     D3DXMatrixMultiply(&m1, &m1, &m4);
00153     D3DXMatrixMultiply(pout, &m1, &m5);
00154 
00155     return pout;
00156 }
00157 
00158 HRESULT WINAPI D3DXMatrixDecompose(D3DXVECTOR3 *poutscale, D3DXQUATERNION *poutrotation, D3DXVECTOR3 *pouttranslation, CONST D3DXMATRIX *pm)
00159 {
00160     D3DXMATRIX normalized;
00161     D3DXVECTOR3 vec;
00162 
00163     /*Compute the scaling part.*/
00164     vec.x=pm->u.m[0][0];
00165     vec.y=pm->u.m[0][1];
00166     vec.z=pm->u.m[0][2];
00167     poutscale->x=D3DXVec3Length(&vec);
00168 
00169     vec.x=pm->u.m[1][0];
00170     vec.y=pm->u.m[1][1];
00171     vec.z=pm->u.m[1][2];
00172     poutscale->y=D3DXVec3Length(&vec);
00173 
00174     vec.x=pm->u.m[2][0];
00175     vec.y=pm->u.m[2][1];
00176     vec.z=pm->u.m[2][2];
00177     poutscale->z=D3DXVec3Length(&vec);
00178 
00179     /*Compute the translation part.*/
00180     pouttranslation->x=pm->u.m[3][0];
00181     pouttranslation->y=pm->u.m[3][1];
00182     pouttranslation->z=pm->u.m[3][2];
00183 
00184     /*Let's calculate the rotation now*/
00185     if ( (poutscale->x == 0.0f) || (poutscale->y == 0.0f) || (poutscale->z == 0.0f) ) return D3DERR_INVALIDCALL;
00186 
00187     normalized.u.m[0][0]=pm->u.m[0][0]/poutscale->x;
00188     normalized.u.m[0][1]=pm->u.m[0][1]/poutscale->x;
00189     normalized.u.m[0][2]=pm->u.m[0][2]/poutscale->x;
00190     normalized.u.m[1][0]=pm->u.m[1][0]/poutscale->y;
00191     normalized.u.m[1][1]=pm->u.m[1][1]/poutscale->y;
00192     normalized.u.m[1][2]=pm->u.m[1][2]/poutscale->y;
00193     normalized.u.m[2][0]=pm->u.m[2][0]/poutscale->z;
00194     normalized.u.m[2][1]=pm->u.m[2][1]/poutscale->z;
00195     normalized.u.m[2][2]=pm->u.m[2][2]/poutscale->z;
00196 
00197     D3DXQuaternionRotationMatrix(poutrotation,&normalized);
00198     return S_OK;
00199 }
00200 
00201 FLOAT WINAPI D3DXMatrixDeterminant(CONST D3DXMATRIX *pm)
00202 {
00203     D3DXVECTOR4 minor, v1, v2, v3;
00204     FLOAT det;
00205 
00206     v1.x = pm->u.m[0][0]; v1.y = pm->u.m[1][0]; v1.z = pm->u.m[2][0]; v1.w = pm->u.m[3][0];
00207     v2.x = pm->u.m[0][1]; v2.y = pm->u.m[1][1]; v2.z = pm->u.m[2][1]; v2.w = pm->u.m[3][1];
00208     v3.x = pm->u.m[0][2]; v3.y = pm->u.m[1][2]; v3.z = pm->u.m[2][2]; v3.w = pm->u.m[3][2];
00209     D3DXVec4Cross(&minor, &v1, &v2, &v3);
00210     det =  - (pm->u.m[0][3] * minor.x + pm->u.m[1][3] * minor.y + pm->u.m[2][3] * minor.z + pm->u.m[3][3] * minor.w);
00211     return det;
00212 }
00213 
00214 D3DXMATRIX* WINAPI D3DXMatrixInverse(D3DXMATRIX *pout, FLOAT *pdeterminant, CONST D3DXMATRIX *pm)
00215 {
00216     int a, i, j;
00217     D3DXMATRIX out;
00218     D3DXVECTOR4 v, vec[3];
00219     FLOAT det;
00220 
00221     det = D3DXMatrixDeterminant(pm);
00222     if ( !det ) return NULL;
00223     if ( pdeterminant ) *pdeterminant = det;
00224     for (i=0; i<4; i++)
00225     {
00226         for (j=0; j<4; j++)
00227         {
00228             if (j != i )
00229             {
00230                 a = j;
00231                 if ( j > i ) a = a-1;
00232                 vec[a].x = pm->u.m[j][0];
00233                 vec[a].y = pm->u.m[j][1];
00234                 vec[a].z = pm->u.m[j][2];
00235                 vec[a].w = pm->u.m[j][3];
00236             }
00237         }
00238     D3DXVec4Cross(&v, &vec[0], &vec[1], &vec[2]);
00239     out.u.m[0][i] = pow(-1.0f, i) * v.x / det;
00240     out.u.m[1][i] = pow(-1.0f, i) * v.y / det;
00241     out.u.m[2][i] = pow(-1.0f, i) * v.z / det;
00242     out.u.m[3][i] = pow(-1.0f, i) * v.w / det;
00243    }
00244 
00245    *pout = out;
00246    return pout;
00247 }
00248 
00249 D3DXMATRIX* WINAPI D3DXMatrixLookAtLH(D3DXMATRIX *pout, CONST D3DXVECTOR3 *peye, CONST D3DXVECTOR3 *pat, CONST D3DXVECTOR3 *pup)
00250 {
00251     D3DXVECTOR3 right, rightn, up, upn, vec, vec2;
00252 
00253     D3DXVec3Subtract(&vec2, pat, peye);
00254     D3DXVec3Normalize(&vec, &vec2);
00255     D3DXVec3Cross(&right, pup, &vec);
00256     D3DXVec3Cross(&up, &vec, &right);
00257     D3DXVec3Normalize(&rightn, &right);
00258     D3DXVec3Normalize(&upn, &up);
00259     pout->u.m[0][0] = rightn.x;
00260     pout->u.m[1][0] = rightn.y;
00261     pout->u.m[2][0] = rightn.z;
00262     pout->u.m[3][0] = -D3DXVec3Dot(&rightn,peye);
00263     pout->u.m[0][1] = upn.x;
00264     pout->u.m[1][1] = upn.y;
00265     pout->u.m[2][1] = upn.z;
00266     pout->u.m[3][1] = -D3DXVec3Dot(&upn, peye);
00267     pout->u.m[0][2] = vec.x;
00268     pout->u.m[1][2] = vec.y;
00269     pout->u.m[2][2] = vec.z;
00270     pout->u.m[3][2] = -D3DXVec3Dot(&vec, peye);
00271     pout->u.m[0][3] = 0.0f;
00272     pout->u.m[1][3] = 0.0f;
00273     pout->u.m[2][3] = 0.0f;
00274     pout->u.m[3][3] = 1.0f;
00275     return pout;
00276 }
00277 
00278 D3DXMATRIX* WINAPI D3DXMatrixLookAtRH(D3DXMATRIX *pout, CONST D3DXVECTOR3 *peye, CONST D3DXVECTOR3 *pat, CONST D3DXVECTOR3 *pup)
00279 {
00280     D3DXVECTOR3 right, rightn, up, upn, vec, vec2;
00281 
00282     D3DXVec3Subtract(&vec2, pat, peye);
00283     D3DXVec3Normalize(&vec, &vec2);
00284     D3DXVec3Cross(&right, pup, &vec);
00285     D3DXVec3Cross(&up, &vec, &right);
00286     D3DXVec3Normalize(&rightn, &right);
00287     D3DXVec3Normalize(&upn, &up);
00288     pout->u.m[0][0] = -rightn.x;
00289     pout->u.m[1][0] = -rightn.y;
00290     pout->u.m[2][0] = -rightn.z;
00291     pout->u.m[3][0] = D3DXVec3Dot(&rightn,peye);
00292     pout->u.m[0][1] = upn.x;
00293     pout->u.m[1][1] = upn.y;
00294     pout->u.m[2][1] = upn.z;
00295     pout->u.m[3][1] = -D3DXVec3Dot(&upn, peye);
00296     pout->u.m[0][2] = -vec.x;
00297     pout->u.m[1][2] = -vec.y;
00298     pout->u.m[2][2] = -vec.z;
00299     pout->u.m[3][2] = D3DXVec3Dot(&vec, peye);
00300     pout->u.m[0][3] = 0.0f;
00301     pout->u.m[1][3] = 0.0f;
00302     pout->u.m[2][3] = 0.0f;
00303     pout->u.m[3][3] = 1.0f;
00304     return pout;
00305 }
00306 
00307 D3DXMATRIX* WINAPI D3DXMatrixMultiply(D3DXMATRIX *pout, CONST D3DXMATRIX *pm1, CONST D3DXMATRIX *pm2)
00308 {
00309     D3DXMATRIX out;
00310     int i,j;
00311 
00312     for (i=0; i<4; i++)
00313     {
00314         for (j=0; j<4; j++)
00315         {
00316             out.u.m[i][j] = pm1->u.m[i][0] * pm2->u.m[0][j] + pm1->u.m[i][1] * pm2->u.m[1][j] + pm1->u.m[i][2] * pm2->u.m[2][j] + pm1->u.m[i][3] * pm2->u.m[3][j];
00317         }
00318     }
00319 
00320     *pout = out;
00321     return pout;
00322 }
00323 
00324 D3DXMATRIX* WINAPI D3DXMatrixMultiplyTranspose(D3DXMATRIX *pout, CONST D3DXMATRIX *pm1, CONST D3DXMATRIX *pm2)
00325 {
00326     D3DXMatrixMultiply(pout, pm1, pm2);
00327     D3DXMatrixTranspose(pout, pout);
00328     return pout;
00329 }
00330 
00331 D3DXMATRIX* WINAPI D3DXMatrixOrthoLH(D3DXMATRIX *pout, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf)
00332 {
00333     D3DXMatrixIdentity(pout);
00334     pout->u.m[0][0] = 2.0f / w;
00335     pout->u.m[1][1] = 2.0f / h;
00336     pout->u.m[2][2] = 1.0f / (zf - zn);
00337     pout->u.m[3][2] = zn / (zn - zf);
00338     return pout;
00339 }
00340 
00341 D3DXMATRIX* WINAPI D3DXMatrixOrthoOffCenterLH(D3DXMATRIX *pout, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf)
00342 {
00343     D3DXMatrixIdentity(pout);
00344     pout->u.m[0][0] = 2.0f / (r - l);
00345     pout->u.m[1][1] = 2.0f / (t - b);
00346     pout->u.m[2][2] = 1.0f / (zf -zn);
00347     pout->u.m[3][0] = -1.0f -2.0f *l / (r - l);
00348     pout->u.m[3][1] = 1.0f + 2.0f * t / (b - t);
00349     pout->u.m[3][2] = zn / (zn -zf);
00350     return pout;
00351 }
00352 
00353 D3DXMATRIX* WINAPI D3DXMatrixOrthoOffCenterRH(D3DXMATRIX *pout, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf)
00354 {
00355     D3DXMatrixIdentity(pout);
00356     pout->u.m[0][0] = 2.0f / (r - l);
00357     pout->u.m[1][1] = 2.0f / (t - b);
00358     pout->u.m[2][2] = 1.0f / (zn -zf);
00359     pout->u.m[3][0] = -1.0f -2.0f *l / (r - l);
00360     pout->u.m[3][1] = 1.0f + 2.0f * t / (b - t);
00361     pout->u.m[3][2] = zn / (zn -zf);
00362     return pout;
00363 }
00364 
00365 D3DXMATRIX* WINAPI D3DXMatrixOrthoRH(D3DXMATRIX *pout, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf)
00366 {
00367     D3DXMatrixIdentity(pout);
00368     pout->u.m[0][0] = 2.0f / w;
00369     pout->u.m[1][1] = 2.0f / h;
00370     pout->u.m[2][2] = 1.0f / (zn - zf);
00371     pout->u.m[3][2] = zn / (zn - zf);
00372     return pout;
00373 }
00374 
00375 D3DXMATRIX* WINAPI D3DXMatrixPerspectiveFovLH(D3DXMATRIX *pout, FLOAT fovy, FLOAT aspect, FLOAT zn, FLOAT zf)
00376 {
00377     D3DXMatrixIdentity(pout);
00378     pout->u.m[0][0] = 1.0f / (aspect * tan(fovy/2.0f));
00379     pout->u.m[1][1] = 1.0f / tan(fovy/2.0f);
00380     pout->u.m[2][2] = zf / (zf - zn);
00381     pout->u.m[2][3] = 1.0f;
00382     pout->u.m[3][2] = (zf * zn) / (zn - zf);
00383     pout->u.m[3][3] = 0.0f;
00384     return pout;
00385 }
00386 
00387 D3DXMATRIX* WINAPI D3DXMatrixPerspectiveFovRH(D3DXMATRIX *pout, FLOAT fovy, FLOAT aspect, FLOAT zn, FLOAT zf)
00388 {
00389     D3DXMatrixIdentity(pout);
00390     pout->u.m[0][0] = 1.0f / (aspect * tan(fovy/2.0f));
00391     pout->u.m[1][1] = 1.0f / tan(fovy/2.0f);
00392     pout->u.m[2][2] = zf / (zn - zf);
00393     pout->u.m[2][3] = -1.0f;
00394     pout->u.m[3][2] = (zf * zn) / (zn - zf);
00395     pout->u.m[3][3] = 0.0f;
00396     return pout;
00397 }
00398 
00399 D3DXMATRIX* WINAPI D3DXMatrixPerspectiveLH(D3DXMATRIX *pout, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf)
00400 {
00401     D3DXMatrixIdentity(pout);
00402     pout->u.m[0][0] = 2.0f * zn / w;
00403     pout->u.m[1][1] = 2.0f * zn / h;
00404     pout->u.m[2][2] = zf / (zf - zn);
00405     pout->u.m[3][2] = (zn * zf) / (zn - zf);
00406     pout->u.m[2][3] = 1.0f;
00407     pout->u.m[3][3] = 0.0f;
00408     return pout;
00409 }
00410 
00411 D3DXMATRIX* WINAPI D3DXMatrixPerspectiveOffCenterLH(D3DXMATRIX *pout, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf)
00412 {
00413     D3DXMatrixIdentity(pout);
00414     pout->u.m[0][0] = 2.0f * zn / (r - l);
00415     pout->u.m[1][1] = -2.0f * zn / (b - t);
00416     pout->u.m[2][0] = -1.0f - 2.0f * l / (r - l);
00417     pout->u.m[2][1] = 1.0f + 2.0f * t / (b - t);
00418     pout->u.m[2][2] = - zf / (zn - zf);
00419     pout->u.m[3][2] = (zn * zf) / (zn -zf);
00420     pout->u.m[2][3] = 1.0f;
00421     pout->u.m[3][3] = 0.0f;
00422     return pout;
00423 }
00424 
00425 D3DXMATRIX* WINAPI D3DXMatrixPerspectiveOffCenterRH(D3DXMATRIX *pout, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf)
00426 {
00427     D3DXMatrixIdentity(pout);
00428     pout->u.m[0][0] = 2.0f * zn / (r - l);
00429     pout->u.m[1][1] = -2.0f * zn / (b - t);
00430     pout->u.m[2][0] = 1.0f + 2.0f * l / (r - l);
00431     pout->u.m[2][1] = -1.0f -2.0f * t / (b - t);
00432     pout->u.m[2][2] = zf / (zn - zf);
00433     pout->u.m[3][2] = (zn * zf) / (zn -zf);
00434     pout->u.m[2][3] = -1.0f;
00435     pout->u.m[3][3] = 0.0f;
00436     return pout;
00437 }
00438 
00439 D3DXMATRIX* WINAPI D3DXMatrixPerspectiveRH(D3DXMATRIX *pout, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf)
00440 {
00441     D3DXMatrixIdentity(pout);
00442     pout->u.m[0][0] = 2.0f * zn / w;
00443     pout->u.m[1][1] = 2.0f * zn / h;
00444     pout->u.m[2][2] = zf / (zn - zf);
00445     pout->u.m[3][2] = (zn * zf) / (zn - zf);
00446     pout->u.m[2][3] = -1.0f;
00447     pout->u.m[3][3] = 0.0f;
00448     return pout;
00449 }
00450 
00451 D3DXMATRIX* WINAPI D3DXMatrixReflect(D3DXMATRIX *pout, CONST D3DXPLANE *pplane)
00452 {
00453     D3DXPLANE Nplane;
00454 
00455     D3DXPlaneNormalize(&Nplane, pplane);
00456     D3DXMatrixIdentity(pout);
00457     pout->u.m[0][0] = 1.0f - 2.0f * Nplane.a * Nplane.a;
00458     pout->u.m[0][1] = -2.0f * Nplane.a * Nplane.b;
00459     pout->u.m[0][2] = -2.0f * Nplane.a * Nplane.c;
00460     pout->u.m[1][0] = -2.0f * Nplane.a * Nplane.b;
00461     pout->u.m[1][1] = 1.0f - 2.0f * Nplane.b * Nplane.b;
00462     pout->u.m[1][2] = -2.0f * Nplane.b * Nplane.c;
00463     pout->u.m[2][0] = -2.0f * Nplane.c * Nplane.a;
00464     pout->u.m[2][1] = -2.0f * Nplane.c * Nplane.b;
00465     pout->u.m[2][2] = 1.0f - 2.0f * Nplane.c * Nplane.c;
00466     pout->u.m[3][0] = -2.0f * Nplane.d * Nplane.a;
00467     pout->u.m[3][1] = -2.0f * Nplane.d * Nplane.b;
00468     pout->u.m[3][2] = -2.0f * Nplane.d * Nplane.c;
00469     return pout;
00470 }
00471 
00472 D3DXMATRIX* WINAPI D3DXMatrixRotationAxis(D3DXMATRIX *pout, CONST D3DXVECTOR3 *pv, FLOAT angle)
00473 {
00474     D3DXVECTOR3 v;
00475 
00476     D3DXVec3Normalize(&v,pv);
00477     D3DXMatrixIdentity(pout);
00478     pout->u.m[0][0] = (1.0f - cos(angle)) * v.x * v.x + cos(angle);
00479     pout->u.m[1][0] = (1.0f - cos(angle)) * v.x * v.y - sin(angle) * v.z;
00480     pout->u.m[2][0] = (1.0f - cos(angle)) * v.x * v.z + sin(angle) * v.y;
00481     pout->u.m[0][1] = (1.0f - cos(angle)) * v.y * v.x + sin(angle) * v.z;
00482     pout->u.m[1][1] = (1.0f - cos(angle)) * v.y * v.y + cos(angle);
00483     pout->u.m[2][1] = (1.0f - cos(angle)) * v.y * v.z - sin(angle) * v.x;
00484     pout->u.m[0][2] = (1.0f - cos(angle)) * v.z * v.x - sin(angle) * v.y;
00485     pout->u.m[1][2] = (1.0f - cos(angle)) * v.z * v.y + sin(angle) * v.x;
00486     pout->u.m[2][2] = (1.0f - cos(angle)) * v.z * v.z + cos(angle);
00487     return pout;
00488 }
00489 
00490 D3DXMATRIX* WINAPI D3DXMatrixRotationQuaternion(D3DXMATRIX *pout, CONST D3DXQUATERNION *pq)
00491 {
00492     D3DXMatrixIdentity(pout);
00493     pout->u.m[0][0] = 1.0f - 2.0f * (pq->y * pq->y + pq->z * pq->z);
00494     pout->u.m[0][1] = 2.0f * (pq->x *pq->y + pq->z * pq->w);
00495     pout->u.m[0][2] = 2.0f * (pq->x * pq->z - pq->y * pq->w);
00496     pout->u.m[1][0] = 2.0f * (pq->x * pq->y - pq->z * pq->w);
00497     pout->u.m[1][1] = 1.0f - 2.0f * (pq->x * pq->x + pq->z * pq->z);
00498     pout->u.m[1][2] = 2.0f * (pq->y *pq->z + pq->x *pq->w);
00499     pout->u.m[2][0] = 2.0f * (pq->x * pq->z + pq->y * pq->w);
00500     pout->u.m[2][1] = 2.0f * (pq->y *pq->z - pq->x *pq->w);
00501     pout->u.m[2][2] = 1.0f - 2.0f * (pq->x * pq->x + pq->y * pq->y);
00502     return pout;
00503 }
00504 
00505 D3DXMATRIX* WINAPI D3DXMatrixRotationX(D3DXMATRIX *pout, FLOAT angle)
00506 {
00507     D3DXMatrixIdentity(pout);
00508     pout->u.m[1][1] = cos(angle);
00509     pout->u.m[2][2] = cos(angle);
00510     pout->u.m[1][2] = sin(angle);
00511     pout->u.m[2][1] = -sin(angle);
00512     return pout;
00513 }
00514 
00515 D3DXMATRIX* WINAPI D3DXMatrixRotationY(D3DXMATRIX *pout, FLOAT angle)
00516 {
00517     D3DXMatrixIdentity(pout);
00518     pout->u.m[0][0] = cos(angle);
00519     pout->u.m[2][2] = cos(angle);
00520     pout->u.m[0][2] = -sin(angle);
00521     pout->u.m[2][0] = sin(angle);
00522     return pout;
00523 }
00524 
00525 D3DXMATRIX* WINAPI D3DXMatrixRotationYawPitchRoll(D3DXMATRIX *pout, FLOAT yaw, FLOAT pitch, FLOAT roll)
00526 {
00527     D3DXMATRIX m;
00528 
00529     D3DXMatrixIdentity(pout);
00530     D3DXMatrixRotationZ(&m, roll);
00531     D3DXMatrixMultiply(pout, pout, &m);
00532     D3DXMatrixRotationX(&m, pitch);
00533     D3DXMatrixMultiply(pout, pout, &m);
00534     D3DXMatrixRotationY(&m, yaw);
00535     D3DXMatrixMultiply(pout, pout, &m);
00536     return pout;
00537 }
00538 D3DXMATRIX* WINAPI D3DXMatrixRotationZ(D3DXMATRIX *pout, FLOAT angle)
00539 {
00540     D3DXMatrixIdentity(pout);
00541     pout->u.m[0][0] = cos(angle);
00542     pout->u.m[1][1] = cos(angle);
00543     pout->u.m[0][1] = sin(angle);
00544     pout->u.m[1][0] = -sin(angle);
00545     return pout;
00546 }
00547 
00548 D3DXMATRIX* WINAPI D3DXMatrixScaling(D3DXMATRIX *pout, FLOAT sx, FLOAT sy, FLOAT sz)
00549 {
00550     D3DXMatrixIdentity(pout);
00551     pout->u.m[0][0] = sx;
00552     pout->u.m[1][1] = sy;
00553     pout->u.m[2][2] = sz;
00554     return pout;
00555 }
00556 
00557 D3DXMATRIX* WINAPI D3DXMatrixShadow(D3DXMATRIX *pout, CONST D3DXVECTOR4 *plight, CONST D3DXPLANE *pplane)
00558 {
00559     D3DXPLANE Nplane;
00560     FLOAT dot;
00561 
00562     D3DXPlaneNormalize(&Nplane, pplane);
00563     dot = D3DXPlaneDot(&Nplane, plight);
00564     pout->u.m[0][0] = dot - Nplane.a * plight->x;
00565     pout->u.m[0][1] = -Nplane.a * plight->y;
00566     pout->u.m[0][2] = -Nplane.a * plight->z;
00567     pout->u.m[0][3] = -Nplane.a * plight->w;
00568     pout->u.m[1][0] = -Nplane.b * plight->x;
00569     pout->u.m[1][1] = dot - Nplane.b * plight->y;
00570     pout->u.m[1][2] = -Nplane.b * plight->z;
00571     pout->u.m[1][3] = -Nplane.b * plight->w;
00572     pout->u.m[2][0] = -Nplane.c * plight->x;
00573     pout->u.m[2][1] = -Nplane.c * plight->y;
00574     pout->u.m[2][2] = dot - Nplane.c * plight->z;
00575     pout->u.m[2][3] = -Nplane.c * plight->w;
00576     pout->u.m[3][0] = -Nplane.d * plight->x;
00577     pout->u.m[3][1] = -Nplane.d * plight->y;
00578     pout->u.m[3][2] = -Nplane.d * plight->z;
00579     pout->u.m[3][3] = dot - Nplane.d * plight->w;
00580     return pout;
00581 }
00582 
00583 D3DXMATRIX* WINAPI D3DXMatrixTransformation(D3DXMATRIX *pout, CONST D3DXVECTOR3 *pscalingcenter, CONST D3DXQUATERNION *pscalingrotation, CONST D3DXVECTOR3 *pscaling, CONST D3DXVECTOR3 *protationcenter, CONST D3DXQUATERNION *protation, CONST D3DXVECTOR3 *ptranslation)
00584 {
00585     D3DXMATRIX m1, m2, m3, m4, m5, m6, m7;
00586     D3DXQUATERNION prc;
00587     D3DXVECTOR3 psc, pt;
00588 
00589     if ( !pscalingcenter )
00590     {
00591         psc.x = 0.0f;
00592         psc.y = 0.0f;
00593         psc.z = 0.0f;
00594     }
00595     else
00596     {
00597         psc.x = pscalingcenter->x;
00598         psc.y = pscalingcenter->y;
00599         psc.z = pscalingcenter->z;
00600     }
00601 
00602     if ( !protationcenter )
00603     {
00604         prc.x = 0.0f;
00605         prc.y = 0.0f;
00606         prc.z = 0.0f;
00607     }
00608     else
00609     {
00610         prc.x = protationcenter->x;
00611         prc.y = protationcenter->y;
00612         prc.z = protationcenter->z;
00613     }
00614 
00615     if ( !ptranslation )
00616     {
00617         pt.x = 0.0f;
00618         pt.y = 0.0f;
00619         pt.z = 0.0f;
00620     }
00621     else
00622     {
00623         pt.x = ptranslation->x;
00624         pt.y = ptranslation->y;
00625         pt.z = ptranslation->z;
00626     }
00627 
00628     D3DXMatrixTranslation(&m1, -psc.x, -psc.y, -psc.z);
00629 
00630     if ( !pscalingrotation )
00631     {
00632         D3DXMatrixIdentity(&m2);
00633         D3DXMatrixIdentity(&m4);
00634     }
00635     else
00636     {
00637         D3DXMatrixRotationQuaternion(&m4, pscalingrotation);
00638         D3DXMatrixInverse(&m2, NULL, &m4);
00639     }
00640 
00641     if ( !pscaling ) D3DXMatrixIdentity(&m3);
00642     else D3DXMatrixScaling(&m3, pscaling->x, pscaling->y, pscaling->z);
00643 
00644     if ( !protation ) D3DXMatrixIdentity(&m6);
00645     else D3DXMatrixRotationQuaternion(&m6, protation);
00646 
00647     D3DXMatrixTranslation(&m5, psc.x - prc.x,  psc.y - prc.y,  psc.z - prc.z);
00648     D3DXMatrixTranslation(&m7, prc.x + pt.x, prc.y + pt.y, prc.z + pt.z);
00649     D3DXMatrixMultiply(&m1, &m1, &m2);
00650     D3DXMatrixMultiply(&m1, &m1, &m3);
00651     D3DXMatrixMultiply(&m1, &m1, &m4);
00652     D3DXMatrixMultiply(&m1, &m1, &m5);
00653     D3DXMatrixMultiply(&m1, &m1, &m6);
00654     D3DXMatrixMultiply(pout, &m1, &m7);
00655     return pout;
00656 }
00657 D3DXMATRIX* WINAPI D3DXMatrixTransformation2D(D3DXMATRIX *pout, CONST D3DXVECTOR2 *pscalingcenter, FLOAT scalingrotation, CONST D3DXVECTOR2 *pscaling, CONST D3DXVECTOR2 *protationcenter, FLOAT rotation, CONST D3DXVECTOR2 *ptranslation)
00658 {
00659     D3DXQUATERNION rot, sca_rot;
00660     D3DXVECTOR3 rot_center, sca, sca_center, trans;
00661 
00662     if ( pscalingcenter )
00663     {
00664         sca_center.x=pscalingcenter->x;
00665         sca_center.y=pscalingcenter->y;
00666         sca_center.z=0.0f;
00667     }
00668     else
00669     {
00670         sca_center.x=0.0f;
00671         sca_center.y=0.0f;
00672         sca_center.z=0.0f;
00673     }
00674 
00675     if ( pscaling )
00676     {
00677         sca.x=pscaling->x;
00678         sca.y=pscaling->y;
00679         sca.z=1.0f;
00680     }
00681     else
00682     {
00683         sca.x=1.0f;
00684         sca.y=1.0f;
00685         sca.z=1.0f;
00686     }
00687 
00688     if ( protationcenter )
00689     {
00690         rot_center.x=protationcenter->x;
00691         rot_center.y=protationcenter->y;
00692         rot_center.z=0.0f;
00693     }
00694     else
00695     {
00696         rot_center.x=0.0f;
00697         rot_center.y=0.0f;
00698         rot_center.z=0.0f;
00699     }
00700 
00701     if ( ptranslation )
00702     {
00703         trans.x=ptranslation->x;
00704         trans.y=ptranslation->y;
00705         trans.z=0.0f;
00706     }
00707     else
00708     {
00709         trans.x=0.0f;
00710         trans.y=0.0f;
00711         trans.z=0.0f;
00712     }
00713 
00714     rot.w=cos(rotation/2.0f);
00715     rot.x=0.0f;
00716     rot.y=0.0f;
00717     rot.z=sin(rotation/2.0f);
00718 
00719     sca_rot.w=cos(scalingrotation/2.0f);
00720     sca_rot.x=0.0f;
00721     sca_rot.y=0.0f;
00722     sca_rot.z=sin(scalingrotation/2.0f);
00723 
00724     D3DXMatrixTransformation(pout, &sca_center, &sca_rot, &sca, &rot_center, &rot, &trans);
00725 
00726     return pout;
00727 }
00728 
00729 D3DXMATRIX* WINAPI D3DXMatrixTranslation(D3DXMATRIX *pout, FLOAT x, FLOAT y, FLOAT z)
00730 {
00731     D3DXMatrixIdentity(pout);
00732     pout->u.m[3][0] = x;
00733     pout->u.m[3][1] = y;
00734     pout->u.m[3][2] = z;
00735     return pout;
00736 }
00737 
00738 D3DXMATRIX* WINAPI D3DXMatrixTranspose(D3DXMATRIX *pout, CONST D3DXMATRIX *pm)
00739 {
00740     CONST D3DXMATRIX m = *pm;
00741     int i,j;
00742 
00743     for (i=0; i<4; i++)
00744         for (j=0; j<4; j++) pout->u.m[i][j] = m.u.m[j][i];
00745 
00746     return pout;
00747 }
00748 
00749 /*_________________D3DXMatrixStack____________________*/
00750 
00751 static const unsigned int INITIAL_STACK_SIZE = 32;
00752 
00753 HRESULT WINAPI D3DXCreateMatrixStack(DWORD flags, LPD3DXMATRIXSTACK* ppstack)
00754 {
00755     ID3DXMatrixStackImpl* object;
00756 
00757     TRACE("flags %#x, ppstack %p\n", flags, ppstack);
00758 
00759     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ID3DXMatrixStackImpl));
00760     if ( object == NULL )
00761     {
00762      *ppstack = NULL;
00763      return E_OUTOFMEMORY;
00764     }
00765     object->lpVtbl = &ID3DXMatrixStack_Vtbl;
00766     object->ref = 1;
00767 
00768     object->stack = HeapAlloc(GetProcessHeap(), 0, INITIAL_STACK_SIZE * sizeof(D3DXMATRIX));
00769     if (!object->stack)
00770     {
00771         HeapFree(GetProcessHeap(), 0, object);
00772         *ppstack = NULL;
00773         return E_OUTOFMEMORY;
00774     }
00775 
00776     object->current = 0;
00777     object->stack_size = INITIAL_STACK_SIZE;
00778     D3DXMatrixIdentity(&object->stack[0]);
00779 
00780     TRACE("Created matrix stack %p\n", object);
00781 
00782     *ppstack = (LPD3DXMATRIXSTACK)object;
00783     return D3D_OK;
00784 }
00785 
00786 static HRESULT WINAPI ID3DXMatrixStackImpl_QueryInterface(ID3DXMatrixStack *iface, REFIID riid, void **ppobj)
00787 {
00788     ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
00789     if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_ID3DXMatrixStack))
00790     {
00791      ID3DXMatrixStack_AddRef(iface);
00792      *ppobj = This;
00793      return S_OK;
00794     }
00795     *ppobj = NULL;
00796     ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
00797     return E_NOINTERFACE;
00798 }
00799 
00800 static ULONG WINAPI ID3DXMatrixStackImpl_AddRef(ID3DXMatrixStack *iface)
00801 {
00802     ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
00803     ULONG ref = InterlockedIncrement(&This->ref);
00804     TRACE("(%p) : AddRef from %d\n", This, ref - 1);
00805     return ref;
00806 }
00807 
00808 static ULONG WINAPI ID3DXMatrixStackImpl_Release(ID3DXMatrixStack* iface)
00809 {
00810     ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
00811     ULONG ref = InterlockedDecrement(&This->ref);
00812     if (!ref)
00813     {
00814         HeapFree(GetProcessHeap(), 0, This->stack);
00815         HeapFree(GetProcessHeap(), 0, This);
00816     }
00817     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
00818     return ref;
00819 }
00820 
00821 static D3DXMATRIX* WINAPI ID3DXMatrixStackImpl_GetTop(ID3DXMatrixStack *iface)
00822 {
00823     ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
00824 
00825     TRACE("iface %p\n", iface);
00826 
00827     return &This->stack[This->current];
00828 }
00829 
00830 static HRESULT WINAPI ID3DXMatrixStackImpl_LoadIdentity(ID3DXMatrixStack *iface)
00831 {
00832     ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
00833 
00834     TRACE("iface %p\n", iface);
00835 
00836     D3DXMatrixIdentity(&This->stack[This->current]);
00837 
00838     return D3D_OK;
00839 }
00840 
00841 static HRESULT WINAPI ID3DXMatrixStackImpl_LoadMatrix(ID3DXMatrixStack *iface, CONST D3DXMATRIX *pm)
00842 {
00843     ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
00844 
00845     TRACE("iface %p\n", iface);
00846 
00847     This->stack[This->current] = *pm;
00848 
00849     return D3D_OK;
00850 }
00851 
00852 static HRESULT WINAPI ID3DXMatrixStackImpl_MultMatrix(ID3DXMatrixStack *iface, CONST D3DXMATRIX *pm)
00853 {
00854     ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
00855 
00856     TRACE("iface %p\n", iface);
00857 
00858     D3DXMatrixMultiply(&This->stack[This->current], &This->stack[This->current], pm);
00859 
00860     return D3D_OK;
00861 }
00862 
00863 static HRESULT WINAPI ID3DXMatrixStackImpl_MultMatrixLocal(ID3DXMatrixStack *iface, CONST D3DXMATRIX *pm)
00864 {
00865     ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
00866 
00867     TRACE("iface %p\n", iface);
00868 
00869     D3DXMatrixMultiply(&This->stack[This->current], pm, &This->stack[This->current]);
00870 
00871     return D3D_OK;
00872 }
00873 
00874 static HRESULT WINAPI ID3DXMatrixStackImpl_Pop(ID3DXMatrixStack *iface)
00875 {
00876     ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
00877 
00878     TRACE("iface %p\n", iface);
00879 
00880     /* Popping the last element on the stack returns D3D_OK, but does nothing. */
00881     if (!This->current) return D3D_OK;
00882 
00883     if (This->current <= This->stack_size / 4 && This->stack_size >= INITIAL_STACK_SIZE * 2)
00884     {
00885         unsigned int new_size;
00886         D3DXMATRIX *new_stack;
00887 
00888         new_size = This->stack_size / 2;
00889         new_stack = HeapReAlloc(GetProcessHeap(), 0, This->stack, new_size * sizeof(D3DXMATRIX));
00890         if (new_stack)
00891         {
00892             This->stack_size = new_size;
00893             This->stack = new_stack;
00894         }
00895     }
00896 
00897     --This->current;
00898 
00899     return D3D_OK;
00900 }
00901 
00902 static HRESULT WINAPI ID3DXMatrixStackImpl_Push(ID3DXMatrixStack *iface)
00903 {
00904     ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
00905 
00906     TRACE("iface %p\n", iface);
00907 
00908     if (This->current == This->stack_size - 1)
00909     {
00910         unsigned int new_size;
00911         D3DXMATRIX *new_stack;
00912 
00913         if (This->stack_size > UINT_MAX / 2) return E_OUTOFMEMORY;
00914 
00915         new_size = This->stack_size * 2;
00916         new_stack = HeapReAlloc(GetProcessHeap(), 0, This->stack, new_size * sizeof(D3DXMATRIX));
00917         if (!new_stack) return E_OUTOFMEMORY;
00918 
00919         This->stack_size = new_size;
00920         This->stack = new_stack;
00921     }
00922 
00923     ++This->current;
00924     This->stack[This->current] = This->stack[This->current - 1];
00925 
00926     return D3D_OK;
00927 }
00928 
00929 static HRESULT WINAPI ID3DXMatrixStackImpl_RotateAxis(ID3DXMatrixStack *iface, CONST D3DXVECTOR3 *pv, FLOAT angle)
00930 {
00931     D3DXMATRIX temp;
00932     ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
00933 
00934     TRACE("iface %p\n", iface);
00935 
00936     D3DXMatrixRotationAxis(&temp, pv, angle);
00937     D3DXMatrixMultiply(&This->stack[This->current], &This->stack[This->current], &temp);
00938 
00939     return D3D_OK;
00940 }
00941 
00942 static HRESULT WINAPI ID3DXMatrixStackImpl_RotateAxisLocal(ID3DXMatrixStack *iface, CONST D3DXVECTOR3 *pv, FLOAT angle)
00943 {
00944     D3DXMATRIX temp;
00945     ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
00946 
00947     TRACE("iface %p\n", iface);
00948 
00949     D3DXMatrixRotationAxis(&temp, pv, angle);
00950     D3DXMatrixMultiply(&This->stack[This->current], &temp, &This->stack[This->current]);
00951 
00952     return D3D_OK;
00953 }
00954 
00955 static HRESULT WINAPI ID3DXMatrixStackImpl_RotateYawPitchRoll(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
00956 {
00957     D3DXMATRIX temp;
00958     ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
00959 
00960     TRACE("iface %p\n", iface);
00961 
00962     D3DXMatrixRotationYawPitchRoll(&temp, x, y, z);
00963     D3DXMatrixMultiply(&This->stack[This->current], &This->stack[This->current], &temp);
00964 
00965     return D3D_OK;
00966 }
00967 
00968 static HRESULT WINAPI ID3DXMatrixStackImpl_RotateYawPitchRollLocal(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
00969 {
00970     D3DXMATRIX temp;
00971     ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
00972 
00973     TRACE("iface %p\n", iface);
00974 
00975     D3DXMatrixRotationYawPitchRoll(&temp, x, y, z);
00976     D3DXMatrixMultiply(&This->stack[This->current], &temp, &This->stack[This->current]);
00977 
00978     return D3D_OK;
00979 }
00980 
00981 static HRESULT WINAPI ID3DXMatrixStackImpl_Scale(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
00982 {
00983     D3DXMATRIX temp;
00984     ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
00985 
00986     TRACE("iface %p\n", iface);
00987 
00988     D3DXMatrixScaling(&temp, x, y, z);
00989     D3DXMatrixMultiply(&This->stack[This->current], &This->stack[This->current], &temp);
00990 
00991     return D3D_OK;
00992 }
00993 
00994 static HRESULT WINAPI ID3DXMatrixStackImpl_ScaleLocal(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
00995 {
00996     D3DXMATRIX temp;
00997     ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
00998 
00999     TRACE("iface %p\n", iface);
01000 
01001     D3DXMatrixScaling(&temp, x, y, z);
01002     D3DXMatrixMultiply(&This->stack[This->current], &temp, &This->stack[This->current]);
01003 
01004     return D3D_OK;
01005 }
01006 
01007 static HRESULT WINAPI ID3DXMatrixStackImpl_Translate(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
01008 {
01009     D3DXMATRIX temp;
01010     ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
01011 
01012     TRACE("iface %p\n", iface);
01013 
01014     D3DXMatrixTranslation(&temp, x, y, z);
01015     D3DXMatrixMultiply(&This->stack[This->current], &This->stack[This->current], &temp);
01016 
01017     return D3D_OK;
01018 }
01019 
01020 static HRESULT WINAPI ID3DXMatrixStackImpl_TranslateLocal(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
01021 {
01022     D3DXMATRIX temp;
01023     ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
01024 
01025     TRACE("iface %p\n", iface);
01026 
01027     D3DXMatrixTranslation(&temp, x, y, z);
01028     D3DXMatrixMultiply(&This->stack[This->current], &temp,&This->stack[This->current]);
01029 
01030     return D3D_OK;
01031 }
01032 
01033 static const ID3DXMatrixStackVtbl ID3DXMatrixStack_Vtbl =
01034 {
01035     ID3DXMatrixStackImpl_QueryInterface,
01036     ID3DXMatrixStackImpl_AddRef,
01037     ID3DXMatrixStackImpl_Release,
01038     ID3DXMatrixStackImpl_Pop,
01039     ID3DXMatrixStackImpl_Push,
01040     ID3DXMatrixStackImpl_LoadIdentity,
01041     ID3DXMatrixStackImpl_LoadMatrix,
01042     ID3DXMatrixStackImpl_MultMatrix,
01043     ID3DXMatrixStackImpl_MultMatrixLocal,
01044     ID3DXMatrixStackImpl_RotateAxis,
01045     ID3DXMatrixStackImpl_RotateAxisLocal,
01046     ID3DXMatrixStackImpl_RotateYawPitchRoll,
01047     ID3DXMatrixStackImpl_RotateYawPitchRollLocal,
01048     ID3DXMatrixStackImpl_Scale,
01049     ID3DXMatrixStackImpl_ScaleLocal,
01050     ID3DXMatrixStackImpl_Translate,
01051     ID3DXMatrixStackImpl_TranslateLocal,
01052     ID3DXMatrixStackImpl_GetTop
01053 };
01054 
01055 /*_________________D3DXPLANE________________*/
01056 
01057 D3DXPLANE* WINAPI D3DXPlaneFromPointNormal(D3DXPLANE *pout, CONST D3DXVECTOR3 *pvpoint, CONST D3DXVECTOR3 *pvnormal)
01058 {
01059     pout->a = pvnormal->x;
01060     pout->b = pvnormal->y;
01061     pout->c = pvnormal->z;
01062     pout->d = -D3DXVec3Dot(pvpoint, pvnormal);
01063     return pout;
01064 }
01065 
01066 D3DXPLANE* WINAPI D3DXPlaneFromPoints(D3DXPLANE *pout, CONST D3DXVECTOR3 *pv1, CONST D3DXVECTOR3 *pv2, CONST D3DXVECTOR3 *pv3)
01067 {
01068     D3DXVECTOR3 edge1, edge2, normal, Nnormal;
01069 
01070     edge1.x = 0.0f; edge1.y = 0.0f; edge1.z = 0.0f;
01071     edge2.x = 0.0f; edge2.y = 0.0f; edge2.z = 0.0f;
01072     D3DXVec3Subtract(&edge1, pv2, pv1);
01073     D3DXVec3Subtract(&edge2, pv3, pv1);
01074     D3DXVec3Cross(&normal, &edge1, &edge2);
01075     D3DXVec3Normalize(&Nnormal, &normal);
01076     D3DXPlaneFromPointNormal(pout, pv1, &Nnormal);
01077     return pout;
01078 }
01079 
01080 D3DXVECTOR3* WINAPI D3DXPlaneIntersectLine(D3DXVECTOR3 *pout, CONST D3DXPLANE *pp, CONST D3DXVECTOR3 *pv1, CONST D3DXVECTOR3 *pv2)
01081 {
01082     D3DXVECTOR3 direction, normal;
01083     FLOAT dot, temp;
01084 
01085     normal.x = pp->a;
01086     normal.y = pp->b;
01087     normal.z = pp->c;
01088     direction.x = pv2->x - pv1->x;
01089     direction.y = pv2->y - pv1->y;
01090     direction.z = pv2->z - pv1->z;
01091     dot = D3DXVec3Dot(&normal, &direction);
01092     if ( !dot ) return NULL;
01093     temp = ( pp->d + D3DXVec3Dot(&normal, pv1) ) / dot;
01094     pout->x = pv1->x - temp * direction.x;
01095     pout->y = pv1->y - temp * direction.y;
01096     pout->z = pv1->z - temp * direction.z;
01097     return pout;
01098 }
01099 
01100 D3DXPLANE* WINAPI D3DXPlaneNormalize(D3DXPLANE *pout, CONST D3DXPLANE *pp)
01101 {
01102     D3DXPLANE out;
01103     FLOAT norm;
01104 
01105     norm = sqrt(pp->a * pp->a + pp->b * pp->b + pp->c * pp->c);
01106     if ( norm )
01107     {
01108      out.a = pp->a / norm;
01109      out.b = pp->b / norm;
01110      out.c = pp->c / norm;
01111      out.d = pp->d / norm;
01112     }
01113     else
01114     {
01115      out.a = 0.0f;
01116      out.b = 0.0f;
01117      out.c = 0.0f;
01118      out.d = 0.0f;
01119     }
01120     *pout = out;
01121     return pout;
01122 }
01123 
01124 D3DXPLANE* WINAPI D3DXPlaneTransform(D3DXPLANE *pout, CONST D3DXPLANE *pplane, CONST D3DXMATRIX *pm)
01125 {
01126     CONST D3DXPLANE plane = *pplane;
01127     pout->a = pm->u.m[0][0] * plane.a + pm->u.m[1][0] * plane.b + pm->u.m[2][0] * plane.c + pm->u.m[3][0] * plane.d;
01128     pout->b = pm->u.m[0][1] * plane.a + pm->u.m[1][1] * plane.b + pm->u.m[2][1] * plane.c + pm->u.m[3][1] * plane.d;
01129     pout->c = pm->u.m[0][2] * plane.a + pm->u.m[1][2] * plane.b + pm->u.m[2][2] * plane.c + pm->u.m[3][2] * plane.d;
01130     pout->d = pm->u.m[0][3] * plane.a + pm->u.m[1][3] * plane.b + pm->u.m[2][3] * plane.c + pm->u.m[3][3] * plane.d;
01131     return pout;
01132 }
01133 
01134 D3DXPLANE* WINAPI D3DXPlaneTransformArray(D3DXPLANE* out, UINT outstride, CONST D3DXPLANE* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements)
01135 {
01136     UINT i;
01137 
01138     for (i = 0; i < elements; ++i) {
01139         D3DXPlaneTransform(
01140             (D3DXPLANE*)((char*)out + outstride * i),
01141             (CONST D3DXPLANE*)((const char*)in + instride * i),
01142             matrix);
01143     }
01144     return out;
01145 }
01146 
01147 /*_________________D3DXQUATERNION________________*/
01148 
01149 D3DXQUATERNION* WINAPI D3DXQuaternionBaryCentric(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq1, CONST D3DXQUATERNION *pq2, CONST D3DXQUATERNION *pq3, FLOAT f, FLOAT g)
01150 {
01151     D3DXQUATERNION temp1, temp2;
01152     D3DXQuaternionSlerp(pout, D3DXQuaternionSlerp(&temp1, pq1, pq2, f + g), D3DXQuaternionSlerp(&temp2, pq1, pq3, f+g), g / (f + g));
01153     return pout;
01154 }
01155 
01156 D3DXQUATERNION* WINAPI D3DXQuaternionExp(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq)
01157 {
01158     FLOAT norm;
01159 
01160     norm = sqrt(pq->x * pq->x + pq->y * pq->y + pq->z * pq->z);
01161     if (norm )
01162     {
01163      pout->x = sin(norm) * pq->x / norm;
01164      pout->y = sin(norm) * pq->y / norm;
01165      pout->z = sin(norm) * pq->z / norm;
01166      pout->w = cos(norm);
01167     }
01168     else
01169     {
01170      pout->x = 0.0f;
01171      pout->y = 0.0f;
01172      pout->z = 0.0f;
01173      pout->w = 1.0f;
01174     }
01175     return pout;
01176 }
01177 
01178 D3DXQUATERNION* WINAPI D3DXQuaternionInverse(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq)
01179 {
01180     D3DXQUATERNION out;
01181     FLOAT norm;
01182 
01183     norm = D3DXQuaternionLengthSq(pq);
01184 
01185     out.x = -pq->x / norm;
01186     out.y = -pq->y / norm;
01187     out.z = -pq->z / norm;
01188     out.w = pq->w / norm;
01189 
01190     *pout =out;
01191     return pout;
01192 }
01193 
01194 D3DXQUATERNION* WINAPI D3DXQuaternionLn(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq)
01195 {
01196     FLOAT norm, normvec, theta;
01197 
01198     norm = D3DXQuaternionLengthSq(pq);
01199     if ( norm > 1.0001f )
01200     {
01201      pout->x = pq->x;
01202      pout->y = pq->y;
01203      pout->z = pq->z;
01204      pout->w = 0.0f;
01205     }
01206     else if( norm > 0.99999f)
01207     {
01208      normvec = sqrt( pq->x * pq->x + pq->y * pq->y + pq->z * pq->z );
01209      theta = atan2(normvec, pq->w) / normvec;
01210      pout->x = theta * pq->x;
01211      pout->y = theta * pq->y;
01212      pout->z = theta * pq->z;
01213      pout->w = 0.0f;
01214     }
01215     else
01216     {
01217      FIXME("The quaternion (%f, %f, %f, %f) has a norm <1. This should not happen. Windows returns a result anyway. This case is not implemented yet.\n", pq->x, pq->y, pq->z, pq->w);
01218     }
01219     return pout;
01220 }
01221 
01222 D3DXQUATERNION* WINAPI D3DXQuaternionMultiply(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq1, CONST D3DXQUATERNION *pq2)
01223 {
01224     D3DXQUATERNION out;
01225     out.x = pq2->w * pq1->x + pq2->x * pq1->w + pq2->y * pq1->z - pq2->z * pq1->y;
01226     out.y = pq2->w * pq1->y - pq2->x * pq1->z + pq2->y * pq1->w + pq2->z * pq1->x;
01227     out.z = pq2->w * pq1->z + pq2->x * pq1->y - pq2->y * pq1->x + pq2->z * pq1->w;
01228     out.w = pq2->w * pq1->w - pq2->x * pq1->x - pq2->y * pq1->y - pq2->z * pq1->z;
01229     *pout = out;
01230     return pout;
01231 }
01232 
01233 D3DXQUATERNION* WINAPI D3DXQuaternionNormalize(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq)
01234 {
01235     D3DXQUATERNION out;
01236     FLOAT norm;
01237 
01238     norm = D3DXQuaternionLength(pq);
01239 
01240     out.x = pq->x / norm;
01241     out.y = pq->y / norm;
01242     out.z = pq->z / norm;
01243     out.w = pq->w / norm;
01244 
01245     *pout=out;
01246 
01247     return pout;
01248 }
01249 
01250 D3DXQUATERNION* WINAPI D3DXQuaternionRotationAxis(D3DXQUATERNION *pout, CONST D3DXVECTOR3 *pv, FLOAT angle)
01251 {
01252     D3DXVECTOR3 temp;
01253 
01254     D3DXVec3Normalize(&temp, pv);
01255     pout->x = sin( angle / 2.0f ) * temp.x;
01256     pout->y = sin( angle / 2.0f ) * temp.y;
01257     pout->z = sin( angle / 2.0f ) * temp.z;
01258     pout->w = cos( angle / 2.0f );
01259     return pout;
01260 }
01261 
01262 D3DXQUATERNION* WINAPI D3DXQuaternionRotationMatrix(D3DXQUATERNION *pout, CONST D3DXMATRIX *pm)
01263 {
01264     int i, maxi;
01265     FLOAT maxdiag, S, trace;
01266 
01267     trace = pm->u.m[0][0] + pm->u.m[1][1] + pm->u.m[2][2] + 1.0f;
01268     if ( trace > 1.0f)
01269     {
01270      pout->x = ( pm->u.m[1][2] - pm->u.m[2][1] ) / ( 2.0f * sqrt(trace) );
01271      pout->y = ( pm->u.m[2][0] - pm->u.m[0][2] ) / ( 2.0f * sqrt(trace) );
01272      pout->z = ( pm->u.m[0][1] - pm->u.m[1][0] ) / ( 2.0f * sqrt(trace) );
01273      pout->w = sqrt(trace) / 2.0f;
01274      return pout;
01275      }
01276     maxi = 0;
01277     maxdiag = pm->u.m[0][0];
01278     for (i=1; i<3; i++)
01279     {
01280      if ( pm->u.m[i][i] > maxdiag )
01281      {
01282       maxi = i;
01283       maxdiag = pm->u.m[i][i];
01284      }
01285     }
01286     switch( maxi )
01287     {
01288      case 0:
01289        S = 2.0f * sqrt(1.0f + pm->u.m[0][0] - pm->u.m[1][1] - pm->u.m[2][2]);
01290        pout->x = 0.25f * S;
01291        pout->y = ( pm->u.m[0][1] + pm->u.m[1][0] ) / S;
01292        pout->z = ( pm->u.m[0][2] + pm->u.m[2][0] ) / S;
01293        pout->w = ( pm->u.m[1][2] - pm->u.m[2][1] ) / S;
01294      break;
01295      case 1:
01296        S = 2.0f * sqrt(1.0f + pm->u.m[1][1] - pm->u.m[0][0] - pm->u.m[2][2]);
01297        pout->x = ( pm->u.m[0][1] + pm->u.m[1][0] ) / S;
01298        pout->y = 0.25f * S;
01299        pout->z = ( pm->u.m[1][2] + pm->u.m[2][1] ) / S;
01300        pout->w = ( pm->u.m[2][0] - pm->u.m[0][2] ) / S;
01301      break;
01302      case 2:
01303        S = 2.0f * sqrt(1.0f + pm->u.m[2][2] - pm->u.m[0][0] - pm->u.m[1][1]);
01304        pout->x = ( pm->u.m[0][2] + pm->u.m[2][0] ) / S;
01305        pout->y = ( pm->u.m[1][2] + pm->u.m[2][1] ) / S;
01306        pout->z = 0.25f * S;
01307        pout->w = ( pm->u.m[0][1] - pm->u.m[1][0] ) / S;
01308      break;
01309     }
01310     return pout;
01311 }
01312 
01313 D3DXQUATERNION* WINAPI D3DXQuaternionRotationYawPitchRoll(D3DXQUATERNION *pout, FLOAT yaw, FLOAT pitch, FLOAT roll)
01314 {
01315     pout->x = sin( yaw / 2.0f) * cos(pitch / 2.0f) * sin(roll / 2.0f) + cos(yaw / 2.0f) * sin(pitch / 2.0f) * cos(roll / 2.0f);
01316     pout->y = sin( yaw / 2.0f) * cos(pitch / 2.0f) * cos(roll / 2.0f) - cos(yaw / 2.0f) * sin(pitch / 2.0f) * sin(roll / 2.0f);
01317     pout->z = cos(yaw / 2.0f) * cos(pitch / 2.0f) * sin(roll / 2.0f) - sin( yaw / 2.0f) * sin(pitch / 2.0f) * cos(roll / 2.0f);
01318     pout->w = cos( yaw / 2.0f) * cos(pitch / 2.0f) * cos(roll / 2.0f) + sin(yaw / 2.0f) * sin(pitch / 2.0f) * sin(roll / 2.0f);
01319     return pout;
01320 }
01321 
01322 D3DXQUATERNION* WINAPI D3DXQuaternionSlerp(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq1, CONST D3DXQUATERNION *pq2, FLOAT t)
01323 {
01324     FLOAT dot, epsilon, temp, theta, u;
01325 
01326     epsilon = 1.0f;
01327     temp = 1.0f - t;
01328     u = t;
01329     dot = D3DXQuaternionDot(pq1, pq2);
01330     if ( dot < 0.0f )
01331     {
01332         epsilon = -1.0f;
01333         dot = -dot;
01334     }
01335     if( 1.0f - dot > 0.001f )
01336     {
01337         theta = acos(dot);
01338         temp  = sin(theta * temp) / sin(theta);
01339         u = sin(theta * u) / sin(theta);
01340     }
01341     pout->x = temp * pq1->x + epsilon * u * pq2->x;
01342     pout->y = temp * pq1->y + epsilon * u * pq2->y;
01343     pout->z = temp * pq1->z + epsilon * u * pq2->z;
01344     pout->w = temp * pq1->w + epsilon * u * pq2->w;
01345     return pout;
01346 }
01347 
01348 D3DXQUATERNION* WINAPI D3DXQuaternionSquad(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq1, CONST D3DXQUATERNION *pq2, CONST D3DXQUATERNION *pq3, CONST D3DXQUATERNION *pq4, FLOAT t)
01349 {
01350     D3DXQUATERNION temp1, temp2;
01351 
01352     D3DXQuaternionSlerp(pout, D3DXQuaternionSlerp(&temp1, pq1, pq4, t), D3DXQuaternionSlerp(&temp2, pq2, pq3, t), 2.0f * t * (1.0f - t));
01353     return pout;
01354 }
01355 
01356 void WINAPI D3DXQuaternionToAxisAngle(CONST D3DXQUATERNION *pq, D3DXVECTOR3 *paxis, FLOAT *pangle)
01357 {
01358     paxis->x = pq->x;
01359     paxis->y = pq->y;
01360     paxis->z = pq->z;
01361     *pangle = 2.0f * acos(pq->w);
01362 }
01363 
01364 /*_________________D3DXVec2_____________________*/
01365 
01366 D3DXVECTOR2* WINAPI D3DXVec2BaryCentric(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv1, CONST D3DXVECTOR2 *pv2, CONST D3DXVECTOR2 *pv3, FLOAT f, FLOAT g)
01367 {
01368     pout->x = (1.0f-f-g) * (pv1->x) + f * (pv2->x) + g * (pv3->x);
01369     pout->y = (1.0f-f-g) * (pv1->y) + f * (pv2->y) + g * (pv3->y);
01370     return pout;
01371 }
01372 
01373 D3DXVECTOR2* WINAPI D3DXVec2CatmullRom(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv0, CONST D3DXVECTOR2 *pv1, CONST D3DXVECTOR2 *pv2, CONST D3DXVECTOR2 *pv3, FLOAT s)
01374 {
01375     pout->x = 0.5f * (2.0f * pv1->x + (pv2->x - pv0->x) *s + (2.0f *pv0->x - 5.0f * pv1->x + 4.0f * pv2->x - pv3->x) * s * s + (pv3->x -3.0f * pv2->x + 3.0f * pv1->x - pv0->x) * s * s * s);
01376     pout->y = 0.5f * (2.0f * pv1->y + (pv2->y - pv0->y) *s + (2.0f *pv0->y - 5.0f * pv1->y + 4.0f * pv2->y - pv3->y) * s * s + (pv3->y -3.0f * pv2->y + 3.0f * pv1->y - pv0->y) * s * s * s);
01377     return pout;
01378 }
01379 
01380 D3DXVECTOR2* WINAPI D3DXVec2Hermite(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv1, CONST D3DXVECTOR2 *pt1, CONST D3DXVECTOR2 *pv2, CONST D3DXVECTOR2 *pt2, FLOAT s)
01381 {
01382     FLOAT h1, h2, h3, h4;
01383 
01384     h1 = 2.0f * s * s * s - 3.0f * s * s + 1.0f;
01385     h2 = s * s * s - 2.0f * s * s + s;
01386     h3 = -2.0f * s * s * s + 3.0f * s * s;
01387     h4 = s * s * s - s * s;
01388 
01389     pout->x = h1 * (pv1->x) + h2 * (pt1->x) + h3 * (pv2->x) + h4 * (pt2->x);
01390     pout->y = h1 * (pv1->y) + h2 * (pt1->y) + h3 * (pv2->y) + h4 * (pt2->y);
01391     return pout;
01392 }
01393 
01394 D3DXVECTOR2* WINAPI D3DXVec2Normalize(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv)
01395 {
01396     D3DXVECTOR2 out;
01397     FLOAT norm;
01398 
01399     norm = D3DXVec2Length(pv);
01400     if ( !norm )
01401     {
01402      out.x = 0.0f;
01403      out.y = 0.0f;
01404     }
01405     else
01406     {
01407      out.x = pv->x / norm;
01408      out.y = pv->y / norm;
01409     }
01410     *pout=out;
01411     return pout;
01412 }
01413 
01414 D3DXVECTOR4* WINAPI D3DXVec2Transform(D3DXVECTOR4 *pout, CONST D3DXVECTOR2 *pv, CONST D3DXMATRIX *pm)
01415 {
01416     pout->x = pm->u.m[0][0] * pv->x + pm->u.m[1][0] * pv->y  + pm->u.m[3][0];
01417     pout->y = pm->u.m[0][1] * pv->x + pm->u.m[1][1] * pv->y  + pm->u.m[3][1];
01418     pout->z = pm->u.m[0][2] * pv->x + pm->u.m[1][2] * pv->y  + pm->u.m[3][2];
01419     pout->w = pm->u.m[0][3] * pv->x + pm->u.m[1][3] * pv->y  + pm->u.m[3][3];
01420     return pout;
01421 }
01422 
01423 D3DXVECTOR4* WINAPI D3DXVec2TransformArray(D3DXVECTOR4* out, UINT outstride, CONST D3DXVECTOR2* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements)
01424 {
01425     UINT i;
01426 
01427     for (i = 0; i < elements; ++i) {
01428         D3DXVec2Transform(
01429             (D3DXVECTOR4*)((char*)out + outstride * i),
01430             (CONST D3DXVECTOR2*)((const char*)in + instride * i),
01431             matrix);
01432     }
01433     return out;
01434 }
01435 
01436 D3DXVECTOR2* WINAPI D3DXVec2TransformCoord(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv, CONST D3DXMATRIX *pm)
01437 {
01438     D3DXVECTOR2 v;
01439     FLOAT norm;
01440 
01441     v = *pv;
01442     norm = pm->u.m[0][3] * pv->x + pm->u.m[1][3] * pv->y + pm->u.m[3][3];
01443 
01444     pout->x = (pm->u.m[0][0] * v.x + pm->u.m[1][0] * v.y + pm->u.m[3][0]) / norm;
01445     pout->y = (pm->u.m[0][1] * v.x + pm->u.m[1][1] * v.y + pm->u.m[3][1]) / norm;
01446 
01447     return pout;
01448 }
01449 
01450 D3DXVECTOR2* WINAPI D3DXVec2TransformCoordArray(D3DXVECTOR2* out, UINT outstride, CONST D3DXVECTOR2* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements)
01451 {
01452     UINT i;
01453 
01454     for (i = 0; i < elements; ++i) {
01455         D3DXVec2TransformCoord(
01456             (D3DXVECTOR2*)((char*)out + outstride * i),
01457             (CONST D3DXVECTOR2*)((const char*)in + instride * i),
01458             matrix);
01459     }
01460     return out;
01461 }
01462 
01463 D3DXVECTOR2* WINAPI D3DXVec2TransformNormal(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv, CONST D3DXMATRIX *pm)
01464 {
01465     CONST D3DXVECTOR2 v = *pv;
01466     pout->x = pm->u.m[0][0] * v.x + pm->u.m[1][0] * v.y;
01467     pout->y = pm->u.m[0][1] * v.x + pm->u.m[1][1] * v.y;
01468     return pout;
01469 }
01470 
01471 D3DXVECTOR2* WINAPI D3DXVec2TransformNormalArray(D3DXVECTOR2* out, UINT outstride, CONST D3DXVECTOR2 *in, UINT instride, CONST D3DXMATRIX *matrix, UINT elements)
01472 {
01473     UINT i;
01474 
01475     for (i = 0; i < elements; ++i) {
01476         D3DXVec2TransformNormal(
01477             (D3DXVECTOR2*)((char*)out + outstride * i),
01478             (CONST D3DXVECTOR2*)((const char*)in + instride * i),
01479             matrix);
01480     }
01481     return out;
01482 }
01483 
01484 /*_________________D3DXVec3_____________________*/
01485 
01486 D3DXVECTOR3* WINAPI D3DXVec3BaryCentric(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv1, CONST D3DXVECTOR3 *pv2, CONST D3DXVECTOR3 *pv3, FLOAT f, FLOAT g)
01487 {
01488     pout->x = (1.0f-f-g) * (pv1->x) + f * (pv2->x) + g * (pv3->x);
01489     pout->y = (1.0f-f-g) * (pv1->y) + f * (pv2->y) + g * (pv3->y);
01490     pout->z = (1.0f-f-g) * (pv1->z) + f * (pv2->z) + g * (pv3->z);
01491     return pout;
01492 }
01493 
01494 D3DXVECTOR3* WINAPI D3DXVec3CatmullRom( D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv0, CONST D3DXVECTOR3 *pv1, CONST D3DXVECTOR3 *pv2, CONST D3DXVECTOR3 *pv3, FLOAT s)
01495 {
01496     pout->x = 0.5f * (2.0f * pv1->x + (pv2->x - pv0->x) *s + (2.0f *pv0->x - 5.0f * pv1->x + 4.0f * pv2->x - pv3->x) * s * s + (pv3->x -3.0f * pv2->x + 3.0f * pv1->x - pv0->x) * s * s * s);
01497     pout->y = 0.5f * (2.0f * pv1->y + (pv2->y - pv0->y) *s + (2.0f *pv0->y - 5.0f * pv1->y + 4.0f * pv2->y - pv3->y) * s * s + (pv3->y -3.0f * pv2->y + 3.0f * pv1->y - pv0->y) * s * s * s);
01498     pout->z = 0.5f * (2.0f * pv1->z + (pv2->z - pv0->z) *s + (2.0f *pv0->z - 5.0f * pv1->z + 4.0f * pv2->z - pv3->z) * s * s + (pv3->z -3.0f * pv2->z + 3.0f * pv1->z - pv0->z) * s * s * s);
01499     return pout;
01500 }
01501 
01502 D3DXVECTOR3* WINAPI D3DXVec3Hermite(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv1, CONST D3DXVECTOR3 *pt1, CONST D3DXVECTOR3 *pv2, CONST D3DXVECTOR3 *pt2, FLOAT s)
01503 {
01504     FLOAT h1, h2, h3, h4;
01505 
01506     h1 = 2.0f * s * s * s - 3.0f * s * s + 1.0f;
01507     h2 = s * s * s - 2.0f * s * s + s;
01508     h3 = -2.0f * s * s * s + 3.0f * s * s;
01509     h4 = s * s * s - s * s;
01510 
01511     pout->x = h1 * (pv1->x) + h2 * (pt1->x) + h3 * (pv2->x) + h4 * (pt2->x);
01512     pout->y = h1 * (pv1->y) + h2 * (pt1->y) + h3 * (pv2->y) + h4 * (pt2->y);
01513     pout->z = h1 * (pv1->z) + h2 * (pt1->z) + h3 * (pv2->z) + h4 * (pt2->z);
01514     return pout;
01515 }
01516 
01517 D3DXVECTOR3* WINAPI D3DXVec3Normalize(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv)
01518 {
01519     D3DXVECTOR3 out;
01520     FLOAT norm;
01521 
01522     norm = D3DXVec3Length(pv);
01523     if ( !norm )
01524     {
01525      out.x = 0.0f;
01526      out.y = 0.0f;
01527      out.z = 0.0f;
01528     }
01529     else
01530     {
01531      out.x = pv->x / norm;
01532      out.y = pv->y / norm;
01533      out.z = pv->z / norm;
01534     }
01535     *pout = out;
01536     return pout;
01537 }
01538 
01539 D3DXVECTOR3* WINAPI D3DXVec3Project(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv, CONST D3DVIEWPORT9 *pviewport, CONST D3DXMATRIX *pprojection, CONST D3DXMATRIX *pview, CONST D3DXMATRIX *pworld)
01540 {
01541     D3DXMATRIX m;
01542     D3DXVECTOR3 out;
01543 
01544     D3DXMatrixMultiply(&m, pworld, pview);
01545     D3DXMatrixMultiply(&m, &m, pprojection);
01546     D3DXVec3TransformCoord(&out, pv, &m);
01547     out.x = pviewport->X +  ( 1.0f + out.x ) * pviewport->Width / 2.0f;
01548     out.y = pviewport->Y +  ( 1.0f - out.y ) * pviewport->Height / 2.0f;
01549     out.z = pviewport->MinZ + out.z * ( pviewport->MaxZ - pviewport->MinZ );
01550     *pout = out;
01551     return pout;
01552 }
01553 
01554 D3DXVECTOR3* WINAPI D3DXVec3ProjectArray(D3DXVECTOR3* out, UINT outstride, CONST D3DXVECTOR3* in, UINT instride, CONST D3DVIEWPORT9* viewport, CONST D3DXMATRIX* projection, CONST D3DXMATRIX* view, CONST D3DXMATRIX* world, UINT elements)
01555 {
01556     UINT i;
01557 
01558     for (i = 0; i < elements; ++i) {
01559         D3DXVec3Project(
01560             (D3DXVECTOR3*)((char*)out + outstride * i),
01561             (CONST D3DXVECTOR3*)((const char*)in + instride * i),
01562             viewport, projection, view, world);
01563     }
01564     return out;
01565 }
01566 
01567 D3DXVECTOR4* WINAPI D3DXVec3Transform(D3DXVECTOR4 *pout, CONST D3DXVECTOR3 *pv, CONST D3DXMATRIX *pm)
01568 {
01569     pout->x = pm->u.m[0][0] * pv->x + pm->u.m[1][0] * pv->y + pm->u.m[2][0] * pv->z + pm->u.m[3][0];
01570     pout->y = pm->u.m[0][1] * pv->x + pm->u.m[1][1] * pv->y + pm->u.m[2][1] * pv->z + pm->u.m[3][1];
01571     pout->z = pm->u.m[0][2] * pv->x + pm->u.m[1][2] * pv->y + pm->u.m[2][2] * pv->z + pm->u.m[3][2];
01572     pout->w = pm->u.m[0][3] * pv->x + pm->u.m[1][3] * pv->y + pm->u.m[2][3] * pv->z + pm->u.m[3][3];
01573     return pout;
01574 }
01575 
01576 D3DXVECTOR4* WINAPI D3DXVec3TransformArray(D3DXVECTOR4* out, UINT outstride, CONST D3DXVECTOR3* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements)
01577 {
01578     UINT i;
01579 
01580     for (i = 0; i < elements; ++i) {
01581         D3DXVec3Transform(
01582             (D3DXVECTOR4*)((char*)out + outstride * i),
01583             (CONST D3DXVECTOR3*)((const char*)in + instride * i),
01584             matrix);
01585     }
01586     return out;
01587 }
01588 
01589 D3DXVECTOR3* WINAPI D3DXVec3TransformCoord(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv, CONST D3DXMATRIX *pm)
01590 {
01591     D3DXVECTOR3 out;
01592     FLOAT norm;
01593 
01594     norm = pm->u.m[0][3] * pv->x + pm->u.m[1][3] * pv->y + pm->u.m[2][3] *pv->z + pm->u.m[3][3];
01595 
01596     out.x = (pm->u.m[0][0] * pv->x + pm->u.m[1][0] * pv->y + pm->u.m[2][0] * pv->z + pm->u.m[3][0]) / norm;
01597     out.y = (pm->u.m[0][1] * pv->x + pm->u.m[1][1] * pv->y + pm->u.m[2][1] * pv->z + pm->u.m[3][1]) / norm;
01598     out.z = (pm->u.m[0][2] * pv->x + pm->u.m[1][2] * pv->y + pm->u.m[2][2] * pv->z + pm->u.m[3][2]) / norm;
01599 
01600     *pout = out;
01601 
01602     return pout;
01603 }
01604 
01605 D3DXVECTOR3* WINAPI D3DXVec3TransformCoordArray(D3DXVECTOR3* out, UINT outstride, CONST D3DXVECTOR3* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements)
01606 {
01607     UINT i;
01608 
01609     for (i = 0; i < elements; ++i) {
01610         D3DXVec3TransformCoord(
01611             (D3DXVECTOR3*)((char*)out + outstride * i),
01612             (CONST D3DXVECTOR3*)((const char*)in + instride * i),
01613             matrix);
01614     }
01615     return out;
01616 }
01617 
01618 D3DXVECTOR3* WINAPI D3DXVec3TransformNormal(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv, CONST D3DXMATRIX *pm)
01619 {
01620     CONST D3DXVECTOR3 v = *pv;
01621     pout->x = pm->u.m[0][0] * v.x + pm->u.m[1][0] * v.y + pm->u.m[2][0] * v.z;
01622     pout->y = pm->u.m[0][1] * v.x + pm->u.m[1][1] * v.y + pm->u.m[2][1] * v.z;
01623     pout->z = pm->u.m[0][2] * v.x + pm->u.m[1][2] * v.y + pm->u.m[2][2] * v.z;
01624     return pout;
01625 
01626 }
01627 
01628 D3DXVECTOR3* WINAPI D3DXVec3TransformNormalArray(D3DXVECTOR3* out, UINT outstride, CONST D3DXVECTOR3* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements)
01629 {
01630     UINT i;
01631 
01632     for (i = 0; i < elements; ++i) {
01633         D3DXVec3TransformNormal(
01634             (D3DXVECTOR3*)((char*)out + outstride * i),
01635             (CONST D3DXVECTOR3*)((const char*)in + instride * i),
01636             matrix);
01637     }
01638     return out;
01639 }
01640 
01641 D3DXVECTOR3* WINAPI D3DXVec3Unproject(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv, CONST D3DVIEWPORT9 *pviewport, CONST D3DXMATRIX *pprojection, CONST D3DXMATRIX *pview, CONST D3DXMATRIX *pworld)
01642 {
01643     D3DXMATRIX m;
01644     D3DXVECTOR3 out;
01645 
01646     D3DXMatrixMultiply(&m, pworld, pview);
01647     D3DXMatrixMultiply(&m, &m, pprojection);
01648     D3DXMatrixInverse(&m, NULL, &m);
01649     out.x = 2.0f * ( pv->x - pviewport->X ) / pviewport->Width - 1.0f;
01650     out.y = 1.0f - 2.0f * ( pv->y - pviewport->Y ) / pviewport->Height;
01651     out.z = ( pv->z - pviewport->MinZ) / ( pviewport->MaxZ - pviewport->MinZ );
01652     D3DXVec3TransformCoord(&out, &out, &m);
01653     *pout = out;
01654     return pout;
01655 }
01656 
01657 D3DXVECTOR3* WINAPI D3DXVec3UnprojectArray(D3DXVECTOR3* out, UINT outstride, CONST D3DXVECTOR3* in, UINT instride, CONST D3DVIEWPORT9* viewport, CONST D3DXMATRIX* projection, CONST D3DXMATRIX* view, CONST D3DXMATRIX* world, UINT elements)
01658 {
01659     UINT i;
01660 
01661     for (i = 0; i < elements; ++i) {
01662         D3DXVec3Unproject(
01663             (D3DXVECTOR3*)((char*)out + outstride * i),
01664             (CONST D3DXVECTOR3*)((const char*)in + instride * i),
01665             viewport, projection, view, world);
01666     }
01667     return out;
01668 }
01669 
01670 /*_________________D3DXVec4_____________________*/
01671 
01672 D3DXVECTOR4* WINAPI D3DXVec4BaryCentric(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv1, CONST D3DXVECTOR4 *pv2, CONST D3DXVECTOR4 *pv3, FLOAT f, FLOAT g)
01673 {
01674     pout->x = (1.0f-f-g) * (pv1->x) + f * (pv2->x) + g * (pv3->x);
01675     pout->y = (1.0f-f-g) * (pv1->y) + f * (pv2->y) + g * (pv3->y);
01676     pout->z = (1.0f-f-g) * (pv1->z) + f * (pv2->z) + g * (pv3->z);
01677     pout->w = (1.0f-f-g) * (pv1->w) + f * (pv2->w) + g * (pv3->w);
01678     return pout;
01679 }
01680 
01681 D3DXVECTOR4* WINAPI D3DXVec4CatmullRom(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv0, CONST D3DXVECTOR4 *pv1, CONST D3DXVECTOR4 *pv2, CONST D3DXVECTOR4 *pv3, FLOAT s)
01682 {
01683     pout->x = 0.5f * (2.0f * pv1->x + (pv2->x - pv0->x) *s + (2.0f *pv0->x - 5.0f * pv1->x + 4.0f * pv2->x - pv3->x) * s * s + (pv3->x -3.0f * pv2->x + 3.0f * pv1->x - pv0->x) * s * s * s);
01684     pout->y = 0.5f * (2.0f * pv1->y + (pv2->y - pv0->y) *s + (2.0f *pv0->y - 5.0f * pv1->y + 4.0f * pv2->y - pv3->y) * s * s + (pv3->y -3.0f * pv2->y + 3.0f * pv1->y - pv0->y) * s * s * s);
01685     pout->z = 0.5f * (2.0f * pv1->z + (pv2->z - pv0->z) *s + (2.0f *pv0->z - 5.0f * pv1->z + 4.0f * pv2->z - pv3->z) * s * s + (pv3->z -3.0f * pv2->z + 3.0f * pv1->z - pv0->z) * s * s * s);
01686     pout->w = 0.5f * (2.0f * pv1->w + (pv2->w - pv0->w) *s + (2.0f *pv0->w - 5.0f * pv1->w + 4.0f * pv2->w - pv3->w) * s * s + (pv3->w -3.0f * pv2->w + 3.0f * pv1->w - pv0->w) * s * s * s);
01687     return pout;
01688 }
01689 
01690 D3DXVECTOR4* WINAPI D3DXVec4Cross(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv1, CONST D3DXVECTOR4 *pv2, CONST D3DXVECTOR4 *pv3)
01691 {
01692     D3DXVECTOR4 out;
01693     out.x = pv1->y * (pv2->z * pv3->w - pv3->z * pv2->w) - pv1->z * (pv2->y * pv3->w - pv3->y * pv2->w) + pv1->w * (pv2->y * pv3->z - pv2->z *pv3->y);
01694     out.y = -(pv1->x * (pv2->z * pv3->w - pv3->z * pv2->w) - pv1->z * (pv2->x * pv3->w - pv3->x * pv2->w) + pv1->w * (pv2->x * pv3->z - pv3->x * pv2->z));
01695     out.z = pv1->x * (pv2->y * pv3->w - pv3->y * pv2->w) - pv1->y * (pv2->x *pv3->w - pv3->x * pv2->w) + pv1->w * (pv2->x * pv3->y - pv3->x * pv2->y);
01696     out.w = -(pv1->x * (pv2->y * pv3->z - pv3->y * pv2->z) - pv1->y * (pv2->x * pv3->z - pv3->x *pv2->z) + pv1->z * (pv2->x * pv3->y - pv3->x * pv2->y));
01697     *pout = out;
01698     return pout;
01699 }
01700 
01701 D3DXVECTOR4* WINAPI D3DXVec4Hermite(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv1, CONST D3DXVECTOR4 *pt1, CONST D3DXVECTOR4 *pv2, CONST D3DXVECTOR4 *pt2, FLOAT s)
01702 {
01703     FLOAT h1, h2, h3, h4;
01704 
01705     h1 = 2.0f * s * s * s - 3.0f * s * s + 1.0f;
01706     h2 = s * s * s - 2.0f * s * s + s;
01707     h3 = -2.0f * s * s * s + 3.0f * s * s;
01708     h4 = s * s * s - s * s;
01709 
01710     pout->x = h1 * (pv1->x) + h2 * (pt1->x) + h3 * (pv2->x) + h4 * (pt2->x);
01711     pout->y = h1 * (pv1->y) + h2 * (pt1->y) + h3 * (pv2->y) + h4 * (pt2->y);
01712     pout->z = h1 * (pv1->z) + h2 * (pt1->z) + h3 * (pv2->z) + h4 * (pt2->z);
01713     pout->w = h1 * (pv1->w) + h2 * (pt1->w) + h3 * (pv2->w) + h4 * (pt2->w);
01714     return pout;
01715 }
01716 
01717 D3DXVECTOR4* WINAPI D3DXVec4Normalize(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv)
01718 {
01719     D3DXVECTOR4 out;
01720     FLOAT norm;
01721 
01722     norm = D3DXVec4Length(pv);
01723 
01724     out.x = pv->x / norm;
01725     out.y = pv->y / norm;
01726     out.z = pv->z / norm;
01727     out.w = pv->w / norm;
01728 
01729     *pout = out;
01730     return pout;
01731 }
01732 
01733 D3DXVECTOR4* WINAPI D3DXVec4Transform(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv, CONST D3DXMATRIX *pm)
01734 {
01735     D3DXVECTOR4 out;
01736     out.x = pm->u.m[0][0] * pv->x + pm->u.m[1][0] * pv->y + pm->u.m[2][0] * pv->z + pm->u.m[3][0] * pv->w;
01737     out.y = pm->u.m[0][1] * pv->x + pm->u.m[1][1] * pv->y + pm->u.m[2][1] * pv->z + pm->u.m[3][1] * pv->w;
01738     out.z = pm->u.m[0][2] * pv->x + pm->u.m[1][2] * pv->y + pm->u.m[2][2] * pv->z + pm->u.m[3][2] * pv->w;
01739     out.w = pm->u.m[0][3] * pv->x + pm->u.m[1][3] * pv->y + pm->u.m[2][3] * pv->z + pm->u.m[3][3] * pv->w;
01740     *pout = out;
01741     return pout;
01742 }
01743 
01744 D3DXVECTOR4* WINAPI D3DXVec4TransformArray(D3DXVECTOR4* out, UINT outstride, CONST D3DXVECTOR4* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements)
01745 {
01746     UINT i;
01747 
01748     for (i = 0; i < elements; ++i) {
01749         D3DXVec4Transform(
01750             (D3DXVECTOR4*)((char*)out + outstride * i),
01751             (CONST D3DXVECTOR4*)((const char*)in + instride * i),
01752             matrix);
01753     }
01754     return out;
01755 }

Generated on Sun May 27 2012 04:22:11 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.