windows-nt/Source/XPSP1/NT/multimedia/opengl/scrsave/common/math.c
2020-09-26 16:20:57 +08:00

198 lines
4.9 KiB
C

/******************************Module*Header*******************************\
* Module Name: math.c
*
* Misc. useful math utility functions.
*
* Copyright (c) 1994 Microsoft Corporation
*
\**************************************************************************/
#include <windows.h>
#include <GL\gl.h>
#include <math.h>
#include "sscommon.h"
#define ZERO_EPS 0.00000001
POINT3D ss_ptZero = {0.0f, 0.0f, 0.0f};
void ss_xformPoint(POINT3D *ptOut, POINT3D *ptIn, MATRIX *mat)
{
double x, y, z;
x = (ptIn->x * mat->M[0][0]) + (ptIn->y * mat->M[0][1]) +
(ptIn->z * mat->M[0][2]) + mat->M[0][3];
y = (ptIn->x * mat->M[1][0]) + (ptIn->y * mat->M[1][1]) +
(ptIn->z * mat->M[1][2]) + mat->M[1][3];
z = (ptIn->x * mat->M[2][0]) + (ptIn->y * mat->M[2][1]) +
(ptIn->z * mat->M[2][2]) + mat->M[2][3];
ptOut->x = (float) x;
ptOut->y = (float) y;
ptOut->z = (float) z;
}
void ss_xformNorm(POINT3D *ptOut, POINT3D *ptIn, MATRIX *mat)
{
double x, y, z;
double len;
x = (ptIn->x * mat->M[0][0]) + (ptIn->y * mat->M[0][1]) +
(ptIn->z * mat->M[0][2]);
y = (ptIn->x * mat->M[1][0]) + (ptIn->y * mat->M[1][1]) +
(ptIn->z * mat->M[1][2]);
z = (ptIn->x * mat->M[2][0]) + (ptIn->y * mat->M[2][1]) +
(ptIn->z * mat->M[2][2]);
len = (x * x) + (y * y) + (z * z);
if (len >= ZERO_EPS)
len = 1.0 / sqrt(len);
else
len = 1.0;
ptOut->x = (float) (x * len);
ptOut->y = (float) (y * len);
ptOut->z = (float) (z * len);
return;
}
void ss_matrixIdent(MATRIX *mat)
{
mat->M[0][0] = 1.0f; mat->M[0][1] = 0.0f;
mat->M[0][2] = 0.0f; mat->M[0][3] = 0.0f;
mat->M[1][0] = 0.0f; mat->M[1][1] = 1.0f;
mat->M[1][2] = 0.0f; mat->M[1][3] = 0.0f;
mat->M[2][0] = 0.0f; mat->M[2][1] = 0.0f;
mat->M[2][2] = 1.0f; mat->M[2][3] = 0.0f;
mat->M[3][0] = 0.0f; mat->M[3][1] = 0.0f;
mat->M[3][2] = 0.0f; mat->M[3][3] = 1.0f;
}
void ss_matrixRotate(MATRIX *m, double xTheta, double yTheta, double zTheta)
{
float xScale, yScale, zScale;
float sinX, cosX;
float sinY, cosY;
float sinZ, cosZ;
xScale = m->M[0][0];
yScale = m->M[1][1];
zScale = m->M[2][2];
sinX = (float) sin(xTheta);
cosX = (float) cos(xTheta);
sinY = (float) sin(yTheta);
cosY = (float) cos(yTheta);
sinZ = (float) sin(zTheta);
cosZ = (float) cos(zTheta);
m->M[0][0] = (float) ((cosZ * cosY) * xScale);
m->M[0][1] = (float) ((cosZ * -sinY * -sinX + sinZ * cosX) * yScale);
m->M[0][2] = (float) ((cosZ * -sinY * cosX + sinZ * sinX) * zScale);
m->M[1][0] = (float) (-sinZ * cosY * xScale);
m->M[1][1] = (float) ((-sinZ * -sinY * -sinX + cosZ * cosX) * yScale);
m->M[1][2] = (float) ((-sinZ * -sinY * cosX + cosZ * sinX) * zScale);
m->M[2][0] = (float) (sinY * xScale);
m->M[2][1] = (float) (cosY * -sinX * yScale);
m->M[2][2] = (float) (cosY * cosX * zScale);
}
void ss_matrixTranslate(MATRIX *m, double xTrans, double yTrans,
double zTrans)
{
m->M[0][3] = (float) xTrans;
m->M[1][3] = (float) yTrans;
m->M[2][3] = (float) zTrans;
}
void ss_matrixMult( MATRIX *m1, MATRIX *m2, MATRIX *m3 )
{
int i, j;
for( j = 0; j < 4; j ++ ) {
for( i = 0; i < 4; i ++ ) {
m1->M[j][i] = m2->M[j][0] * m3->M[0][i] +
m2->M[j][1] * m3->M[1][i] +
m2->M[j][2] * m3->M[2][i] +
m2->M[j][3] * m3->M[3][i];
}
}
}
void ss_calcNorm(POINT3D *norm, POINT3D *p1, POINT3D *p2, POINT3D *p3)
{
float crossX, crossY, crossZ;
float abX, abY, abZ;
float acX, acY, acZ;
float sqrLength;
float invLength;
abX = p2->x - p1->x; // calculate p2 - p1
abY = p2->y - p1->y;
abZ = p2->z - p1->z;
acX = p3->x - p1->x; // calculate p3 - p1
acY = p3->y - p1->y;
acZ = p3->z - p1->z;
crossX = (abY * acZ) - (abZ * acY); // get cross product
crossY = (abZ * acX) - (abX * acZ); // (p2 - p1) X (p3 - p1)
crossZ = (abX * acY) - (abY * acX);
sqrLength = (crossX * crossX) + (crossY * crossY) +
(crossZ * crossZ);
if (sqrLength > ZERO_EPS)
invLength = (float) (1.0 / sqrt(sqrLength));
else
invLength = 1.0f;
norm->x = crossX * invLength;
norm->y = crossY * invLength;
norm->z = crossZ * invLength;
}
void ss_normalizeNorm( POINT3D *n )
{
float len;
len = (n->x * n->x) + (n->y * n->y) + (n->z * n->z);
if (len > ZERO_EPS)
len = (float) (1.0 / sqrt(len));
else
len = 1.0f;
n->x *= len;
n->y *= len;
n->z *= len;
}
void ss_normalizeNorms(POINT3D *p, ULONG cPts)
{
float len;
ULONG i;
for (i = 0; i < cPts; i++, p++) {
len = (p->x * p->x) + (p->y * p->y) + (p->z * p->z);
if (len > ZERO_EPS)
len = (float) (1.0 / sqrt(len));
else
len = 1.0f;
p->x *= len;
p->y *= len;
p->z *= len;
}
}