diff options
author | Karl Berry <karl@freefriends.org> | 2019-10-06 17:17:34 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2019-10-06 17:17:34 +0000 |
commit | 7f9f7dad00ea5f025578c491005835740f9ffd90 (patch) | |
tree | 011a87a78042a82ea3a18f5c08e60f6a3930bf0b /Build/source/utils/asymptote/drawsurface.cc | |
parent | 37d8fb68e502daabe6aa5f5ae9fb78191f275742 (diff) |
asy 2.56 sources
git-svn-id: svn://tug.org/texlive/trunk@52300 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/drawsurface.cc')
-rw-r--r-- | Build/source/utils/asymptote/drawsurface.cc | 397 |
1 files changed, 185 insertions, 212 deletions
diff --git a/Build/source/utils/asymptote/drawsurface.cc b/Build/source/utils/asymptote/drawsurface.cc index 80f7581ee32..617474ea4cc 100644 --- a/Build/source/utils/asymptote/drawsurface.cc +++ b/Build/source/utils/asymptote/drawsurface.cc @@ -12,7 +12,7 @@ #include <iomanip> #include <fstream> -#ifdef HAVE_GL +#ifdef HAVE_LIBGLM #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> @@ -20,28 +20,19 @@ using namespace prc; #include "material.h" -namespace camp { -#ifdef HAVE_GL -mem::vector<Material> drawElement::material; -MaterialMap drawElement::materialMap; -size_t drawElement::materialIndex; +namespace camp { -using gl::modelView; -//double* Tx=modelView.T; // x-component of current transform -//double* Ty=modelView.T+4; // y-component of current transform -double* Tz=modelView.T+8; // z-component of current transform - -#endif +mem::vector<triple> drawElement::center; +size_t drawElement::centerIndex=0; +triple drawElement::lastcenter=0; +size_t drawElement::lastcenterIndex=0; const triple drawElement::zero; using vm::array; -#ifdef HAVE_GL -BezierCurve drawSurface::C; -BezierPatch drawBezierPatch::S; -BezierTriangle drawBezierTriangle::S; +#ifdef HAVE_LIBGLM void storecolor(GLfloat *colors, int i, const vm::array &pens, int j) { @@ -61,48 +52,38 @@ void storecolor(GLfloat *colors, int i, const RGBAColour& p) colors[i+3]=p.A; } -void clearMaterialBuffer(bool draw) -{ - if(draw) { - drawBezierPatch::S.draw(); - drawPath3::R.draw(); - drawPixel::R.draw(); - } - drawElement::material.clear(); - drawElement::material.reserve(nmaterials); - drawElement::materialMap.clear(); - drawElement::materialIndex=0; -} - void setcolors(bool colors, const RGBAColour& diffuse, const RGBAColour& emissive, const RGBAColour& specular, double shininess, - double metallic, double fresnel0) + double metallic, double fresnel0, jsfile *out) { Material m; if(colors) { static glm::vec4 Black(0.0,0.0,0.0,diffuse.A); m=Material(Black,Black, glm::vec4(specular.R,specular.G,specular.B,specular.A), - shininess, metallic, fresnel0); - } else + shininess,metallic,fresnel0); + } else m=Material(glm::vec4(diffuse.R,diffuse.G,diffuse.B,diffuse.A), glm::vec4(emissive.R,emissive.G,emissive.B,emissive.A), glm::vec4(specular.R,specular.G,specular.B,specular.A), - shininess, metallic, fresnel0); + shininess,metallic,fresnel0); - MaterialMap::iterator p=drawElement::materialMap.find(m); - if(p != drawElement::materialMap.end()) - drawElement::materialIndex=p->second; + MaterialMap::iterator p=materialMap.find(m); + if(p != materialMap.end()) materialIndex=p->second; else { - drawElement::materialIndex=drawElement::material.size(); - if(drawElement::materialIndex >= nmaterials) + materialIndex=material.size(); + if(materialIndex >= nmaterials) nmaterials=min(Maxmaterials,2*nmaterials); - if(drawElement::materialIndex >= Maxmaterials) +#ifdef HAVE_GL + if(!out && materialIndex >= Maxmaterials) clearMaterialBuffer(true); - drawElement::material.push_back(m); - drawElement::materialMap[m]=drawElement::materialIndex; +#endif + material.push_back(m); + materialMap[m]=materialIndex; + if(out) + out->addMaterial(materialIndex); } } @@ -161,8 +142,8 @@ void drawBezierPatch::bounds(const double* t, bbox3& b) c0=cz[0]; fuzz=Fuzz*run::norm(cz,16); - z=bound(cz,min,b.empty ? c0 : min(c0,b.lower),fuzz,maxdepth); - Z=bound(cz,max,b.empty ? c0 : max(c0,b.upper),fuzz,maxdepth); + z=bound(cz,min,b.empty ? c0 : min(c0,b.near),fuzz,maxdepth); + Z=bound(cz,max,b.empty ? c0 : max(c0,b.far),fuzz,maxdepth); } b.add(x,y,z); @@ -238,9 +219,10 @@ bool drawBezierPatch::write(prcfile *out, unsigned int *, double, groupsmap&) if(straight) { triple vertices[]={controls[0],controls[12],controls[3],controls[15]}; - if(colors) - out->addQuad(vertices,colors); - else + if(colors) { + prc::RGBAColour Colors[]={colors[0],colors[1],colors[3],colors[2]}; + out->addQuad(vertices,Colors); + } else out->addRectangle(vertices,m); } else out->addPatch(controls,m); @@ -248,84 +230,89 @@ bool drawBezierPatch::write(prcfile *out, unsigned int *, double, groupsmap&) return true; } +bool drawBezierPatch::write(jsfile *out) +{ +#ifdef HAVE_LIBGLM + if(invisible) + return true; + + if(billboard) { + meshinit(); + drawElement::centerIndex=centerIndex; + } else drawElement::centerIndex=0; + + setcolors(colors,diffuse,emissive,specular,shininess,metallic,fresnel0,out); + + if(straight) { + triple Controls[]={controls[0],controls[12],controls[15],controls[3]}; + out->addPatch(Controls,4,Min,Max,colors,4); + } else + out->addPatch(controls,16,Min,Max,colors,4); + +#endif + return true; +} + void drawBezierPatch::render(double size2, const triple& b, const triple& B, - double perspective, bool transparent) + double perspective, bool remesh) { #ifdef HAVE_GL - if(invisible || - ((colors ? colors[0].A+colors[1].A+colors[2].A+colors[3].A < 4.0 : - diffuse.A < 1.0) ^ transparent)) return; - - const bool billboard=interaction == BILLBOARD && - !settings::getSetting<bool>("offscreen"); - triple m,M; - - double f,F,s; - if(perspective) { - f=Min.getz()*perspective; - F=Max.getz()*perspective; - m=triple(min(f*b.getx(),F*b.getx()),min(f*b.gety(),F*b.gety()),b.getz()); - M=triple(max(f*B.getx(),F*B.getx()),max(f*B.gety(),F*B.gety()),B.getz()); - s=max(f,F); - } else { - m=b; - M=B; - s=1.0; - } + if(invisible) return; + transparent=colors ? colors[0].A+colors[1].A+colors[2].A+colors[3].A < 4.0 : + diffuse.A < 1.0; - const pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety())); - - bbox3 box(m,M); - box.transform(modelView.Tinv); - m=box.Min(); - M=box.Max(); + bool offscreen; + if(billboard) { + drawElement::centerIndex=centerIndex; + BB.init(center); + offscreen=bbox2(Min,Max,BB).offscreen(); + } else + offscreen=bbox2(Min,Max).offscreen(); - if(!billboard && (Max.getx() < m.getx() || Min.getx() > M.getx() || - Max.gety() < m.gety() || Min.gety() > M.gety() || - Max.getz() < m.getz() || Min.getz() > M.getz())) + if(offscreen) { // Fully offscreen + S.Onscreen=false; + S.data.clear(); return; + } + + triple *Controls; + triple Controls0[16]; + if(billboard) { + Controls=Controls0; + for(size_t i=0; i < 16; i++) { + Controls[i]=BB.transform(controls[i]); + } + } else { + Controls=controls; + if(!remesh && S.Onscreen) { // Fully onscreen; no need to re-render + S.append(); + return; + } + } + + double s=perspective ? Min.getz()*perspective : 1.0; // Move to glrender + + const pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety())); setcolors(colors,diffuse,emissive,specular,shininess,metallic,fresnel0); - if(billboard) BB.init(center); - GLfloat c[16]; if(colors) for(size_t i=0; i < 4; ++i) storecolor(c,4*i,colors[i]); - triple *Controls; - triple Controls0[16]; - if(billboard) { - Controls=Controls0; - for(size_t i=0; i < 16; i++) - Controls[i]=BB.transform(controls[i]); - } else - Controls=controls; - if(gl::outlinemode) { triple edge0[]={Controls[0],Controls[4],Controls[8],Controls[12]}; - C.queue(edge0,straight,size3.length()/size2,m,M); + C.queue(edge0,straight,size3.length()/size2); triple edge1[]={Controls[12],Controls[13],Controls[14],Controls[15]}; - C.queue(edge1,straight,size3.length()/size2,m,M); + C.queue(edge1,straight,size3.length()/size2); triple edge2[]={Controls[15],Controls[11],Controls[7],Controls[3]}; - C.queue(edge2,straight,size3.length()/size2,m,M); + C.queue(edge2,straight,size3.length()/size2); triple edge3[]={Controls[3],Controls[2],Controls[1],Controls[0]}; - C.queue(edge3,straight,size3.length()/size2,m,M); - C.draw(); + C.queue(edge3,straight,size3.length()/size2); } else { - S.queue(Controls,straight,size3.length()/size2,m,M,transparent, + S.queue(Controls,straight,size3.length()/size2,transparent, colors ? c : NULL); - if(BezierPatch::nvertices >= gl::maxvertices) { - S.drawMaterials(); - BezierPatch::clear(); - gl::forceRemesh=true; - } - if(BezierPatch::Nvertices >= gl::maxvertices) { - S.drawColors(); - BezierPatch::Clear(); - gl::forceRemesh=true; - } } #endif } @@ -386,8 +373,8 @@ void drawBezierTriangle::bounds(const double* t, bbox3& b) c0=cz[0]; fuzz=Fuzz*run::norm(cz,10); - z=boundtri(cz,min,b.empty ? c0 : min(c0,b.lower),fuzz,maxdepth); - Z=boundtri(cz,max,b.empty ? c0 : max(c0,b.upper),fuzz,maxdepth); + z=boundtri(cz,min,b.empty ? c0 : min(c0,b.near),fuzz,maxdepth); + Z=boundtri(cz,max,b.empty ? c0 : max(c0,b.far),fuzz,maxdepth); } b.add(x,y,z); @@ -474,72 +461,87 @@ bool drawBezierTriangle::write(prcfile *out, unsigned int *, double, return true; } +bool drawBezierTriangle::write(jsfile *out) +{ +#ifdef HAVE_LIBGLM + if(invisible) + return true; + + if(billboard) { + meshinit(); + drawElement::centerIndex=centerIndex; + } else drawElement::centerIndex=0; + + setcolors(colors,diffuse,emissive,specular,shininess,metallic,fresnel0,out); + + if(straight) { + triple Controls[]={controls[0],controls[6],controls[9]}; + out->addPatch(Controls,3,Min,Max,colors,3); + } else + out->addPatch(controls,10,Min,Max,colors,3); + +#endif + return true; +} + void drawBezierTriangle::render(double size2, const triple& b, const triple& B, - double perspective, bool transparent) + double perspective, bool remesh) { #ifdef HAVE_GL - if(invisible || - ((colors ? colors[0].A+colors[1].A+colors[2].A < 3.0 : - diffuse.A < 1.0) ^ transparent)) return; - - const bool billboard=interaction == BILLBOARD && - !settings::getSetting<bool>("offscreen"); - triple m,M; - - double f,F,s; - if(perspective) { - f=Min.getz()*perspective; - F=Max.getz()*perspective; - m=triple(min(f*b.getx(),F*b.getx()),min(f*b.gety(),F*b.gety()),b.getz()); - M=triple(max(f*B.getx(),F*B.getx()),max(f*B.gety(),F*B.gety()),B.getz()); - s=max(f,F); - } else { - m=b; - M=B; - s=1.0; - } + if(invisible) return; + transparent=colors ? colors[0].A+colors[1].A+colors[2].A < 3.0 : + diffuse.A < 1.0; - const pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety())); - - bbox3 box(m,M); - box.transform(modelView.Tinv); - m=box.Min(); - M=box.Max(); - - if(!billboard && (Max.getx() < m.getx() || Min.getx() > M.getx() || - Max.gety() < m.gety() || Min.gety() > M.gety() || - Max.getz() < m.getz() || Min.getz() > M.getz())) + bool offscreen; + if(billboard) { + drawElement::centerIndex=centerIndex; + BB.init(center); + offscreen=bbox2(Min,Max,BB).offscreen(); + } else + offscreen=bbox2(Min,Max).offscreen(); + + if(offscreen) { // Fully offscreen + S.Onscreen=false; + S.data.clear(); return; + } - setcolors(colors,diffuse,emissive,specular,shininess,metallic,fresnel0); - - if(billboard) BB.init(center); - - GLfloat v[12]; - if(colors) - for(size_t i=0; i < 3; ++i) - storecolor(v,4*i,colors[i]); - triple *Controls; triple Controls0[10]; if(billboard) { Controls=Controls0; - for(size_t i=0; i < 10; i++) - Controls[i]=BB.transform(controls[i]); - } else + for(size_t i=0; i < 10; i++) { + Controls[i]=BB.transform(controls[i]); + } + } else { Controls=controls; + if(!remesh && S.Onscreen) { // Fully onscreen; no need to re-render + S.append(); + return; + } + } + + double s=perspective ? Min.getz()*perspective : 1.0; // Move to glrender + + const pair size3(s*(B.getx()-b.getx()),s*(B.gety()-b.gety())); + + setcolors(colors,diffuse,emissive,specular,shininess,metallic,fresnel0); + GLfloat c[12]; + if(colors) + for(size_t i=0; i < 3; ++i) + storecolor(c,4*i,colors[i]); + if(gl::outlinemode) { triple edge0[]={Controls[0],Controls[1],Controls[3],Controls[6]}; - C.queue(edge0,straight,size3.length()/size2,m,M); + C.queue(edge0,straight,size3.length()/size2); triple edge1[]={Controls[6],Controls[7],Controls[8],Controls[9]}; - C.queue(edge1,straight,size3.length()/size2,m,M); + C.queue(edge1,straight,size3.length()/size2); triple edge2[]={Controls[9],Controls[5],Controls[2],Controls[0]}; - C.queue(edge2,straight,size3.length()/size2,m,M); - C.draw(); + C.queue(edge2,straight,size3.length()/size2); } else - S.queue(Controls,straight,size3.length()/size2,m,M,transparent, - colors ? v : NULL); + S.queue(Controls,straight,size3.length()/size2,transparent, + colors ? c : NULL); #endif } @@ -651,37 +653,10 @@ void drawNurbs::displacement() #endif } -void drawNurbs::render(double size2, const triple& Min, const triple& Max, - double perspective, bool transparent) +void drawNurbs::render(double size2, const triple& b, const triple& B, + double perspective, bool remesh) { -#ifdef HAVE_GL - if(invisible || ((colors ? colors[3]+colors[7]+colors[11]+colors[15] < 4.0 - : diffuse.A < 1.0) ^ transparent)) return; - - bbox3 B(this->Min,this->Max); - B.transform(modelView.T); - - triple m=B.Min(); - triple M=B.Max(); - - if(perspective) { - double f=m.getz()*perspective; - double F=M.getz()*perspective; - if(M.getx() < min(f*Min.getx(),F*Min.getx()) || - m.getx() > max(f*Max.getx(),F*Max.getx()) || - M.gety() < min(f*Min.gety(),F*Min.gety()) || - m.gety() > max(f*Max.gety(),F*Max.gety()) || - M.getz() < Min.getz() || - m.getz() > Max.getz()) return; - } else { - if(M.getx() < Min.getx() || m.getx() > Max.getx() || - M.gety() < Min.gety() || m.gety() > Max.gety() || - M.getz() < Min.getz() || m.getz() > Max.getz()) return; - } - - setcolors(colors,diffuse,emissive,specular,shininess,metallic,fresnel0); // TODO: implement NURBS renderer -#endif } void drawSphere::P(triple& t, double x, double y, double z) @@ -910,41 +885,39 @@ bool drawTriangles::write(prcfile *out, unsigned int *, double, groupsmap&) return true; } -void drawTriangles::render(double size2, const triple& Min, - const triple& Max, double perspective, - bool transparent) +bool drawTriangles::write(jsfile *out) { -#ifdef HAVE_GL +#ifdef HAVE_LIBGLM if(invisible) - return; - - if(invisible || ((diffuse.A < 1.0) ^ transparent)) return; - - triple m,M; - - bbox3 B(this->Min,this->Max); - B.transform(modelView.T); + return true; + + setcolors(nC,diffuse,emissive,specular,shininess,metallic,fresnel0,out); + + out->addTriangles(nP,P,nN,N,nC,C,nI,PI,NI,CI,Min,Max); +#endif + return true; +} - m=B.Min(); - M=B.Max(); +void drawTriangles::render(double size2, const triple& b, + const triple& B, double perspective, + bool remesh) +{ +#ifdef HAVE_GL + if(invisible) return; + + transparent=diffuse.A < 1.0; - if(perspective) { - const double f=m.getz()*perspective; - const double F=M.getz()*perspective; - if((M.getx() < min(f*Min.getx(),F*Min.getx()) || - m.getx() > max(f*Max.getx(),F*Max.getx()) || - M.gety() < min(f*Min.gety(),F*Min.gety()) || - m.gety() > max(f*Max.gety(),F*Max.gety()) || - M.getz() < Min.getz() || - m.getz() > Max.getz())) - return; - } else { - if((M.getx() < Min.getx() || m.getx() > Max.getx() || - M.gety() < Min.gety() || m.gety() > Max.gety() || - M.getz() < Min.getz() || m.getz() > Max.getz())) - return; + if(bbox2(Min,Max).offscreen()) { // Fully offscreen + R.Onscreen=false; + R.data.clear(); + return; } + if(!remesh && R.Onscreen) { // Fully onscreen; no need to re-render + R.append(); + return; + } + setcolors(nC,diffuse,emissive,specular,shininess,metallic,fresnel0); R.queue(nP,P,nN,N,nC,C,nI,PI,NI,CI,transparent); #endif |