This is h3Dmat.c in view mode; [Download] [Up]
#include <string.h>
#include <math.h>
#include "h3D.h"
/*
* Internal C functions
*/
void h3D_translate(display disp, float dx, float dy, float dz);
void h3D_scale(display disp, float sx, float sy, float sz);
void h3D_xRotationCS(display disp);
void h3D_xRotationResetCS(display disp);
void h3D_yRotationCS(display disp);
void h3D_zRotationCS(display disp, float cosAngle, float sinAngle);
void h3D_perspective(display disp);
void h3D_setUnitMatrix(display disp);
void
h3D_render3D(display disp, int n, float *x, float *y, float *z, float **results)
{
threeD_t *threeD;
float h, *u = results[0], *v = results[1], *w = results[2];
register float *mat;
threeD = disp->threeDWorkArea; /* set local pointer */
mat = threeD->matrix;
while (n--) {
h = mat[12] * *x + mat[13] * *y + mat[14] * *z + mat[15];
*u++ = (mat[0] * *x + mat[1] * *y + mat[2] * *z + mat[3]) / h;
*v++ = (mat[4] * *x++ + mat[5] * *y++ + mat[6] * *z++ +
mat[7]) / h;
*w++ = h;
}
return;
}
/* same as above, but not interested in depth information */
void
h3D_render2D(display disp, int n, float *x, float *y, float *z, float **results)
{
threeD_t *threeD;
float h, *u = results[0], *v = results[1];
register float *mat;
threeD = disp->threeDWorkArea; /* set local pointer */
mat = threeD->matrix;
while (n--) {
h = mat[12] * *x + mat[13] * *y + mat[14] * *z + mat[15];
*u++ = (mat[0] * *x + mat[1] * *y + mat[2] * *z + mat[3]) / h;
*v++ = (mat[4] * *x++ + mat[5] * *y++ + mat[6] * *z++ +
mat[7]) / h;
}
return;
}
void
h3D_renderXYShow(display disp, float *coords)
{
threeD_t *threeD;
float h;
float prevX, prevY, newX, newY;
register float *mat, *res, *x, *y, *z;
int nCoords;
threeD = disp->threeDWorkArea; /* set local pointer */
nCoords = threeD->nScatterPoints;
if (nCoords <= 0)
return;
x = &coords[0];
y = &coords[1];
z = &coords[2];
mat = threeD->matrix;
res = threeD->scatterResults;
/* save first XY pair */
h = mat[12] * *x + mat[13] * *y + mat[14] * *z + mat[15];
prevX = (mat[0] * *x + mat[1] * *y + mat[2] * *z + mat[3]) / h;
prevY = (mat[4] * *x + mat[5] * *y + mat[6] * *z + mat[7]) / h;
*res++ = prevX;
*res++ = prevY;
x +=3;
y +=3;
z +=3;
nCoords--;
/* now save the increments from previous coord */
while (nCoords--) {
h = mat[12] * *x + mat[13] * *y + mat[14] * *z + mat[15];
newX = (mat[0] * *x + mat[1] * *y + mat[2] * *z + mat[3]) / h;
newY = (mat[4] * *x + mat[5] * *y + mat[6] * *z + mat[7]) / h;
*res++ = newX - prevX;
*res++ = newY - prevY;
prevX = newX;
prevY = newY;
x +=3;
y +=3;
z +=3;
}
*res++ = 0.0;
*res++ = 0.0;
return;
}
/* Same as above but just save coords, not differences. Used for PS output */
void
h3D_renderXYPS(display disp, float *coords)
{
threeD_t *threeD;
float h;
register float *mat, *res, *x, *y, *z;
int nCoords;
threeD = disp->threeDWorkArea; /* set local pointer */
nCoords = threeD->nScatterPoints;
if (nCoords <= 0)
return;
x = &coords[0];
y = &coords[1];
z = &coords[2];
mat = threeD->matrix;
res = threeD->scatterResults;
while (nCoords--) {
h = mat[12] * *x + mat[13] * *y + mat[14] * *z + mat[15];
*res++ = (mat[0] * *x + mat[1] * *y + mat[2] * *z + mat[3]) / h;
*res++ = (mat[4] * *x + mat[5] * *y + mat[6] * *z + mat[7]) / h;
x +=3;
y +=3;
z +=3;
}
return;
}
void
h3D_translate(display disp, float dx, float dy, float dz)
{
threeD_t *threeD;
register float *mat, *thisrow, *lastrow;
register short int n = 4;
threeD = disp->threeDWorkArea; /* set local pointer */
mat = threeD->matrix;
thisrow = mat;
lastrow = mat + 12;
while (n--)
*thisrow++ += dx * *lastrow++;
n = 4;
lastrow -= 4;
while (n--)
*thisrow++ += dy * *lastrow++;
n = 4;
lastrow -= 4;
while (n--)
*thisrow++ += dz * *lastrow++;
return;
}
void
h3D_scale(display disp, float sx, float sy, float sz)
{
threeD_t *threeD;
register float *mat, *thisrow;
register short int n = 4;
threeD = disp->threeDWorkArea; /* set local pointer */
mat = threeD->matrix;
thisrow = mat;
while (n--)
*thisrow++ *= sx;
n = 4;
while (n--)
*thisrow++ *= sy;
n = 4;
while (n--)
*thisrow++ *= sz;
return;
}
void
h3D_xRotationCS(display disp)
{
threeD_t *threeD;
register float temp, *mat, *thisrow, *otherrow;
register short int n = 4;
threeD = disp->threeDWorkArea; /* set local pointer */
mat = threeD->matrix;
thisrow = mat + 4;
otherrow = mat + 8;
while (n--) {
temp = threeD->cosPhi * *thisrow - threeD->sinPhi * *otherrow;
*otherrow++ = threeD->sinPhi * *thisrow + threeD->cosPhi * *otherrow;
*thisrow++ = temp;
}
return;
}
void
h3D_xRotationResetCS(display disp)
{
threeD_t *threeD;
register float temp, *mat, *thisrow, *otherrow;
register short int n = 4;
threeD = disp->threeDWorkArea; /* set local pointer */
mat = threeD->matrix;
thisrow = mat + 4;
otherrow = mat + 8;
while (n--) {
temp = *otherrow;
*otherrow++ = -*thisrow;
*thisrow++ = temp;
}
return;
}
void
h3D_yRotationCS(display disp)
{
threeD_t *threeD;
register float temp, *mat, *thisrow, *otherrow;
register short int n = 4;
threeD = disp->threeDWorkArea; /* set local pointer */
mat = threeD->matrix;
thisrow = mat;
otherrow = mat + 8;
while (n--) {
temp = threeD->cosTheta * *thisrow + threeD->sinTheta * *otherrow;
*otherrow++ = -threeD->sinTheta * *thisrow + threeD->cosTheta * *otherrow;
*thisrow++ = temp;
}
return;
}
void
h3D_zRotationCS(display disp, float cosAngle, float sinAngle)
{
threeD_t *threeD;
register float temp, *mat, *thisrow, *otherrow;
register short int n = 4;
threeD = disp->threeDWorkArea; /* set local pointer */
mat = threeD->matrix;
thisrow = mat;
otherrow = mat + 4;
while (n--) {
temp = cosAngle * *thisrow - sinAngle * *otherrow;
*otherrow++ = sinAngle * *thisrow + cosAngle * *otherrow;
*thisrow++ = temp;
}
return;
}
void
h3D_perspective(display disp)
{
threeD_t *threeD;
register float inv_d, *mat, *thisrow, *otherrow;
register short int n = 4;
threeD = disp->threeDWorkArea; /* set local pointer */
mat = threeD->matrix;
thisrow = mat + 12;
otherrow = mat + 8;
inv_d = 1.0/disp->dist;
while (n--) {
*thisrow++ -= inv_d * *otherrow;
*otherrow++ = 0.;
}
return;
}
/*
* Reset matrix to unity
*/
void
h3D_setUnitMatrix(display disp)
{
threeD_t *threeD;
register float *mat;
register short int n = 16;
threeD = disp->threeDWorkArea; /* set local pointer */
mat = threeD->matrix;
while (n--) *mat++ = 0.0;
mat = threeD->matrix;
mat[0] = mat[5] = mat[10] = mat[15] = 1.0;
return;
}
/*
* The starting point for rotations and dist changes
*/
void
h3D_reScaleMatrix(display disp)
{
threeD_t *threeD;
threeD = disp->threeDWorkArea; /* set local pointer */
h3D_setUnitMatrix(disp);
h3D_translate(disp, -(threeD->limits[0] + threeD->limits[3]) / 2., -(threeD->limits[1] + threeD->limits[4]) / 2.,
-(threeD->limits[2] + threeD->limits[5]) / 2.);
h3D_scale(disp, 1./ (threeD->limits[3] - threeD->limits[0]), 1./ (threeD->limits[4] - threeD->limits[1]),
1./ (threeD->limits[5] - threeD->limits[2]));
h3D_xRotationResetCS(disp);
memmove(threeD->thetaSave, threeD->matrix, 16 * sizeof(float));
threeD->thetaIsSaved = 1;
threeD->phiIsSaved = threeD->distIsSaved = 0;
return;
}
/*
* Starting point followed by theta, phi, and dist changes.
* Can skip the starting point if theta is cached.
*/
void
h3D_newTheta(display disp)
{
threeD_t *threeD;
threeD = disp->threeDWorkArea; /* set local pointer */
if (threeD->thetaIsSaved)
memmove(threeD->matrix, threeD->thetaSave, 16 * sizeof(float));
else
h3D_reScaleMatrix(disp);
threeD->phiIsSaved = threeD->distIsSaved = 0;
threeD->cosTheta = cos(disp->theta);
threeD->sinTheta = sin(disp->theta);
h3D_yRotationCS(disp); /* theta change */
h3D_xRotationCS(disp); /* phi change */
h3D_perspective(disp); /* dist change */
/* Have to reset the 'near face' every time theta changes */
h3D_setNearFace(disp);
/* Show that display re-calculation will be needed */
h3D_setDirty(disp);
return;
}
/*
* Starting point followed by theta, phi, and dist changes.
* Can skip starting point + theta change, if phi is cached.
*/
void
h3D_newPhi(display disp)
{
threeD_t *threeD;
threeD = disp->threeDWorkArea; /* set local pointer */
if (threeD->phiIsSaved)
memmove(threeD->matrix, threeD->phiSave, 16 * sizeof(float));
else {
if (threeD->thetaIsSaved)
memmove(threeD->matrix, threeD->thetaSave, 16 * sizeof(float));
else
h3D_reScaleMatrix(disp);
h3D_yRotationCS(disp); /* theta change */
memmove(threeD->phiSave, threeD->matrix, 16 * sizeof(float));
threeD->phiIsSaved = 1;
}
threeD->distIsSaved = 0;
threeD->cosPhi = cos(disp->phi);
threeD->sinPhi = sin(disp->phi);
h3D_xRotationCS(disp); /* phi change */
h3D_perspective(disp); /* dist change */
/* Show that display re-calculation will be needed */
h3D_setDirty(disp);
return;
}
/*
* Starting point followed by theta, phi, and dist changes.
* Can skip the starting point + theta + phi changes, if dist is cached
*/
void
h3D_newDist(display disp)
{
threeD_t *threeD;
threeD = disp->threeDWorkArea; /* set local pointer */
if (threeD->distIsSaved)
memmove(threeD->matrix, threeD->distSave, 16 * sizeof(float));
else {
if (threeD->thetaIsSaved)
memmove(threeD->matrix, threeD->thetaSave, 16 * sizeof(float));
else
h3D_reScaleMatrix(disp);
h3D_yRotationCS(disp); /* theta change */
h3D_xRotationCS(disp); /* phi change */
memmove(threeD->distSave, threeD->matrix, 16 * sizeof(float));
threeD->distIsSaved = 1;
}
h3D_perspective(disp); /* dist change */
/* Show that display re-calculation will be needed */
h3D_setDirty(disp);
return;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.