diff options
Diffstat (limited to 'Build/source/utils/asymptote/bezierpatch.cc')
-rw-r--r-- | Build/source/utils/asymptote/bezierpatch.cc | 638 |
1 files changed, 319 insertions, 319 deletions
diff --git a/Build/source/utils/asymptote/bezierpatch.cc b/Build/source/utils/asymptote/bezierpatch.cc index bcdd238cca3..314ac948093 100644 --- a/Build/source/utils/asymptote/bezierpatch.cc +++ b/Build/source/utils/asymptote/bezierpatch.cc @@ -54,12 +54,12 @@ std::vector<iz> IZ; const double FillFactor=0.1; -inline int sgn1(double x) +inline int sgn1(double x) { return x >= 0.0 ? 1 : -1; } -inline int sgn(double x) +inline int sgn(double x) { return (x > 0.0 ? 1 : (x < 0.0 ? -1 : 0)); } @@ -94,7 +94,7 @@ bool pierce(const double *a, const double *b, const double *c, const double *A, int sa=sgn(orient3d(A,b,c,B)); int sb=sgn(orient3d(A,c,a,B)); int sc=sgn(orient3d(A,a,b,B)); - return sa == sb && sb == sc; + return sa == sb && sb == sc; } // returns true iff triangle abc is pierced by an edge of triangle ABC @@ -114,7 +114,7 @@ bool intersect0(const double *a, const double *b, const double *c, if(pierce(a,b,c,C,A)) return true; } return false; -} +} // returns true iff triangle abc intersects triangle ABC bool intersect3D(const double *a, const double *b, const double *c, @@ -142,7 +142,7 @@ inline double intersect(const double *P, const double *Q, const double *n, double denom=n[0]*(Q[0]-P[0])+n[1]*(Q[1]-P[1])+n[2]*(Q[2]-P[2]); return denom == 0 ? DBL_MAX : (d-n[0]*P[0]-n[1]*P[1]-n[2]*P[2])/denom; } - + inline triple interp(const double *a, const double *b, double t) { return triple(a[0]+t*(b[0]-a[0]),a[1]+t*(b[1]-a[1]),a[2]+t*(b[2]-a[2])); @@ -163,7 +163,7 @@ inline triple interp(const triple& a, const triple& b, double t) unsigned n; unsigned int count; - + // Sort nonintersecting triangles by depth. int compare(const void *p, const void *P) { @@ -174,29 +174,29 @@ int compare(const void *p, const void *P) unsigned IA=((GLuint *) P)[0]; unsigned IB=((GLuint *) P)[1]; unsigned IC=((GLuint *) P)[2]; - - return zbuffer[Ia]+zbuffer[Ib]+zbuffer[Ic] < + + return zbuffer[Ia]+zbuffer[Ib]+zbuffer[Ic] < zbuffer[IA]+zbuffer[IB]+zbuffer[IC] ? -1 : 1; - + /* - double a[]={xbuffer[Ia],ybuffer[Ia],zbuffer[Ia]}; - double b[]={xbuffer[Ib],ybuffer[Ib],zbuffer[Ib]}; - double c[]={xbuffer[Ic],ybuffer[Ic],zbuffer[Ic]}; - - double A[]={xbuffer[IA],ybuffer[IA],zbuffer[IA]}; - double B[]={xbuffer[IB],ybuffer[IB],zbuffer[IB]}; - double C[]={xbuffer[IC],ybuffer[IC],zbuffer[IC]}; - - double viewpoint[]={0,0,100000}; - - double sa=-orient3d(A,B,C,a); - double sb=-orient3d(A,B,C,b); - double sc=-orient3d(A,B,C,c); - double s=min(sa,sb,sc); - double S=max(sa,sb,sc); - double eps=1000; - - if(s < -eps && S > eps) { //swap + double a[]={xbuffer[Ia],ybuffer[Ia],zbuffer[Ia]}; + double b[]={xbuffer[Ib],ybuffer[Ib],zbuffer[Ib]}; + double c[]={xbuffer[Ic],ybuffer[Ic],zbuffer[Ic]}; + + double A[]={xbuffer[IA],ybuffer[IA],zbuffer[IA]}; + double B[]={xbuffer[IB],ybuffer[IB],zbuffer[IB]}; + double C[]={xbuffer[IC],ybuffer[IC],zbuffer[IC]}; + + double viewpoint[]={0,0,100000}; + + double sa=-orient3d(A,B,C,a); + double sb=-orient3d(A,B,C,b); + double sc=-orient3d(A,B,C,c); + double s=min(sa,sb,sc); + double S=max(sa,sb,sc); + double eps=1000; + + if(s < -eps && S > eps) { //swap double sA=-orient3d(a,b,c,A); double sB=-orient3d(a,b,c,B); double sC=-orient3d(a,b,c,C); @@ -206,12 +206,12 @@ int compare(const void *p, const void *P) int sz=sgn1(orient3d(a,b,c,viewpoint)); if(S < -eps) return -sz; if(S > eps) return sz; - } - if(S < -s) S=s; - int sz=sgn1(orient3d(A,B,C,viewpoint)); - if(S < -eps) return sz; - if(S > eps) return -sz; - return a[2]+b[2]+c[2] < A[2]+B[2]+C[2] ? -1 : 1; + } + if(S < -s) S=s; + int sz=sgn1(orient3d(A,B,C,viewpoint)); + if(S < -eps) return sz; + if(S > eps) return -sz; + return a[2]+b[2]+c[2] < A[2]+B[2]+C[2] ? -1 : 1; */ } @@ -220,47 +220,47 @@ void split(unsigned i3, GLuint ia, GLuint ib, GLuint ic, double *a, double *b, double *c, double *N, double *A) { double td=intersect(a,b,N,A); double te=intersect(a,c,N,A); - + triple d=interp(a,b,td); triple e=interp(a,c,te); - + GLuint Ia=tstride*ia; GLuint Ib=tstride*ib; GLuint Ic=tstride*ic; - + triple na=triple(V[Ia+3],V[Ia+4],V[Ia+5]); triple nb=triple(V[Ib+3],V[Ib+4],V[Ib+5]); triple nc=triple(V[Ic+3],V[Ic+4],V[Ic+5]); - + triple nd=interp(na,nb,td); triple ne=interp(na,nc,te); - + GLuint id,ie; - + if(colors) { GLfloat *ca=&V[Ia+6]; GLfloat *cb=&V[Ib+6]; GLfloat *cc=&V[Ic+6]; - + GLfloat cd[4],ce[4]; interp(cd,ca,cb,td); interp(ce,ca,cc,te); - + id=data.Vertex(d,nd,cd); ie=data.Vertex(e,ne,ce); } else { id=data.Vertex(d,nd); ie=data.Vertex(e,ne); } - + I[i3]=ia; I[i3+1]=id; I[i3+2]=ie; - + I.push_back(id); I.push_back(ib); I.push_back(ie); - + I.push_back(ie); I.push_back(ib); I.push_back(ic); @@ -274,10 +274,10 @@ void BezierPatch::init(double res) MaterialIndex=transparent ? (color ? -1-materialIndex : 1+materialIndex) : materialIndex; - + pvertex=transparent ? &vertexBuffer::tvertex : &vertexBuffer::vertex; } - + void BezierPatch::render(const triple *p, bool straight, GLfloat *c0) { triple p0=p[0]; @@ -285,7 +285,7 @@ void BezierPatch::render(const triple *p, bool straight, GLfloat *c0) for(unsigned i=1; i < 16; ++i) epsilon=max(epsilon,abs2(p[i]-p0)); epsilon *= DBL_EPSILON; - + triple p3=p[3]; triple p12=p[12]; triple p15=p[15]; @@ -295,36 +295,36 @@ void BezierPatch::render(const triple *p, bool straight, GLfloat *c0) n0=normal(p3,p[2],p[1],p0,p[13],p[14],p15); if(abs2(n0) <= epsilon) n0=normal(p15,p[11],p[7],p3,p[4],p[8],p12); } - + triple n1=normal(p0,p[4],p[8],p12,p[13],p[14],p15); if(abs2(n1) <= epsilon) { n1=normal(p0,p[4],p[8],p12,p[11],p[7],p3); if(abs2(n1) <= epsilon) n1=normal(p3,p[2],p[1],p0,p[13],p[14],p15); } - + triple n2=normal(p12,p[13],p[14],p15,p[11],p[7],p3); if(abs2(n2) <= epsilon) { n2=normal(p12,p[13],p[14],p15,p[2],p[1],p0); if(abs2(n2) <= epsilon) n2=normal(p0,p[4],p[8],p12,p[11],p[7],p3); } - + triple n3=normal(p15,p[11],p[7],p3,p[2],p[1],p0); if(abs2(n3) <= epsilon) { n3=normal(p15,p[11],p[7],p3,p[4],p[8],p12); if(abs2(n3) <= epsilon) n3=normal(p12,p[13],p[14],p15,p[2],p[1],p0); } - + GLuint i0,i1,i2,i3; if(color) { GLfloat *c1=c0+4; GLfloat *c2=c0+8; GLfloat *c3=c0+12; - + i0=data.Vertex(p0,n0,c0); i1=data.Vertex(p12,n1,c1); i2=data.Vertex(p15,n2,c2); i3=data.Vertex(p3,n3,c3); - + if(!straight) render(p,i0,i1,i2,i3,p0,p12,p15,p3,false,false,false,false, c0,c1,c2,c3); @@ -333,11 +333,11 @@ void BezierPatch::render(const triple *p, bool straight, GLfloat *c0) i1=(data.*pvertex)(p12,n1); i2=(data.*pvertex)(p15,n2); i3=(data.*pvertex)(p3,n3); - + if(!straight) render(p,i0,i1,i2,i3,p0,p12,p15,p3,false,false,false,false); } - + if(straight) { std::vector<GLuint> &q=data.indices; triple Pa[]={p0,p12,p15}; @@ -382,14 +382,14 @@ void BezierPatch::render(const triple *p, q.push_back(I3); } } else { // Patch is not flat - if(offscreen(16,p)) return; + if(offscreen(16,p)) return; - /* Control points are indexed as follows: + /* Control points are indexed as follows: - Coordinate + Coordinate +----- Index - + 03 13 23 33 +-----+-----+-----+ |3 |7 |11 |15 @@ -406,216 +406,215 @@ void BezierPatch::render(const triple *p, +-----+-----+-----+ 0 4 8 12 - */ + */ triple p0=p[0]; triple p3=p[3]; triple p12=p[12]; triple p15=p[15]; - if(d.getx() < res2) { // flat in horizontal direction; split vertically - /* - P refers to a corner - m refers to a midpoint - s refers to a subpatch - - +--------+--------+ - |P3 P2| - | | - | s1 | - | | - | | - m1 +-----------------+ m0 - | | - | | - | s0 | - | | - |P0 P1| - +-----------------+ - - */ - - Split3 c0(p0,p[1],p[2],p3); - Split3 c1(p[4],p[5],p[6],p[7]); - Split3 c2(p[8],p[9],p[10],p[11]); - Split3 c3(p12,p[13],p[14],p15); - - triple s0[]={p0 ,c0.m0,c0.m3,c0.m5, - p[4],c1.m0,c1.m3,c1.m5, - p[8],c2.m0,c2.m3,c2.m5, - p12 ,c3.m0,c3.m3,c3.m5}; - - triple s1[]={c0.m5,c0.m4,c0.m2,p3, - c1.m5,c1.m4,c1.m2,p[7], - c2.m5,c2.m4,c2.m2,p[11], - c3.m5,c3.m4,c3.m2,p15}; - - triple n0=normal(s0[12],s0[13],s0[14],s0[15],s0[11],s0[7],s0[3]); - if(abs2(n0) <= epsilon) { - n0=normal(s0[12],s0[13],s0[14],s0[15],s0[2],s0[1],s0[0]); - if(abs2(n0) <= epsilon) - n0=normal(s0[0],s0[4],s0[8],s0[12],s0[11],s0[7],s0[3]); - } - - triple n1=normal(s1[3],s1[2],s1[1],s1[0],s1[4],s1[8],s1[12]); - if(abs2(n1) <= epsilon) { - n1=normal(s1[3],s1[2],s1[1],s1[0],s1[13],s1[14],s1[15]); - if(abs2(n1) <= epsilon) - n1=normal(s1[15],s1[11],s1[7],s1[3],s1[4],s1[8],s1[12]); - } - - // A kludge to remove subdivision cracks, only applied the first time - // an edge is found to be flat before the rest of the subpatch is. - - triple m0=0.5*(P1+P2); - if(!flat1) { - if((flat1=Straightness(p12,p[13],p[14],p15) < res2)) - m0 -= Epsilon*unit(differential(s1[12],s1[8],s1[4],s1[0])); - else m0=s0[15]; - } - - triple m1=0.5*(P3+P0); - if(!flat3) { - if((flat3=Straightness(p0,p[1],p[2],p3) < res2)) - m1 -= Epsilon*unit(differential(s0[3],s0[7],s0[11],s0[15])); - else m1=s1[0]; - } - - if(color) { - GLfloat c0[4],c1[4]; - for(size_t i=0; i < 4; ++i) { - c0[i]=0.5*(C1[i]+C2[i]); - c1[i]=0.5*(C3[i]+C0[i]); - } - - GLuint i0=data.Vertex(m0,n0,c0); - GLuint i1=data.Vertex(m1,n1,c1); - - render(s0,I0,I1,i0,i1,P0,P1,m0,m1,flat0,flat1,false,flat3,C0,C1,c0,c1); - render(s1,i1,i0,I2,I3,m1,m0,P2,P3,false,flat1,flat2,flat3,c1,c0,C2,C3); - } else { - GLuint i0=(data.*pvertex)(m0,n0); - GLuint i1=(data.*pvertex)(m1,n1); - - render(s0,I0,I1,i0,i1,P0,P1,m0,m1,flat0,flat1,false,flat3); - render(s1,i1,i0,I2,I3,m1,m0,P2,P3,false,flat1,flat2,flat3); - } - return; - } - if(d.gety() < res2) { // flat in vertical direction; split horizontally - /* - P refers to a corner - m refers to a midpoint - s refers to a subpatch - - m1 - +--------+--------+ - |P3 | P2| - | | | - | | | - | | | - | | | - | s0 | s1 | - | | | - | | | - | | | - | | | - |P0 | P1| - +--------+--------+ - m0 - - */ - - Split3 c0(p0,p[4],p[8],p12); - Split3 c1(p[1],p[5],p[9],p[13]); - Split3 c2(p[2],p[6],p[10],p[14]); - Split3 c3(p3,p[7],p[11],p15); - - triple s0[]={p0,p[1],p[2],p3, - c0.m0,c1.m0,c2.m0,c3.m0, - c0.m3,c1.m3,c2.m3,c3.m3, - c0.m5,c1.m5,c2.m5,c3.m5}; - - triple s1[]={c0.m5,c1.m5,c2.m5,c3.m5, - c0.m4,c1.m4,c2.m4,c3.m4, - c0.m2,c1.m2,c2.m2,c3.m2, - p12,p[13],p[14],p15}; - - triple n0=normal(s0[0],s0[4],s0[8],s0[12],s0[13],s0[14],s0[15]); - if(abs2(n0) <= epsilon) { - n0=normal(s0[0],s0[4],s0[8],s0[12],s0[11],s0[7],s0[3]); - if(abs2(n0) <= epsilon) - n0=normal(s0[3],s0[2],s0[1],s0[0],s0[13],s0[14],s0[15]); - } - - triple n1=normal(s1[15],s1[11],s1[7],s1[3],s1[2],s1[1],s1[0]); - if(abs2(n1) <= epsilon) { - n1=normal(s1[15],s1[11],s1[7],s1[3],s1[4],s1[8],s1[12]); - if(abs2(n1) <= epsilon) - n1=normal(s1[12],s1[13],s1[14],s1[15],s1[2],s1[1],s1[0]); - } - - // A kludge to remove subdivision cracks, only applied the first time - // an edge is found to be flat before the rest of the subpatch is. - - triple m0=0.5*(P0+P1); - if(!flat0) { - if((flat0=Straightness(p0,p[4],p[8],p12) < res2)) - m0 -= Epsilon*unit(differential(s1[0],s1[1],s1[2],s1[3])); - else m0=s0[12]; - } - - triple m1=0.5*(P2+P3); - if(!flat2) { - if((flat2=Straightness(p15,p[11],p[7],p3) < res2)) - m1 -= Epsilon*unit(differential(s0[15],s0[14],s0[13],s0[12])); - else m1=s1[3]; - } - - if(color) { - GLfloat c0[4],c1[4]; - for(size_t i=0; i < 4; ++i) { - c0[i]=0.5*(C0[i]+C1[i]); - c1[i]=0.5*(C2[i]+C3[i]); - } - - GLuint i0=data.Vertex(m0,n0,c0); - GLuint i1=data.Vertex(m1,n1,c1); - - render(s0,I0,i0,i1,I3,P0,m0,m1,P3,flat0,false,flat2,flat3,C0,c0,c1,C3); - render(s1,i0,I1,I2,i1,m0,P1,P2,m1,flat0,flat1,flat2,false,c0,C1,C2,c1); - } else { - GLuint i0=(data.*pvertex)(m0,n0); - GLuint i1=(data.*pvertex)(m1,n1); - - render(s0,I0,i0,i1,I3,P0,m0,m1,P3,flat0,false,flat2,flat3); - render(s1,i0,I1,I2,i1,m0,P1,P2,m1,flat0,flat1,flat2,false); - } - return; - } - /* - Horizontal and vertical subdivision: - P refers to a corner - m refers to a midpoint - s refers to a subpatch - - m2 - +--------+--------+ - |P3 | P2| - | | | - | s3 | s2 | - | | | - | | m4 | - m3 +--------+--------+ m1 - | | | - | | | - | s0 | s1 | - | | | - |P0 | P1| - +--------+--------+ - m0 + if(d.getx() < res2) { // flat in horizontal direction; split vertically + /* + P refers to a corner + m refers to a midpoint + s refers to a subpatch + + +--------+--------+ + |P3 P2| + | | + | s1 | + | | + | | + m1 +-----------------+ m0 + | | + | | + | s0 | + | | + |P0 P1| + +-----------------+ + + */ + + Split3 c0(p0,p[1],p[2],p3); + Split3 c1(p[4],p[5],p[6],p[7]); + Split3 c2(p[8],p[9],p[10],p[11]); + Split3 c3(p12,p[13],p[14],p15); + + triple s0[]={p0 ,c0.m0,c0.m3,c0.m5, + p[4],c1.m0,c1.m3,c1.m5, + p[8],c2.m0,c2.m3,c2.m5, + p12 ,c3.m0,c3.m3,c3.m5}; + + triple s1[]={c0.m5,c0.m4,c0.m2,p3, + c1.m5,c1.m4,c1.m2,p[7], + c2.m5,c2.m4,c2.m2,p[11], + c3.m5,c3.m4,c3.m2,p15}; + + triple n0=normal(s0[12],s0[13],s0[14],s0[15],s0[11],s0[7],s0[3]); + if(abs2(n0) <= epsilon) { + n0=normal(s0[12],s0[13],s0[14],s0[15],s0[2],s0[1],s0[0]); + if(abs2(n0) <= epsilon) + n0=normal(s0[0],s0[4],s0[8],s0[12],s0[11],s0[7],s0[3]); + } + + triple n1=normal(s1[3],s1[2],s1[1],s1[0],s1[4],s1[8],s1[12]); + if(abs2(n1) <= epsilon) { + n1=normal(s1[3],s1[2],s1[1],s1[0],s1[13],s1[14],s1[15]); + if(abs2(n1) <= epsilon) + n1=normal(s1[15],s1[11],s1[7],s1[3],s1[4],s1[8],s1[12]); + } + + // A kludge to remove subdivision cracks, only applied the first time + // an edge is found to be flat before the rest of the subpatch is. + + triple m0=0.5*(P1+P2); + if(!flat1) { + if((flat1=Straightness(p12,p[13],p[14],p15) < res2)) + m0 -= Epsilon*unit(differential(s1[12],s1[8],s1[4],s1[0])); + else m0=s0[15]; + } + + triple m1=0.5*(P3+P0); + if(!flat3) { + if((flat3=Straightness(p0,p[1],p[2],p3) < res2)) + m1 -= Epsilon*unit(differential(s0[3],s0[7],s0[11],s0[15])); + else m1=s1[0]; + } + + if(color) { + GLfloat c0[4],c1[4]; + for(size_t i=0; i < 4; ++i) { + c0[i]=0.5*(C1[i]+C2[i]); + c1[i]=0.5*(C3[i]+C0[i]); + } + + GLuint i0=data.Vertex(m0,n0,c0); + GLuint i1=data.Vertex(m1,n1,c1); + + render(s0,I0,I1,i0,i1,P0,P1,m0,m1,flat0,flat1,false,flat3,C0,C1,c0,c1); + render(s1,i1,i0,I2,I3,m1,m0,P2,P3,false,flat1,flat2,flat3,c1,c0,C2,C3); + } else { + GLuint i0=(data.*pvertex)(m0,n0); + GLuint i1=(data.*pvertex)(m1,n1); + + render(s0,I0,I1,i0,i1,P0,P1,m0,m1,flat0,flat1,false,flat3); + render(s1,i1,i0,I2,I3,m1,m0,P2,P3,false,flat1,flat2,flat3); + } + return; + } + if(d.gety() < res2) { // flat in vertical direction; split horizontally + /* + P refers to a corner + m refers to a midpoint + s refers to a subpatch + + m1 + +--------+--------+ + |P3 | P2| + | | | + | | | + | | | + | | | + | s0 | s1 | + | | | + | | | + | | | + | | | + |P0 | P1| + +--------+--------+ + m0 + */ + + Split3 c0(p0,p[4],p[8],p12); + Split3 c1(p[1],p[5],p[9],p[13]); + Split3 c2(p[2],p[6],p[10],p[14]); + Split3 c3(p3,p[7],p[11],p15); + + triple s0[]={p0,p[1],p[2],p3, + c0.m0,c1.m0,c2.m0,c3.m0, + c0.m3,c1.m3,c2.m3,c3.m3, + c0.m5,c1.m5,c2.m5,c3.m5}; + + triple s1[]={c0.m5,c1.m5,c2.m5,c3.m5, + c0.m4,c1.m4,c2.m4,c3.m4, + c0.m2,c1.m2,c2.m2,c3.m2, + p12,p[13],p[14],p15}; + + triple n0=normal(s0[0],s0[4],s0[8],s0[12],s0[13],s0[14],s0[15]); + if(abs2(n0) <= epsilon) { + n0=normal(s0[0],s0[4],s0[8],s0[12],s0[11],s0[7],s0[3]); + if(abs2(n0) <= epsilon) + n0=normal(s0[3],s0[2],s0[1],s0[0],s0[13],s0[14],s0[15]); + } + + triple n1=normal(s1[15],s1[11],s1[7],s1[3],s1[2],s1[1],s1[0]); + if(abs2(n1) <= epsilon) { + n1=normal(s1[15],s1[11],s1[7],s1[3],s1[4],s1[8],s1[12]); + if(abs2(n1) <= epsilon) + n1=normal(s1[12],s1[13],s1[14],s1[15],s1[2],s1[1],s1[0]); + } + + // A kludge to remove subdivision cracks, only applied the first time + // an edge is found to be flat before the rest of the subpatch is. + + triple m0=0.5*(P0+P1); + if(!flat0) { + if((flat0=Straightness(p0,p[4],p[8],p12) < res2)) + m0 -= Epsilon*unit(differential(s1[0],s1[1],s1[2],s1[3])); + else m0=s0[12]; + } + + triple m1=0.5*(P2+P3); + if(!flat2) { + if((flat2=Straightness(p15,p[11],p[7],p3) < res2)) + m1 -= Epsilon*unit(differential(s0[15],s0[14],s0[13],s0[12])); + else m1=s1[3]; + } + + if(color) { + GLfloat c0[4],c1[4]; + for(size_t i=0; i < 4; ++i) { + c0[i]=0.5*(C0[i]+C1[i]); + c1[i]=0.5*(C2[i]+C3[i]); + } + + GLuint i0=data.Vertex(m0,n0,c0); + GLuint i1=data.Vertex(m1,n1,c1); + + render(s0,I0,i0,i1,I3,P0,m0,m1,P3,flat0,false,flat2,flat3,C0,c0,c1,C3); + render(s1,i0,I1,I2,i1,m0,P1,P2,m1,flat0,flat1,flat2,false,c0,C1,C2,c1); + } else { + GLuint i0=(data.*pvertex)(m0,n0); + GLuint i1=(data.*pvertex)(m1,n1); + + render(s0,I0,i0,i1,I3,P0,m0,m1,P3,flat0,false,flat2,flat3); + render(s1,i0,I1,I2,i1,m0,P1,P2,m1,flat0,flat1,flat2,false); + } + return; + } + /* + Horizontal and vertical subdivision: + P refers to a corner + m refers to a midpoint + s refers to a subpatch + + m2 + +--------+--------+ + |P3 | P2| + | | | + | s3 | s2 | + | | | + | | m4 | + m3 +--------+--------+ m1 + | | | + | | | + | s0 | s1 | + | | | + |P0 | P1| + +--------+--------+ + m0 */ - + // Subdivide patch: Split3 c0(p0,p[1],p[2],p3); Split3 c1(p[4],p[5],p[6],p[7]); @@ -638,70 +637,70 @@ void BezierPatch::render(const triple *p, c7.m2,c8.m2,c9.m2,c10.m2,c3.m5,c3.m4,c3.m2,p15}; triple s3[]={c0.m5,c0.m4,c0.m2,p3,c7.m0,c8.m0,c9.m0,c10.m0, c7.m3,c8.m3,c9.m3,c10.m3,c7.m5,c8.m5,c9.m5,c10.m5}; - + triple m4=s0[15]; - + triple n0=normal(s0[0],s0[4],s0[8],s0[12],s0[13],s0[14],s0[15]); if(abs2(n0) <= epsilon) { n0=normal(s0[0],s0[4],s0[8],s0[12],s0[11],s0[7],s0[3]); if(abs2(n0) <= epsilon) n0=normal(s0[3],s0[2],s0[1],s0[0],s0[13],s0[14],s0[15]); } - + triple n1=normal(s1[12],s1[13],s1[14],s1[15],s1[11],s1[7],s1[3]); if(abs2(n1) <= epsilon) { n1=normal(s1[12],s1[13],s1[14],s1[15],s1[2],s1[1],s1[0]); if(abs2(n1) <= epsilon) n1=normal(s1[0],s1[4],s1[8],s1[12],s1[11],s1[7],s1[3]); } - + triple n2=normal(s2[15],s2[11],s2[7],s2[3],s2[2],s2[1],s2[0]); if(abs2(n2) <= epsilon) { n2=normal(s2[15],s2[11],s2[7],s2[3],s2[4],s2[8],s2[12]); if(abs2(n2) <= epsilon) n2=normal(s2[12],s2[13],s2[14],s2[15],s2[2],s2[1],s2[0]); } - + triple n3=normal(s3[3],s3[2],s3[1],s3[0],s3[4],s3[8],s3[12]); if(abs2(n3) <= epsilon) { n3=normal(s3[3],s3[2],s3[1],s3[0],s3[13],s3[14],s3[15]); if(abs2(n3) <= epsilon) n3=normal(s3[15],s3[11],s3[7],s3[3],s3[4],s3[8],s3[12]); } - + triple n4=normal(s2[3],s2[2],s2[1],m4,s2[4],s2[8],s2[12]); - + // A kludge to remove subdivision cracks, only applied the first time // an edge is found to be flat before the rest of the subpatch is. - + triple m0=0.5*(P0+P1); if(!flat0) { if((flat0=Straightness(p0,p[4],p[8],p12) < res2)) m0 -= Epsilon*unit(differential(s1[0],s1[1],s1[2],s1[3])); else m0=s0[12]; } - + triple m1=0.5*(P1+P2); if(!flat1) { if((flat1=Straightness(p12,p[13],p[14],p15) < res2)) m1 -= Epsilon*unit(differential(s2[12],s2[8],s2[4],s2[0])); else m1=s1[15]; } - + triple m2=0.5*(P2+P3); if(!flat2) { if((flat2=Straightness(p15,p[11],p[7],p3) < res2)) m2 -= Epsilon*unit(differential(s3[15],s3[14],s3[13],s3[12])); else m2=s2[3]; } - + triple m3=0.5*(P3+P0); if(!flat3) { if((flat3=Straightness(p0,p[1],p[2],p3) < res2)) m3 -= Epsilon*unit(differential(s0[3],s0[7],s0[11],s0[15])); else m3=s3[0]; } - + if(color) { GLfloat c0[4],c1[4],c2[4],c3[4],c4[4]; for(size_t i=0; i < 4; ++i) { @@ -711,13 +710,13 @@ void BezierPatch::render(const triple *p, c3[i]=0.5*(C3[i]+C0[i]); c4[i]=0.5*(c0[i]+c2[i]); } - + GLuint i0=data.Vertex(m0,n0,c0); GLuint i1=data.Vertex(m1,n1,c1); GLuint i2=data.Vertex(m2,n2,c2); GLuint i3=data.Vertex(m3,n3,c3); GLuint i4=data.Vertex(m4,n4,c4); - + render(s0,I0,i0,i4,i3,P0,m0,m4,m3,flat0,false,false,flat3,C0,c0,c4,c3); render(s1,i0,I1,i1,i4,m0,P1,m1,m4,flat0,flat1,false,false,c0,C1,c1,c4); render(s2,i4,i1,I2,i2,m4,m1,P2,m2,false,flat1,flat2,false,c4,c1,C2,c2); @@ -728,7 +727,7 @@ void BezierPatch::render(const triple *p, GLuint i2=(data.*pvertex)(m2,n2); GLuint i3=(data.*pvertex)(m3,n3); GLuint i4=(data.*pvertex)(m4,n4); - + render(s0,I0,i0,i4,i3,P0,m0,m4,m3,flat0,false,false,flat3); render(s1,i0,I1,i1,i4,m0,P1,m1,m4,flat0,flat1,false,false); render(s2,i4,i1,I2,i2,m4,m1,P2,m2,false,flat1,flat2,false); @@ -743,36 +742,36 @@ void BezierTriangle::render(const triple *p, bool straight, GLfloat *c0) epsilon=0; for(int i=1; i < 10; ++i) epsilon=max(epsilon,abs2(p[i]-p0)); - + epsilon *= DBL_EPSILON; - + triple p6=p[6]; triple p9=p[9]; - + triple n0=normal(p9,p[5],p[2],p0,p[1],p[3],p6); - triple n1=normal(p0,p[1],p[3],p6,p[7],p[8],p9); + triple n1=normal(p0,p[1],p[3],p6,p[7],p[8],p9); triple n2=normal(p6,p[7],p[8],p9,p[5],p[2],p0); - + GLuint i0,i1,i2; if(color) { GLfloat *c1=c0+4; GLfloat *c2=c0+8; - + i0=data.Vertex(p0,n0,c0); i1=data.Vertex(p6,n1,c1); i2=data.Vertex(p9,n2,c2); - + if(!straight) render(p,i0,i1,i2,p0,p6,p9,false,false,false,c0,c1,c2); } else { i0=(data.*pvertex)(p0,n0); i1=(data.*pvertex)(p6,n1); i2=(data.*pvertex)(p9,n2); - + if(!straight) render(p,i0,i1,i2,p0,p6,p9,false,false,false); } - + if(straight) { triple P[]={p0,p6,p9}; if(!offscreen(3,P)) { @@ -923,10 +922,10 @@ void BezierTriangle::render(const triple *p, triple n0=normal(l300,r012,r021,r030,u201,u102,l030); triple n1=normal(r030,u201,u102,l030,l120,l210,l300); triple n2=normal(l030,l120,l210,l300,r012,r021,r030); - + // A kludge to remove subdivision cracks, only applied the first time // an edge is found to be flat before the rest of the subpatch is. - + triple m0=0.5*(P1+P2); if(!flat0) { if((flat0=Straightness(r300,p210,p120,u030) < res2)) @@ -958,11 +957,11 @@ void BezierTriangle::render(const triple *p, c1[i]=0.5*(C2[i]+C0[i]); c2[i]=0.5*(C0[i]+C1[i]); } - + GLuint i0=data.Vertex(m0,n0,c0); GLuint i1=data.Vertex(m1,n1,c1); GLuint i2=data.Vertex(m2,n2,c2); - + render(l,I0,i2,i1,P0,m2,m1,false,flat1,flat2,C0,c2,c1); render(r,i2,I1,i0,m2,P1,m0,flat0,false,flat2,c2,C1,c0); render(u,i1,i0,I2,m1,m0,P2,flat0,flat1,false,c1,c0,C2); @@ -971,7 +970,7 @@ void BezierTriangle::render(const triple *p, GLuint i0=(data.*pvertex)(m0,n0); GLuint i1=(data.*pvertex)(m1,n1); GLuint i2=(data.*pvertex)(m2,n2); - + render(l,I0,i2,i1,P0,m2,m1,false,flat1,flat2); render(r,i2,I1,i0,m2,P1,m0,flat0,false,flat2); render(u,i1,i0,I2,m1,m0,P2,flat0,flat1,false); @@ -986,7 +985,7 @@ void transform(const std::vector<VertexData>& b) // xbuffer.resize(n); // ybuffer.resize(n); zbuffer.resize(n); - + double Tz0=gl::dView[2]; double Tz1=gl::dView[6]; double Tz2=gl::dView[10]; @@ -1001,51 +1000,51 @@ void transform(const std::vector<VertexData>& b) void bounds(const std::vector<GLuint>& I) { unsigned n=I.size()/3; -/* +/* xmin.resize(n); xmax.resize(n); ymin.resize(n); ymax.resize(n); */ - + zmin.resize(n); zmax.resize(n); - + for(unsigned i=0; i < n; ++i) { unsigned i3=3*i; unsigned Ia=I[i3]; unsigned Ib=I[i3+1]; unsigned Ic=I[i3+2]; - - + + /* - double xa=xbuffer[Ia]; - double xb=xbuffer[Ib]; - double xc=xbuffer[Ic]; - - double ya=ybuffer[Ia]; - double yb=ybuffer[Ib]; - double yc=ybuffer[Ic]; + double xa=xbuffer[Ia]; + double xb=xbuffer[Ib]; + double xc=xbuffer[Ic]; + + double ya=ybuffer[Ia]; + double yb=ybuffer[Ib]; + double yc=ybuffer[Ic]; */ - + double za=zbuffer[Ia]; double zb=zbuffer[Ib]; double zc=zbuffer[Ic]; - + /* - xmin[i]=min(xa,xb,xc); - xmax[i]=max(xa,xb,xc); - - ymin[i]=min(ya,yb,yc); - ymax[i]=max(ya,yb,yc); + xmin[i]=min(xa,xb,xc); + xmax[i]=max(xa,xb,xc); + + ymin[i]=min(ya,yb,yc); + ymax[i]=max(ya,yb,yc); */ - + zmin[i]=min(za,zb,zc); zmax[i]=max(za,zb,zc); } } #endif - + void sortTriangles() { if(!transparentData.indices.empty()) { @@ -1062,16 +1061,17 @@ void Triangles::queue(size_t nP, const triple* P, size_t nN, const triple* N, const uint32_t (*CC)[3], bool Transparent) { if(!nN) return; - + data.clear(); Onscreen=true; transparent=Transparent; - + notRendered(); + data.Vertices.resize(nP); data.indices.resize(3*nI); - - MaterialIndex=nC ? -1-materialIndex : 1+materialIndex; - + + MaterialIndex=nC ? -1-materialIndex : 1+materialIndex; + for(size_t i=0; i < nI; ++i) { const uint32_t *PI=PP[i]; uint32_t PI0=PI[0]; @@ -1111,7 +1111,7 @@ void Triangles::queue(size_t nP, const triple* P, size_t nN, const triple* N, } append(); } - + #endif } //namespace camp |