📄 ball.c
字号:
// otherside = ( v1[2]>0.0 || v2[2]>0.0 || v3[2]>0.0 ); otherside = ( v1[2]+v2[2]+v3[2]>0.0 );// glEnable(GL_NORMALIZE);// glTexCoord2f(0.5+0.5*v1[0], 0.5-0.5*(otherside?v1[1]:-v1[1]) ); rho = sqrt(v1[0]*v1[0]+v1[1]*v1[1]); xt=asin(rho)/M_PI*2.3*v1[0]/rho; yt=asin(rho)/M_PI*2.3*v1[1]/rho; xt=v1[0]/r; yt=v1[1]/r; createvertex( v1, n1, 0.5-0.5*(otherside?xt:-xt), 0.5+0.5*yt, array);// glTexCoord2f(0.5+0.5*xt, 0.5-0.5*(otherside?yt:-yt) );// glNormal3fv(n1);// glVertex3fv(v1); rho = sqrt(v2[0]*v2[0]+v2[1]*v2[1]); xt=asin(rho)/M_PI*2.3*v2[0]/rho; yt=asin(rho)/M_PI*2.3*v2[1]/rho; xt=v2[0]/r; yt=v2[1]/r; createvertex( v2, n2, 0.5-0.5*(otherside?xt:-xt), 0.5+0.5*yt, array);// glTexCoord2f(0.5+0.5*xt, 0.5-0.5*(otherside?yt:-yt) );// glNormal3fv(n2);// glVertex3fv(v2); rho = sqrt(v3[0]*v3[0]+v3[1]*v3[1]); xt=asin(rho)/M_PI*2.3*v3[0]/rho; yt=asin(rho)/M_PI*2.3*v3[1]/rho; xt=v3[0]/r; yt=v3[1]/r; createvertex( v3, n3, 0.5-0.5*(otherside?xt:-xt), 0.5+0.5*yt, array);// glTexCoord2f(0.5+0.5*xt, 0.5-0.5*(otherside?yt:-yt) );// glNormal3fv(n3);// glVertex3fv(v3); } else if( depth==1 ){ for (i = 0; i < 3; i++) v123[i] = v1[i]+v2[i]+v3[i]; rescale(v123,r); ball_subdivide_rec( v123, v1, v2, depth-1, r, array); ball_subdivide_rec( v123, v2, v3, depth-1, r, array); ball_subdivide_rec( v123, v3, v1, depth-1, r, array); } else if( depth==3 ){ ball_subdivide9_rec( v1, v2, v3, depth-2, r, array);/* } else if( depth==4 ){ for (i = 0; i < 3; i++) { v12[i] = v1[i]+v2[i]; v23[i] = v2[i]+v3[i]; v31[i] = v3[i]+v1[i]; } rescale(v12,r); rescale(v23,r); rescale(v31,r); create_strip(v1,v12,v31,v23,v2);*/ } else { for (i = 0; i < 3; i++) { v12[i] = v1[i]+v2[i]; v23[i] = v2[i]+v3[i]; v31[i] = v3[i]+v1[i]; } rescale(v12,r); rescale(v23,r); rescale(v31,r); ball_subdivide_rec( v1, v12, v31, depth-2, r, array); ball_subdivide_rec( v2, v23, v12, depth-2, r, array); ball_subdivide_rec( v3, v31, v23, depth-2, r, array); ball_subdivide_rec(v12, v23, v31, depth-2, r, array); }// fprintf(stderr,"back again all (depth=%d)\n",depth);}void ball_subdivide9_rec(float *v1, float *v2, float *v3, const int depth, float r, ElemArray *array){ GLfloat v112[3], v122[3], v223[3], v233[3], v331[3], v311[3], v123[3]; GLint i;// fprintf(stderr,"depth=%d\n",depth); if (depth == 0) { ball_subdivide_rec(v1,v2,v3,0,r, array); // draw the triangle } else { for (i = 0; i < 3; i++) { v112[i] = v1[i]+v1[i]+v2[i]; v122[i] = v1[i]+v2[i]+v2[i]; v223[i] = v2[i]+v2[i]+v3[i]; v233[i] = v2[i]+v3[i]+v3[i]; v331[i] = v3[i]+v3[i]+v1[i]; v311[i] = v3[i]+v1[i]+v1[i]; v123[i] = v1[i]+v2[i]+v3[i]; } rescale(v112,r); rescale(v122,r); rescale(v223,r); rescale(v233,r); rescale(v331,r); rescale(v311,r); rescale(v123,r); ball_subdivide9_rec( v1 , v112, v311, depth-1, r, array); ball_subdivide9_rec( v112, v122, v123, depth-1, r, array); ball_subdivide9_rec( v112, v123, v311, depth-1, r, array); ball_subdivide9_rec( v311, v123, v331, depth-1, r, array); ball_subdivide9_rec( v122, v2 , v223, depth-1, r, array); ball_subdivide9_rec( v122, v223, v123, depth-1, r, array); ball_subdivide9_rec( v123, v223, v233, depth-1, r, array); ball_subdivide9_rec( v123, v233, v331, depth-1, r, array); ball_subdivide9_rec( v331, v233, v3 , depth-1, r, array); }// fprintf(stderr,"back again all (depth=%d)\n",depth);}void ball_subdivide_nonrec(float *v1, float *v2, float *v3, int depth, float r, ElemArray *array)/* if array=0 just make vertices */{ GLfloat v12[3], v13[3], v[3]; GLfloat n[3]; GLint i,j,k,x,y; double xf,yf,vl; int otherside; double xt,yt,rho; int subdiv; if(depth==1) depth=0; if(!(depth&1)){ /* even */ subdiv=1<<(depth/2); }else{ /* odd */ subdiv=(1<<((depth-3)/2))*3; } for (i = 0; i < 3; i++) { v12[i] = v2[i]-v1[i]; v13[i] = v3[i]-v1[i]; } otherside = ( v1[2]+v2[2]+v3[2]>0.0 ); for( i=0; i<subdiv; i++ ){ /* make tristrips */ if(array==NULL){ glBegin(GL_TRIANGLE_STRIP); } else { array->prim_size[array->num_prim]=2*(subdiv-i)+1; (array->num_prim)++; } for(j=0;j<2*(subdiv-i)+1;j++){ if(!(j&1)){ /* even */ x=j/2; y=i; } else { /* odd */ x=(j-1)/2; y=i+1; } xf=(double)x/(double)subdiv; yf=(double)y/(double)subdiv; vl=0.0; for(k=0;k<3;k++){ v[k]=v1[k]+v13[k]*xf+v12[k]*yf; vl+=v[k]*v[k]; } vl=sqrt(vl); for(k=0;k<3;k++){ n[k]=v[k]/vl; v[k]=n[k]*r; } // glEnable(GL_NORMALIZE); // glTexCoord2f(0.5+0.5*v1[0], 0.5-0.5*(otherside?v1[1]:-v1[1]) );/* rho = sqrt(v[0]*v[0]+v[1]*v[1]); xt=asin(rho)/M_PI*2.3*v[0]/rho; yt=asin(rho)/M_PI*2.3*v[1]/rho;*/ xt=n[0]; yt=n[1]; createvertex( v, n, 0.5-0.5*(otherside?xt:-xt), 0.5+0.5*yt, array); } if(array==NULL){ glEnd(); } }// fprintf(stderr,"back again all (depth=%d)\n",depth);}void create_ball_icosa( float r, int ddepth, int id ) /*FOLD00*/{#define X .525731112119133606#define Z .850650808352039932 int i; static GLfloat vdata[12][3] = { {-X, 0.0, Z}, {X, 0.0, Z}, {-X, 0.0, -Z}, {X, 0.0, -Z}, {0.0, Z, X}, {0.0, Z, -X}, {0.0, -Z, X}, {0.0, -Z, -X}, {Z, X, 0.0}, {-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0} }; static GLint tindices[20][3] = { {0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1}, {8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3}, {7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6}, {6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} }; DPRINTF("create_ball_icosa\n"); glDisable( GL_NORMALIZE ); /* remove this */ glNewList(id, GL_COMPILE);// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glPushMatrix();// glScalef( r, r, r );// glEnable( GL_NORMALIZE ); /* remove this */#ifndef USE_TRISTRIPS glBegin(GL_TRIANGLES);#endif for (i = 0; i < 20; i++) {#ifndef USE_TRISTRIPS ball_subdivide_rec(#else ball_subdivide_nonrec(#endif &vdata[tindices[i][0]][0], &vdata[tindices[i][1]][0], &vdata[tindices[i][2]][0], ddepth, r, NULL ); }#ifndef USE_TRISTRIPS glEnd();#endif glPopMatrix();// glDisable( GL_NORMALIZE ); /* remove this */ glEndList();}#ifdef USE_VERTEX_ARRAYSElemArray * create_ball_icosa_array( float r, int ddepth, int id ){#define X .525731112119133606#define Z .850650808352039932 ElemArray * array; int i,pnr,fnr; double volume, scale_ratio; VMvect v1,v2,v3; static GLfloat vdata[12][3] = { {-X, 0.0, Z}, {X, 0.0, Z}, {-X, 0.0, -Z}, {X, 0.0, -Z}, {0.0, Z, X}, {0.0, Z, -X}, {0.0, -Z, X}, {0.0, -Z, -X}, {Z, X, 0.0}, {-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0} }; static GLint tindices[20][3] = { {0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1}, {8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3}, {7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6}, {6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} }; static int init = 0; if(!init){ init=1; for (i = 0; i < 12; i++) { rescale(vdata[i],r); } } if(ddepth%2==0){ fnr = 20*(1<<(ddepth/2*2)); pnr = 10*((1<<(ddepth/2*2))-1) + 12; } else if(ddepth!=1) { fnr = 20*(1<<((ddepth-3)/2*2)); pnr = 10*((1<<((ddepth-3)/2*2))-1) + 12; pnr += fnr * 4; fnr *= 9; } else if(ddepth==1) { fnr = 20*(1<<(ddepth/2*2)); pnr = 10*((1<<(ddepth/2*2))-1) + 12; pnr += fnr; fnr *= 3; } DPRINTF("pnr-ideal=%d\n",pnr); pnr+=(int)(sqrt(pnr)+0.5)*2; /* could (still?) get narrow (theoret. *sqrt(PI) instead of *2) */ DPRINTF("pnr-nachher=%d\n",pnr); array = (ElemArray *)malloc( sizeof(ElemArray) ); array->vert = (GLfloat *)malloc( pnr*3*sizeof(GLfloat) ); array->norm = (GLfloat *)malloc( pnr*3*sizeof(GLfloat) ); array->tex = (GLfloat *)malloc( pnr*2*sizeof(GLfloat) ); array->reftex = (GLfloat *)malloc( pnr*2*sizeof(GLfloat) ); array->index = (int *) malloc( fnr*3*sizeof(int) ); array->num_prim = 0; array->indnr=0; array->vnr=0; DPRINTF("fnr*3=%d\n",fnr*3); DPRINTF("pnr=%d\n",pnr); for (i = 0; i < 20; i++) {#ifndef USE_TRISTRIPS ball_subdivide_rec(#else ball_subdivide_nonrec(#endif &vdata[tindices[i][0]][0], &vdata[tindices[i][1]][0], &vdata[tindices[i][2]][0], ddepth, r, array ); } DPRINTF("array->indnr=%d\n",array->indnr); DPRINTF("array->vnr=%d\n",array->vnr);/* glNewList(id, GL_COMPILE); glPushMatrix(); glBegin(GL_TRIANGLES); for (i = 0; i < array->indnr; i++) { glTexCoord2fv( &array->tex [array->index[i]*2] ); glNormal3fv( &array->norm[array->index[i]*3] ); glVertex3fv( &array->vert[array->index[i]*3] ); fprintf(stderr,"v=<%f,%f,%f>\n", array->vert[array->index[i]*3], array->vert[array->index[i]*3+1], array->vert[array->index[i]*3+2] ); } glEnd(); glPopMatrix(); glEndList();*/#if 1 DPRINTF("create_ball_icosa_array: rescaling vertices\n");#ifndef USE_TRISTRIPS volume=0.0; for(i=0;i<array->indnr;i+=3){ v1.x = array->vert[array->index[i+0]*3+0]; v1.y = array->vert[array->index[i+0]*3+1]; v1.z = array->vert[array->index[i+0]*3+2]; v2.x = array->vert[array->index[i+1]*3+0]; v2.y = array->vert[array->index[i+1]*3+1]; v2.z = array->vert[array->index[i+1]*3+2]; v3.x = array->vert[array->index[i+2]*3+0]; v3.y = array->vert[array->index[i+2]*3+1]; v3.z = array->vert[array->index[i+2]*3+2]; volume+=tri_vol_xy( v1, v2, v3 ); } DPRINTF("create_ball_icosa_array: volume=%f\n",volume);#else volume=0.0; { int j; int actind=0; for(i=0;i<array->num_prim;i++){ for(j=0;j<array->prim_size[i]-2;j++){ v1.x = array->vert[array->index[actind+j+0]*3+0]; v1.y = array->vert[array->index[actind+j+0]*3+1]; v1.z = array->vert[array->index[actind+j+0]*3+2]; v2.x = array->vert[array->index[actind+j+1]*3+0]; v2.y = array->vert[array->index[actind+j+1]*3+1]; v2.z = array->vert[array->index[actind+j+1]*3+2]; v3.x = array->vert[array->index[actind+j+2]*3+0]; v3.y = array->vert[array->index[actind+j+2]*3+1]; v3.z = array->vert[array->index[actind+j+2]*3+2]; if(!(j&1)){ volume+=tri_vol_xy( v1, v2, v3 ); } else { volume-=tri_vol_xy( v1, v2, v3 ); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -