256 lines
6.9 KiB
C
256 lines
6.9 KiB
C
/*
|
|
** Copyright 1992, Silicon Graphics, Inc.
|
|
** All Rights Reserved.
|
|
**
|
|
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
|
|
** the contents of this file may not be disclosed to third parties, copied or
|
|
** duplicated in any form, in whole or in part, without the prior written
|
|
** permission of Silicon Graphics, Inc.
|
|
**
|
|
** RESTRICTED RIGHTS LEGEND:
|
|
** Use, duplication or disclosure by the Government is subject to restrictions
|
|
** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
|
|
** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
|
|
** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
|
|
** rights reserved under the Copyright Laws of the United States.
|
|
*/
|
|
|
|
#include <windows.h>
|
|
#include <GL/gl.h>
|
|
#include "conform.h"
|
|
#include "util.h"
|
|
#include "utile.h"
|
|
|
|
|
|
eval2Rec *MakeEval2(long majorOrder, long minorOrder, long dim, long dataType,
|
|
float *controls)
|
|
{
|
|
long i, controlArrayLength;
|
|
|
|
eval2Rec *e = (eval2Rec *)MALLOC(sizeof(eval2Rec));
|
|
e->majorOrder = majorOrder;
|
|
e->minorOrder = minorOrder;
|
|
e->dim = dim;
|
|
e->dataTypeEnum = dataType;
|
|
|
|
e->cU = (float *)MALLOC(e->majorOrder*sizeof(float));
|
|
e->cV = (float *)MALLOC(e->minorOrder*sizeof(float));
|
|
e->cUDeriv = (float *)MALLOC((e->majorOrder-1)*sizeof(float));
|
|
e->cVDeriv = (float *)MALLOC((e->minorOrder-1)*sizeof(float));
|
|
|
|
controlArrayLength = e->majorOrder * e->minorOrder * e->dim;
|
|
e->controls = (GLfloat *)MALLOC(controlArrayLength*sizeof(GLfloat));
|
|
for (i = 0; i < controlArrayLength; i++) {
|
|
e->controls[i] = controls[i];
|
|
}
|
|
return e;
|
|
}
|
|
|
|
evalDomainRec *MakeDomain(float uStart, float uEnd, long uCount, float vStart,
|
|
float vEnd, long vCount)
|
|
{
|
|
evalDomainRec *d = (evalDomainRec *)MALLOC(sizeof(evalDomainRec));
|
|
d->uStart = uStart;
|
|
d->uEnd = uEnd;
|
|
d->uCount = uCount;
|
|
d->du = (uEnd - uStart) / (float)uCount;
|
|
|
|
d->vStart = vStart;
|
|
d->vEnd = vEnd;
|
|
d->vCount = vCount;
|
|
d->dv = (vEnd - vStart) / (float)vCount;
|
|
return d;
|
|
}
|
|
|
|
void FreeDomain(evalDomainRec *d)
|
|
{
|
|
FREE(d);
|
|
}
|
|
|
|
void FreeEval2(eval2Rec *e)
|
|
{
|
|
|
|
FREE(e->cU);
|
|
FREE(e->cV);
|
|
FREE(e->cUDeriv);
|
|
FREE(e->cVDeriv);
|
|
FREE(e->controls);
|
|
FREE(e);
|
|
}
|
|
|
|
void CRow(float a, float b, long n, float *c)
|
|
{
|
|
float tmp1, tmp2;
|
|
long i, m;
|
|
|
|
c[0] = 1;
|
|
for (m = 1; m <= n; m++) {
|
|
tmp1 = c[0];
|
|
c[0] *= a;
|
|
for (i = 1; i < m; i++) {
|
|
tmp2 = c[i];
|
|
c[i] = a * tmp2 + b * tmp1;
|
|
tmp1 = tmp2;
|
|
}
|
|
c[m] = b * tmp1;
|
|
}
|
|
}
|
|
|
|
/*
|
|
** This routine returns an array containing 1/n * d(B_sub_ij)/da as
|
|
** well as B_sub_i_j; since we are going to normalize the cross product
|
|
** of the output B_subij * v. The 1/n factor drops out.
|
|
*/
|
|
void CRowWithDeriv(float a, float b, long n, float *c, float *cDeriv)
|
|
{
|
|
long i, m;
|
|
|
|
c[0] = 1;
|
|
cDeriv[0] = 0;
|
|
for (m = 1; m <= n; m++) {
|
|
cDeriv[0] = c[0];
|
|
c[0] *= a;
|
|
for (i = 1; i < m; i++) {
|
|
cDeriv[i] = c[i];
|
|
c[i] = a * cDeriv[i] + b * cDeriv[i-1];
|
|
}
|
|
c[m] = b * cDeriv[m-1];
|
|
}
|
|
}
|
|
|
|
void Evaluate2(eval2Rec *e, float u, float v, float *out)
|
|
{
|
|
long i, j, k, index;
|
|
float coeff;
|
|
|
|
for (k = 0; k < e->dim; k++) {
|
|
out[k] = 0.0;
|
|
}
|
|
|
|
CRow(1.0-u, u, e->majorOrder-1, e->cU);
|
|
CRow(1.0-v, v, e->minorOrder-1, e->cV);
|
|
for (i = 0; i < e->majorOrder; i++) {
|
|
for (j = 0; j < e->minorOrder; j++) {
|
|
index = e->dim * (e->minorOrder * i + j);
|
|
coeff = e->cU[i] * e->cV[j];
|
|
for (k = 0; k < e->dim; k++) {
|
|
out[k] += coeff * e->controls[index+k];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
** This routine returns the cross product of two vectors if the normalize
|
|
** flag is GL_TRUE, it normalizes the cross product if the vector has a
|
|
** non-zero length, and returns FALSE if it has a length of zero. 'out'
|
|
** can be either of the two 'in' addresses.
|
|
*/
|
|
long Cross(float *in1, float *in2, float *out, long normalize)
|
|
{
|
|
float tmp[3], length;
|
|
|
|
tmp[0] = in1[1] * in2[2] - in2[1] * in1[2];
|
|
tmp[1] = in1[0] * in1[2] - in1[0] * in2[2];
|
|
tmp[2] = in1[0] * in2[1] - in1[1] * in2[0];
|
|
|
|
out[0] = tmp[0];
|
|
out[1] = tmp[1];
|
|
out[2] = tmp[2];
|
|
|
|
if (normalize == GL_TRUE) {
|
|
length = tmp[0] * tmp[0] + tmp[1] * tmp[1] + tmp[2] * tmp[2];
|
|
if (length > 0.0) {
|
|
length = SQRT(length);
|
|
out[0] /= length;
|
|
out[1] /= length;
|
|
out[2] /= length;
|
|
return GL_TRUE;
|
|
} else {
|
|
return GL_FALSE;
|
|
}
|
|
} else {
|
|
return GL_TRUE;
|
|
}
|
|
}
|
|
|
|
void ClampArray(float *array, float bottom, float top, float dim)
|
|
{
|
|
long i;
|
|
|
|
for (i = 0; i < dim; i++) {
|
|
array[i] = (array[i] > bottom) ? array[i] : bottom;
|
|
array[i] = (array[i] < top) ? array[i] : top;
|
|
}
|
|
}
|
|
|
|
long GetEvalDim(long targetEnum)
|
|
{
|
|
|
|
switch (targetEnum) {
|
|
case GL_MAP1_TEXTURE_COORD_1:
|
|
case GL_MAP2_TEXTURE_COORD_1:
|
|
case GL_MAP1_INDEX:
|
|
case GL_MAP2_INDEX:
|
|
return 1;
|
|
case GL_MAP1_TEXTURE_COORD_2:
|
|
case GL_MAP2_TEXTURE_COORD_2:
|
|
return 2;
|
|
case GL_MAP1_VERTEX_3:
|
|
case GL_MAP2_VERTEX_3:
|
|
case GL_MAP1_NORMAL:
|
|
case GL_MAP2_NORMAL:
|
|
case GL_MAP1_TEXTURE_COORD_3:
|
|
case GL_MAP2_TEXTURE_COORD_3:
|
|
return 3;
|
|
case GL_MAP1_VERTEX_4:
|
|
case GL_MAP2_VERTEX_4:
|
|
case GL_MAP1_COLOR_4:
|
|
case GL_MAP2_COLOR_4:
|
|
case GL_MAP1_TEXTURE_COORD_4:
|
|
case GL_MAP2_TEXTURE_COORD_4:
|
|
return 4;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/*
|
|
** This is not necessarily a complete set, just one that works for
|
|
** everything that we use presently.
|
|
*/
|
|
void ResetEvalToDefault(void)
|
|
{
|
|
float buf[4] = {
|
|
0.0, 0.0, 0.0, 1.0
|
|
};
|
|
|
|
glMap1f(GL_MAP1_VERTEX_4, 0.0, 1.0, 4, 1, buf);
|
|
glMap2f(GL_MAP2_VERTEX_4, 0.0, 1.0, 4, 1, 0.0, 1.0, 4, 1, buf);
|
|
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 1, buf);
|
|
glMap2f(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 1, 0.0, 1.0, 3, 1, buf);
|
|
|
|
glMap1f(GL_MAP1_TEXTURE_COORD_4, 0.0, 1.0, 4, 1, buf);
|
|
glMap2f(GL_MAP2_TEXTURE_COORD_4, 0.0, 1.0, 4, 1, 0.0, 1.0, 4, 1, buf);
|
|
glMap1f(GL_MAP1_TEXTURE_COORD_3, 0.0, 1.0, 3, 1, buf);
|
|
glMap2f(GL_MAP2_TEXTURE_COORD_3, 0.0, 1.0, 3, 1, 0.0, 1.0, 3, 1, buf);
|
|
glMap1f(GL_MAP1_TEXTURE_COORD_2, 0.0, 1.0, 2, 1, buf);
|
|
glMap2f(GL_MAP2_TEXTURE_COORD_2, 0.0, 1.0, 2, 1, 0.0, 1.0, 2, 1, buf);
|
|
glMap1f(GL_MAP1_TEXTURE_COORD_1, 0.0, 1.0, 1, 1, buf);
|
|
glMap2f(GL_MAP2_TEXTURE_COORD_1, 0.0, 1.0, 1, 1, 0.0, 1.0, 1, 1, buf);
|
|
|
|
buf[2] = 1.0;
|
|
glMap1f(GL_MAP1_NORMAL, 0.0, 1.0, 3, 1, buf);
|
|
glMap2f(GL_MAP2_NORMAL, 0.0, 1.0, 3, 1, 0.0, 1.0, 3, 1, buf);
|
|
|
|
buf[0] = 1.0;
|
|
buf[1] = 1.0;
|
|
glMap1f(GL_MAP1_COLOR_4, 0.0, 1.0, 4, 1, buf);
|
|
glMap2f(GL_MAP2_COLOR_4, 0.0, 1.0, 4, 1, 0.0, 1.0, 4, 1, buf);
|
|
|
|
glMap1f(GL_MAP1_INDEX, 0.0, 1.0, 1, 1, buf);
|
|
glMap2f(GL_MAP2_INDEX, 0.0, 1.0, 1, 1, 0.0, 1.0, 1, 1, buf);
|
|
|
|
glDisable(GL_AUTO_NORMAL);
|
|
}
|