135 lines
4.0 KiB
C
135 lines
4.0 KiB
C
/*
|
|
* Copyright (c) 1986, 1987, 1988, 1989 by Sun Microsystems, Inc.
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
* purpose and without fee is hereby granted, provided that the above
|
|
* copyright notice appear in all copies and that both that copyright
|
|
* notice and this permission notice are retained, and that the name
|
|
* of Sun Microsystems, Inc., not be used in advertising or publicity
|
|
* pertaining to this software without specific, written prior permission.
|
|
* Sun Microsystems, Inc., makes no representations about the suitability
|
|
* of this software or the interface defined in this software for any
|
|
* purpose. It is provided "as is" without express or implied warranty.
|
|
*/
|
|
#ifndef lint
|
|
static char sccsid[] = "@(#)setmatrix.c 1.1 94/10/31 Copyr 1986 Sun Micro";
|
|
#endif
|
|
|
|
/*
|
|
* Copyright (c) 1986 by Sun Microsystems, Inc.
|
|
*/
|
|
#include "coretypes.h"
|
|
#include "corevars.h"
|
|
|
|
double sin(), cos();
|
|
|
|
/*
|
|
* Build image transformation matrix from view state variables.
|
|
*
|
|
* This transform scales; rotates (in x, y, z order) about point 0,0,0;
|
|
* then translates
|
|
*/
|
|
_core_setmatrix(segptr)
|
|
segstruc *segptr;
|
|
|
|
{
|
|
register float *pf;
|
|
register segstruc *asegptr;
|
|
float xform[4][4];
|
|
int i, j, k;
|
|
|
|
asegptr = segptr;
|
|
if (identchk(asegptr)) {
|
|
asegptr->idenflag = TRUE;
|
|
return (0);
|
|
}
|
|
asegptr->idenflag = FALSE;
|
|
|
|
_core_identity(&xform[0][0]);
|
|
if (asegptr->type >= XLATE2) {
|
|
xform[3][0] = asegptr->segats.translat[0]; /* translate */
|
|
xform[3][1] = asegptr->segats.translat[1];
|
|
xform[3][2] = asegptr->segats.translat[2];
|
|
}
|
|
if (asegptr->type == XFORM2) {
|
|
_core_push(&xform[0][0]);
|
|
if (asegptr->segats.rotate[2] != 0.) {
|
|
_core_identity(&xform[0][0]); /* rotate about z */
|
|
xform[0][0] = xform[1][1] = cos(asegptr->segats.rotate[2]);
|
|
xform[0][1] = sin(asegptr->segats.rotate[2]);
|
|
xform[1][0] = -xform[0][1];
|
|
_core_push(&xform[0][0]);
|
|
(void)_core_matcon();
|
|
}
|
|
if (asegptr->segats.rotate[1] != 0.) {
|
|
_core_identity(&xform[0][0]); /* rotate about y */
|
|
xform[0][0] = xform[2][2] = cos(asegptr->segats.rotate[1]);
|
|
xform[2][0] = sin(asegptr->segats.rotate[1]);
|
|
xform[0][2] = -xform[2][0];
|
|
_core_push(&xform[0][0]);
|
|
(void)_core_matcon();
|
|
}
|
|
if (asegptr->segats.rotate[0] != 0.) {
|
|
_core_identity(&xform[0][0]); /* rotate about x */
|
|
xform[1][1] = xform[2][2] = cos(asegptr->segats.rotate[0]);
|
|
xform[1][2] = sin(asegptr->segats.rotate[0]);
|
|
xform[2][1] = -xform[1][2];
|
|
_core_push(&xform[0][0]);
|
|
(void)_core_matcon();
|
|
}
|
|
if (asegptr->segats.scale[0] != 1. ||
|
|
asegptr->segats.scale[1] != 1. ||
|
|
asegptr->segats.scale[2] != 1.) {
|
|
_core_identity(&xform[0][0]); /* scale */
|
|
xform[0][0] = asegptr->segats.scale[0];
|
|
xform[1][1] = asegptr->segats.scale[1];
|
|
xform[2][2] = asegptr->segats.scale[2];
|
|
_core_push(&xform[0][0]);
|
|
(void)_core_matcon();
|
|
}
|
|
_core_pop(&xform[0][0]);
|
|
}
|
|
/* convert xform to integer imxform */
|
|
/* don't bother with last column */
|
|
/* since it's never used */
|
|
pf = (float *) xform;
|
|
for (i = 0; i < 3; i++) { /* scale and rotate coefficients */
|
|
for (j = 0; j < 3; j++) { /* have MSW as signed 15 bit */
|
|
k = (int) (*pf); /* integer part and LSW as signed 15 */
|
|
*pf -= (float) k; /* bit fractional part ( 1= 2 to the */
|
|
*pf *= 32767.0; /* -15 power, or 1/32768 ). */
|
|
asegptr->imxform[i][j] = (k << 16) | (_core_roundf(pf) & 0xFFFF);
|
|
pf++;
|
|
}
|
|
pf++;
|
|
}
|
|
|
|
/* translate coeffs are signed int. */
|
|
asegptr->imxform[3][0] = _core_roundf(pf);
|
|
pf++;
|
|
asegptr->imxform[3][1] = _core_roundf(pf);
|
|
pf++;
|
|
asegptr->imxform[3][2] = _core_roundf(pf);
|
|
|
|
return (0);
|
|
}
|
|
|
|
static float idxfrmparams[] = {1., 1., 1., 0., 0., 0., 0., 0., 0.};
|
|
|
|
/*
|
|
* Check for identity matrix
|
|
*/
|
|
static int
|
|
identchk(asegptr)
|
|
register segstruc *asegptr;
|
|
{
|
|
register float *ptr1, *ptr2;
|
|
register short i;
|
|
|
|
ptr1 = idxfrmparams;
|
|
ptr2 = &asegptr->segats.scale[0];
|
|
for (i = 0; i < 9; i++)
|
|
if (*ptr1++ != *ptr2++)
|
|
return (0);
|
|
return (1);
|
|
}
|