home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NEXT Generation 27
/
NEXT27.iso
/
pc
/
demos
/
emperor
/
dx3.exe
/
SDK
/
SAMPLES
/
MISC
/
D3DMATH.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-08-28
|
4KB
|
180 lines
/*==========================================================================
*
* Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
*
* File: d3dmath.c
*
***************************************************************************/
#include <d3d.h>
#include <math.h>
/*
* Normalises the vector v
*/
LPD3DVECTOR
D3DVECTORNormalise(LPD3DVECTOR v)
{
float vx, vy, vz, inv_mod;
vx = v->x;
vy = v->y;
vz = v->z;
if ((vx == 0) && (vy == 0) && (vz == 0))
return v;
inv_mod = (float)(1.0 / sqrt(vx * vx + vy * vy + vz * vz));
v->x = vx * inv_mod;
v->y = vy * inv_mod;
v->z = vz * inv_mod;
return v;
}
/*
* Calculates cross product of a and b.
*/
LPD3DVECTOR
D3DVECTORCrossProduct(LPD3DVECTOR lpd, LPD3DVECTOR lpa, LPD3DVECTOR lpb)
{
lpd->x = lpa->y * lpb->z - lpa->z * lpb->y;
lpd->y = lpa->z * lpb->x - lpa->x * lpb->z;
lpd->z = lpa->x * lpb->y - lpa->y * lpb->x;
return lpd;
}
/*
* lpDst = lpSrc1 * lpSrc2
* lpDst can be equal to lpSrc1 or lpSrc2
*/
LPD3DMATRIX MultiplyD3DMATRIX(LPD3DMATRIX lpDst, LPD3DMATRIX lpSrc1,
LPD3DMATRIX lpSrc2)
{
D3DVALUE M1[4][4], M2[4][4], D[4][4];
int i, r, c;
memcpy(&M1[0][0], lpSrc1, sizeof(D3DMATRIX));
memcpy(&M2[0][0], lpSrc2, sizeof(D3DMATRIX));
for (r = 0; r < 4; r++) {
for (c = 0; c < 4; c++) {
D[r][c] = (float)0.0;
for (i = 0; i < 4; i++)
D[r][c] += M1[r][i] * M2[i][c];
}
}
memcpy(lpDst, &D[0][0], sizeof(D3DMATRIX));
return lpDst;
}
/*
* -1 d = a
*/
LPD3DMATRIX
D3DMATRIXInvert(LPD3DMATRIX d, LPD3DMATRIX a)
{
d->_11 = a->_11;
d->_12 = a->_21;
d->_13 = a->_31;
d->_14 = a->_14;
d->_21 = a->_12;
d->_22 = a->_22;
d->_23 = a->_32;
d->_24 = a->_24;
d->_31 = a->_13;
d->_32 = a->_23;
d->_33 = a->_33;
d->_34 = a->_34;
d->_41 = a->_14;
d->_42 = a->_24;
d->_43 = a->_34;
d->_44 = a->_44;
return d;
}
/*
* Set the rotation part of a matrix such that the vector lpD is the new
* z-axis and lpU is the new y-axis.
*/
LPD3DMATRIX
D3DMATRIXSetRotation(LPD3DMATRIX lpM, LPD3DVECTOR lpD, LPD3DVECTOR lpU)
{
float t;
D3DVECTOR d, u, r;
/*
* Normalise the direction vector.
*/
d.x = lpD->x;
d.y = lpD->y;
d.z = lpD->z;
D3DVECTORNormalise(&d);
u.x = lpU->x;
u.y = lpU->y;
u.z = lpU->z;
/*
* Project u into the plane defined by d and normalise.
*/
t = u.x * d.x + u.y * d.y + u.z * d.z;
u.x -= d.x * t;
u.y -= d.y * t;
u.z -= d.z * t;
D3DVECTORNormalise(&u);
/*
* Calculate the vector pointing along the matrix x axis (in a right
* handed coordinate system) using cross product.
*/
D3DVECTORCrossProduct(&r, &u, &d);
lpM->_11 = r.x;
lpM->_12 = r.y, lpM->_13 = r.z;
lpM->_21 = u.x;
lpM->_22 = u.y, lpM->_23 = u.z;
lpM->_31 = d.x;
lpM->_32 = d.y;
lpM->_33 = d.z;
return lpM;
}
/*
* Calculates a point along a B-Spline curve defined by four points. p
* n output, contain the point. t Position
* along the curve between p2 and p3. This position is a float between 0
* and 1. p1, p2, p3, p4 Points defining spline curve. p, at parameter
* t along the spline curve
*/
void
spline(LPD3DVECTOR p, float t, LPD3DVECTOR p1, LPD3DVECTOR p2,
LPD3DVECTOR p3, LPD3DVECTOR p4)
{
double t2, t3;
float m1, m2, m3, m4;
t2 = (double)(t * t);
t3 = t2 * (double)t;
m1 = (float)((-1.0 * t3) + (2.0 * t2) + (-1.0 * (double)t));
m2 = (float)((3.0 * t3) + (-5.0 * t2) + (0.0 * (double)t) + 2.0);
m3 = (float)((-3.0 * t3) + (4.0 * t2) + (1.0 * (double)t));
m4 = (float)((1.0 * t3) + (-1.0 * t2) + (0.0 * (double)t));
m1 /= (float)2.0;
m2 /= (float)2.0;
m3 /= (float)2.0;
m4 /= (float)2.0;
p->x = p1->x * m1 + p2->x * m2 + p3->x * m3 + p4->x * m4;
p->y = p1->y * m1 + p2->y * m2 + p3->y * m3 + p4->y * m4;
p->z = p1->z * m1 + p2->z * m2 + p3->z * m3 + p4->z * m4;
}