📄 insurfeval.cc
字号:
{
int i,j,x;
surfEvalMachine *temp_em;
switch(which){
case 0: //vertex
vertex_flag = 1;
temp_em = &em_vertex;
break;
case 1: //normal
normal_flag = 1;
temp_em = &em_normal;
break;
case 2: //color
color_flag = 1;
temp_em = &em_color;
break;
default:
texcoord_flag = 1;
temp_em = &em_texcoord;
break;
}
REAL *data = temp_em->ctlPoints;
temp_em->uprime = -1;//initilized
temp_em->vprime = -1;
temp_em->k = k;
temp_em->u1 = ulower;
temp_em->u2 = uupper;
temp_em->ustride = ustride;
temp_em->uorder = uorder;
temp_em->v1 = vlower;
temp_em->v2 = vupper;
temp_em->vstride = vstride;
temp_em->vorder = vorder;
/*copy the contrl points from ctlPoints to global_ev_ctlPoints*/
for (i=0; i<uorder; i++) {
for (j=0; j<vorder; j++) {
for (x=0; x<k; x++) {
data[x] = ctlPoints[x];
}
ctlPoints += vstride;
data += k;
}
ctlPoints += ustride - vstride * vorder;
}
}
void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsEM(surfEvalMachine *em, REAL u, REAL v,
REAL *retPoint, REAL *retdu, REAL *retdv)
{
int j, row, col;
REAL the_uprime;
REAL the_vprime;
REAL p;
REAL pdv;
REAL *data;
if((em->u2 == em->u1) || (em->v2 == em->v1))
return;
the_uprime = (u - em->u1) / (em->u2 - em->u1);
the_vprime = (v - em->v1) / (em->v2 - em->v1);
/* Compute coefficients for values and derivs */
/* Use already cached values if possible */
if(em->uprime != the_uprime) {
inPreEvaluateWithDeriv(em->uorder, the_uprime, em->ucoeff, em->ucoeffDeriv);
em->uprime = the_uprime;
}
if (em->vprime != the_vprime) {
inPreEvaluateWithDeriv(em->vorder, the_vprime, em->vcoeff, em->vcoeffDeriv);
em->vprime = the_vprime;
}
for (j = 0; j < em->k; j++) {
data=em->ctlPoints+j;
retPoint[j] = retdu[j] = retdv[j] = 0.0;
for (row = 0; row < em->uorder; row++) {
/*
** Minor optimization.
** The col == 0 part of the loop is extracted so we don't
** have to initialize p and pdv to 0.
*/
p = em->vcoeff[0] * (*data);
pdv = em->vcoeffDeriv[0] * (*data);
data += em->k;
for (col = 1; col < em->vorder; col++) {
/* Incrementally build up p, pdv value */
p += em->vcoeff[col] * (*data);
pdv += em->vcoeffDeriv[col] * (*data);
data += em->k;
}
/* Use p, pdv value to incrementally add up r, du, dv */
retPoint[j] += em->ucoeff[row] * p;
retdu[j] += em->ucoeffDeriv[row] * p;
retdv[j] += em->ucoeff[row] * pdv;
}
}
}
void OpenGLSurfaceEvaluator::inDoDomain2EM(surfEvalMachine *em, REAL u, REAL v,
REAL *retPoint)
{
int j, row, col;
REAL the_uprime;
REAL the_vprime;
REAL p;
REAL *data;
if((em->u2 == em->u1) || (em->v2 == em->v1))
return;
the_uprime = (u - em->u1) / (em->u2 - em->u1);
the_vprime = (v - em->v1) / (em->v2 - em->v1);
/* Compute coefficients for values and derivs */
/* Use already cached values if possible */
if(em->uprime != the_uprime) {
inPreEvaluate(em->uorder, the_uprime, em->ucoeff);
em->uprime = the_uprime;
}
if (em->vprime != the_vprime) {
inPreEvaluate(em->vorder, the_vprime, em->vcoeff);
em->vprime = the_vprime;
}
for (j = 0; j < em->k; j++) {
data=em->ctlPoints+j;
retPoint[j] = 0.0;
for (row = 0; row < em->uorder; row++) {
/*
** Minor optimization.
** The col == 0 part of the loop is extracted so we don't
** have to initialize p and pdv to 0.
*/
p = em->vcoeff[0] * (*data);
data += em->k;
for (col = 1; col < em->vorder; col++) {
/* Incrementally build up p, pdv value */
p += em->vcoeff[col] * (*data);
data += em->k;
}
/* Use p, pdv value to incrementally add up r, du, dv */
retPoint[j] += em->ucoeff[row] * p;
}
}
}
void OpenGLSurfaceEvaluator::inDoEvalCoord2EM(REAL u, REAL v)
{
REAL temp_vertex[5];
REAL temp_normal[3];
REAL temp_color[4];
REAL temp_texcoord[4];
if(texcoord_flag)
{
inDoDomain2EM(&em_texcoord, u,v, temp_texcoord);
texcoordCallBack(temp_texcoord, userData);
}
if(color_flag)
{
inDoDomain2EM(&em_color, u,v, temp_color);
colorCallBack(temp_color, userData);
}
if(normal_flag) //there is a normla map
{
inDoDomain2EM(&em_normal, u,v, temp_normal);
normalCallBack(temp_normal, userData);
if(vertex_flag)
{
inDoDomain2EM(&em_vertex, u,v,temp_vertex);
if(em_vertex.k == 4)
{
temp_vertex[0] /= temp_vertex[3];
temp_vertex[1] /= temp_vertex[3];
temp_vertex[2] /= temp_vertex[3];
}
temp_vertex[3]=u;
temp_vertex[4]=v;
vertexCallBack(temp_vertex, userData);
}
}
else if(auto_normal_flag) //no normal map but there is a normal callbackfunctin
{
REAL du[4];
REAL dv[4];
/*compute homegeneous point and partial derivatives*/
inDoDomain2WithDerivsEM(&em_vertex, u,v,temp_vertex,du,dv);
if(em_vertex.k ==4)
inComputeFirstPartials(temp_vertex, du, dv);
#ifdef AVOID_ZERO_NORMAL
if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
{
REAL tempdu[4];
REAL tempdata[4];
REAL u1 = em_vertex.u1;
REAL u2 = em_vertex.u2;
if(u-MYDELTA*(u2-u1) < u1)
u = u+ MYDELTA*(u2-u1);
else
u = u-MYDELTA*(u2-u1);
inDoDomain2WithDerivsEM(&em_vertex,u,v, tempdata, tempdu, dv);
if(em_vertex.k ==4)
inComputeFirstPartials(temp_vertex, du, dv);
}
else if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
{
REAL tempdv[4];
REAL tempdata[4];
REAL v1 = em_vertex.v1;
REAL v2 = em_vertex.v2;
if(v-MYDELTA*(v2-v1) < v1)
v = v+ MYDELTA*(v2-v1);
else
v = v-MYDELTA*(v2-v1);
inDoDomain2WithDerivsEM(&em_vertex,u,v, tempdata, du, tempdv);
if(em_vertex.k ==4)
inComputeFirstPartials(temp_vertex, du, dv);
}
#endif
/*compute normal*/
switch(em_vertex.k){
case 3:
inComputeNormal2(du, dv, temp_normal);
break;
case 4:
// inComputeFirstPartials(temp_vertex, du, dv);
inComputeNormal2(du, dv, temp_normal);
/*transform the homegeneous coordinate of retPoint into inhomogenous one*/
temp_vertex[0] /= temp_vertex[3];
temp_vertex[1] /= temp_vertex[3];
temp_vertex[2] /= temp_vertex[3];
break;
}
normalCallBack(temp_normal, userData);
temp_vertex[3] = u;
temp_vertex[4] = v;
vertexCallBack(temp_vertex, userData);
}/*end if auto_normal*/
else //no normal map, and no normal callback function
{
if(vertex_flag)
{
inDoDomain2EM(&em_vertex, u,v,temp_vertex);
if(em_vertex.k == 4)
{
temp_vertex[0] /= temp_vertex[3];
temp_vertex[1] /= temp_vertex[3];
temp_vertex[2] /= temp_vertex[3];
}
temp_vertex[3] = u;
temp_vertex[4] = v;
vertexCallBack(temp_vertex, userData);
}
}
}
void OpenGLSurfaceEvaluator::inBPMEvalEM(bezierPatchMesh* bpm)
{
int i,j,k;
float u,v;
int ustride;
int vstride;
#ifdef USE_LOD
if(bpm->bpatch != NULL)
{
bezierPatch* p=bpm->bpatch;
ustride = p->dimension * p->vorder;
vstride = p->dimension;
glMap2f( (p->dimension == 3)? GL_MAP2_VERTEX_3 : GL_MAP2_VERTEX_4,
p->umin,
p->umax,
ustride,
p->uorder,
p->vmin,
p->vmax,
vstride,
p->vorder,
p->ctlpoints);
/*
inMap2fEM(0, p->dimension,
p->umin,
p->umax,
ustride,
p->uorder,
p->vmin,
p->vmax,
vstride,
p->vorder,
p->ctlpoints);
*/
}
#else
if(bpm->bpatch != NULL){
bezierPatch* p = bpm->bpatch;
ustride = p->dimension * p->vorder;
vstride = p->dimension;
inMap2fEM(0, p->dimension,
p->umin,
p->umax,
ustride,
p->uorder,
p->vmin,
p->vmax,
vstride,
p->vorder,
p->ctlpoints);
}
if(bpm->bpatch_normal != NULL){
bezierPatch* p = bpm->bpatch_normal;
ustride = p->dimension * p->vorder;
vstride = p->dimension;
inMap2fEM(1, p->dimension,
p->umin,
p->umax,
ustride,
p->uorder,
p->vmin,
p->vmax,
vstride,
p->vorder,
p->ctlpoints);
}
if(bpm->bpatch_color != NULL){
bezierPatch* p = bpm->bpatch_color;
ustride = p->dimension * p->vorder;
vstride = p->dimension;
inMap2fEM(2, p->dimension,
p->umin,
p->umax,
ustride,
p->uorder,
p->vmin,
p->vmax,
vstride,
p->vorder,
p->ctlpoints);
}
if(bpm->bpatch_texcoord != NULL){
bezierPatch* p = bpm->bpatch_texcoord;
ustride = p->dimension * p->vorder;
vstride = p->dimension;
inMap2fEM(3, p->dimension,
p->umin,
p->umax,
ustride,
p->uorder,
p->vmin,
p->vmax,
vstride,
p->vorder,
p->ctlpoints);
}
#endif
k=0;
for(i=0; i<bpm->index_length_array; i++)
{
#ifdef USE_LOD
if(bpm->type_array[i] == GL_POLYGON) //a mesh
{
GLfloat *temp = bpm->UVarray+k;
GLfloat u0 = temp[0];
GLfloat v0 = temp[1];
GLfloat u1 = temp[2];
GLfloat v1 = temp[3];
GLint nu = (GLint) ( temp[4]);
GLint nv = (GLint) ( temp[5]);
GLint umin = (GLint) ( temp[6]);
GLint vmin = (GLint) ( temp[7]);
GLint umax = (GLint) ( temp[8]);
GLint vmax = (GLint) ( temp[9]);
glMapGrid2f(LOD_eval_level*nu, u0, u1, LOD_eval_level*nv, v0, v1);
glEvalMesh2(GL_FILL, LOD_eval_level*umin, LOD_eval_level*umax, LOD_eval_level*vmin, LOD_eval_level*vmax);
}
else
{
LOD_eval(bpm->length_array[i], bpm->UVarray+k, bpm->type_array[i],
0
);
}
k+= 2*bpm->length_array[i];
#else //undef USE_LOD
#ifdef CRACK_TEST
if( bpm->bpatch->umin == 2 && bpm->bpatch->umax == 3
&& bpm->bpatch->vmin ==2 && bpm->bpatch->vmax == 3)
{
REAL vertex[4];
REAL normal[4];
#ifdef DEBUG
printf("***number ****1\n");
#endif
beginCallBack(GL_QUAD_STRIP, NULL);
inDoEvalCoord2EM(3.0, 3.0);
inDoEvalCoord2EM(2.0, 3.0);
inDoEvalCoord2EM(3.0, 2.7);
inDoEvalCoord2EM(2.0, 2.7);
inDoEvalCoord2EM(3.0, 2.0);
inDoEvalCoord2EM(2.0, 2.0);
endCallBack(NULL);
beginCallBack(GL_TRIANGLE_STRIP, NULL);
inDoEvalCoord2EM(2.0, 3.0);
inDoEvalCoord2EM(2.0, 2.0);
inDoEvalCoord2EM(2.0, 2.7);
endCallBack(NULL);
}
if( bpm->bpatch->umin == 1 && bpm->bpatch->umax == 2
&& bpm->bpatch->vmin ==2 && bpm->bpatch->vmax == 3)
{
#ifdef DEBUG
printf("***number 3\n");
#endif
beginCallBack(GL_QUAD_STRIP, NULL);
inDoEvalCoord2EM(2.0, 3.0);
inDoEvalCoord2EM(1.0, 3.0);
inDoEvalCoord2EM(2.0, 2.3);
inDoEvalCoord2EM(1.0, 2.3);
inDoEvalCoord2EM(2.0, 2.0);
inDoEvalCoord2EM(1.0, 2.0);
endCallBack(NULL);
beginCallBack(GL_TRIANGLE_STRIP, NULL);
inDoEvalCoord2EM(2.0, 2.3);
inDoEvalCoord2EM(2.0, 2.0);
inDoEvalCoord2EM(2.0, 3.0);
endCallBack(NULL);
}
return;
#endif //CRACK_TEST
beginCallBack(bpm->type_array[i], userData);
for(j=0; j<bpm->length_array[i]; j++)
{
u = bpm->UVarray[k];
v = bpm->UVarray[k+1];
#ifdef USE_LOD
LOD_EVAL_COORD(u,v);
// glEvalCoord2f(u,v);
#else
#ifdef GENERIC_TEST
float temp_normal[3];
float temp_vertex[3];
if(temp_signal == 0)
{
gTessVertexSphere(u,v, temp_normal, temp_vertex);
//printf("normal=(%f,%f,%f)\n", temp_normal[0], temp_normal[1], temp_normal[2])//printf("veretx=(%f,%f,%f)\n", temp_vertex[0], temp_vertex[1], temp_vertex[2]);
normalCallBack(temp_normal, userData);
vertexCallBack(temp_vertex, userData);
}
else if(temp_signal == 1)
{
gTessVertexCyl(u,v, temp_normal, temp_vertex);
//printf("normal=(%f,%f,%f)\n", temp_normal[0], temp_normal[1], temp_normal[2])//printf("veretx=(%f,%f,%f)\n", temp_vertex[0], temp_vertex[1], temp_vertex[2]);
normalCallBack(temp_normal, userData);
vertexCallBack(temp_vertex, userData);
}
else
#endif //GENERIC_TEST
inDoEvalCoord2EM(u,v);
#endif //USE_LOD
k += 2;
}
endCallBack(userData);
#endif //USE_LOD
}
}
void OpenGLSurfaceEvaluator::inBPMListEvalEM(bezierPatchMesh* list)
{
bezierPatchMesh* temp;
for(temp = list; temp != NULL; temp = temp->next)
{
inBPMEvalEM(temp);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -