diff options
Diffstat (limited to 'Build/source/utils/asymptote/base')
-rw-r--r-- | Build/source/utils/asymptote/base/obj.asy | 9 | ||||
-rw-r--r-- | Build/source/utils/asymptote/base/three.asy | 121 | ||||
-rw-r--r-- | Build/source/utils/asymptote/base/three_surface.asy | 67 |
3 files changed, 166 insertions, 31 deletions
diff --git a/Build/source/utils/asymptote/base/obj.asy b/Build/source/utils/asymptote/base/obj.asy index 158d417c136..0a6c4ab047c 100644 --- a/Build/source/utils/asymptote/base/obj.asy +++ b/Build/source/utils/asymptote/base/obj.asy @@ -98,6 +98,15 @@ struct obj { } } +obj operator * (transform3 T, obj o) +{ + obj ot; + ot.s=T*o.s; + ot.surfacepen=copy(o.surfacepen); + ot.meshpen=copy(o.meshpen); + return ot; +} + void draw(picture pic=currentpicture, obj o, light light=currentlight) { draw(pic,o.s,o.surfacepen,o.meshpen,light); diff --git a/Build/source/utils/asymptote/base/three.asy b/Build/source/utils/asymptote/base/three.asy index 23a23223141..5c3a404514f 100644 --- a/Build/source/utils/asymptote/base/three.asy +++ b/Build/source/utils/asymptote/base/three.asy @@ -23,17 +23,9 @@ string defaultembed3Doptions; string defaultembed3Dscript; real defaulteyetoview=63mm/1000mm; -string defaultlabelname="label"; -string Billboard=" "+defaultlabelname; - -string defaultlabelname() -{ - return settings.billboard ? Billboard : defaultlabelname; -} - string partname(string s, int i=0) { - return s == "" ? s : s+"-"+string(i); + return s == "" ? "" : s+"-"+string(i); } triple O=(0,0,0); @@ -331,7 +323,7 @@ projection projection() { projection P; real[] a=_projection(); - if(a[10] == 0.0) return currentprojection; + if(a.length == 0 || a[10] == 0.0) return currentprojection; int k=0; return a[0] == 1 ? orthographic((a[++k],a[++k],a[++k]),(a[++k],a[++k],a[++k]), @@ -2349,6 +2341,11 @@ private string Format(real[] c) return Format((c[0],c[1],c[2])); } +private string format(triple v, string sep=" ") +{ + return string(v.x)+sep+string(v.y)+sep+string(v.z); +} + private string[] file3; private string projection(bool infinity, real viewplanesize) @@ -2372,6 +2369,97 @@ handler.onEvent=function(event) }"; } +private string projection(bool infinity, real viewplanesize) +{ + return "activeCamera=scene.cameras.getByIndex(0); +function asyProjection() {"+ + (infinity ? "activeCamera.projectionType=activeCamera.TYPE_ORTHOGRAPHIC;" : + "activeCamera.projectionType=activeCamera.TYPE_PERSPECTIVE;")+" +activeCamera.viewPlaneSize="+string(viewplanesize)+"; +activeCamera.binding=activeCamera.BINDING_"+(infinity ? "MAX" : "VERTICAL")+"; +} + +asyProjection(); + +handler=new CameraEventHandler(); +runtime.addEventHandler(handler); +handler.onEvent=function(event) +{ + asyProjection(); + scene.update(); +}"; +} + +private string billboard(int[] index, triple[] center) +{ + if(index.length == 0) return ""; + string s=" +var zero=new Vector3(0,0,0); +var meshes=scene.meshes; +var count=meshes.count; + +var index=new Array(); +for(i=0; i < count; i++) { + var mesh=meshes.getByIndex(i); + var name=mesh.name; + end=name.lastIndexOf(\".\")-1; + if(end > 0) { + if(name.substr(end,1) == \"\001\") { + start=name.lastIndexOf(\"-\")+1; + n=end-start; + if(n > 0) { + index[name.substr(start,n)]=i; + mesh.name=name.substr(0,start-1); + } + } + } +} + +var center=new Array( +"; + for(int i=0; i < center.length; ++i) + s += "Vector3("+format(center[i],",")+"), +"; + s += "); + +billboardHandler=new RenderEventHandler(); +billboardHandler.onEvent=function(event) +{ + var camera=scene.cameras.getByIndex(0); + var position=camera.position; + var direction=position.subtract(camera.targetPosition); + var up=camera.up.subtract(position); + + function f(i,k) { + j=index[i]; + if(j >= 0) { + var mesh=meshes.getByIndex(j); + var name=mesh.name; + var R=Matrix4x4(); + R.setView(zero,direction,up); + var c=center[k]; + var T=mesh.transform; + T.setIdentity(); + T.translateInPlace(c.scale(-1)); + T.multiplyInPlace(R); + T.translateInPlace(c); + } + } +"; + for(int i=0; i < index.length; ++i) + s += "f("+string(i)+","+string(index[i])+"); +"; + s += " + runtime.refresh(); +} + +runtime.addEventHandler(billboardHandler); + +runtime.refresh(); +"; +return s; +} + string lightscript(light light) { string script="for(var i=scene.lights.count-1; i >= 0; i--) scene.lights.removeByIndex(i);"+'\n\n'; @@ -2379,8 +2467,8 @@ string lightscript(light light) { string Li="L"+string(i); real[] diffuse=light.diffuse[i]; script += Li+"=scene.createLight();"+'\n'+ - Li+".direction.set("+Format(-light.position[i],",")+");"+'\n'+ - Li+".color.set("+Format((diffuse[0],diffuse[1],diffuse[2]),",")+");"+'\n'; + Li+".direction.set("+format(-light.position[i],",")+");"+'\n'+ + Li+".color.set("+format((diffuse[0],diffuse[1],diffuse[2]),",")+");"+'\n'; } // Work around initialization bug in Adobe Reader 8.0: return script +" @@ -2437,10 +2525,13 @@ string embed3D(string label="", string text=label, string prefix, } else if(!P.absolute) P.angle=2*aTan(Tan(0.5*P.angle)); - string name=prefix+".js"; - writeJavaScript(name,lightscript+projection(P.infinity,viewplanesize),script); + int[] index; + triple[] center; + shipout3(prefix,f,index,center); - shipout3(prefix,f); + string name=prefix+".js"; + writeJavaScript(name,lightscript+projection(P.infinity,viewplanesize)+ + billboard(index,center),script); prefix += ".prc"; if(!settings.inlinetex) diff --git a/Build/source/utils/asymptote/base/three_surface.asy b/Build/source/utils/asymptote/base/three_surface.asy index b60a9be6156..e520229371f 100644 --- a/Build/source/utils/asymptote/base/three_surface.asy +++ b/Build/source/utils/asymptote/base/three_surface.asy @@ -1130,8 +1130,27 @@ real PRCshininess(real shininess) return s(shininess); } +struct interaction +{ + int type; + bool targetsize; + void operator init(int type, bool targetsize=false) { + this.type=type; + this.targetsize=targetsize; + } +} + +restricted interaction Embedded=interaction(0); +restricted interaction Billboard=interaction(1); + +interaction LabelInteraction() +{ + return settings.autobillboard ? Billboard : Embedded; +} + void draw3D(frame f, patch s, triple center=O, material m, - light light=currentlight, string name="") + light light=currentlight, string name="", + interaction interaction=Embedded) { if(s.colors.length > 0) m=mean(s.colors); @@ -1143,7 +1162,8 @@ void draw3D(frame f, patch s, triple center=O, material m, PRCshininess=PRCshininess(m.shininess); real granularity=m.granularity >= 0 ? m.granularity : defaultgranularity; draw(f,s.P,center,s.straight,m.p,m.opacity,m.shininess,PRCshininess, - granularity,s.planar ? s.normal(0.5,0.5) : O,s.colors,lighton,name); + granularity,s.planar ? s.normal(0.5,0.5) : O,s.colors,lighton,name, + interaction.type); } void tensorshade(transform t=identity(), frame f, patch s, @@ -1227,11 +1247,18 @@ void draw(picture pic=currentpicture, surface s, int nu=1, int nv=1, { if(s.empty()) return; + bool cyclic=surfacepen.cyclic; + surfacepen=copy(surfacepen); + surfacepen.cyclic=cyclic; + cyclic=meshpen.cyclic; + meshpen=copy(meshpen); + meshpen.cyclic=cyclic; + pic.add(new void(frame f, transform3 t, picture pic, projection P) { surface S=t*s; - if(is3D()) { + if(is3D()) draw(f,S,nu,nv,surfacepen,meshpen,light,meshlight,name); - } else if(pic != null) + else if(pic != null) pic.add(new void(frame f, transform T) { draw(T,f,S,nu,nv,surfacepen,meshpen,light,meshlight,P); },true); @@ -1354,20 +1381,21 @@ path[] path(Label L, pair z=0, projection P) } void label(frame f, Label L, triple position, align align=NoAlign, - pen p=currentpen, bool targetsize=false, light light=nolight, - string name=defaultlabelname(), projection P=currentprojection) + pen p=currentpen, light light=nolight, + string name=L.s, interaction interaction=LabelInteraction(), + projection P=currentprojection) { Label L=L.copy(); L.align(align); L.p(p); - if(targetsize && settings.render != 0) + if(interaction.targetsize && settings.render != 0) L.T=L.T*scale(abs(P.camera-position)/abs(P.vector())); if(L.defaulttransform3) L.T3=transform3(P); if(is3D()) { int i=-1; for(patch S : surface(L,position).s) - draw3D(f,S,position,L.p,light,partname(name,++i)); + draw3D(f,S,position,L.p,light,partname(name,++i),interaction); } else { if(L.filltype == NoFill) fill(f,path(L,project(position,P.t),P), @@ -1382,8 +1410,9 @@ void label(frame f, Label L, triple position, align align=NoAlign, } void label(picture pic=currentpicture, Label L, triple position, - align align=NoAlign, pen p=currentpen, bool targetsize=false, - light light=nolight, string name=defaultlabelname()) + align align=NoAlign, pen p=currentpen, + light light=nolight, string name=L.s, + interaction interaction=LabelInteraction()) { Label L=L.copy(); L.align(align); @@ -1397,14 +1426,14 @@ void label(picture pic=currentpicture, Label L, triple position, determinant(P.t) != 0) L.align(L.align.dir*unit(project(v+L.align.dir3,P.t)-project(v,P.t))); - if(targetsize && settings.render != 0) + if(interaction.targetsize && settings.render != 0) L.T=L.T*scale(abs(P.camera-v)/abs(P.vector())); if(L.defaulttransform3) L.T3=transform3(P); if(is3D()) { int i=-1; for(patch S : surface(L,v).s) - draw3D(f,S,v,L.p,light,partname(name,++i)); + draw3D(f,S,v,L.p,light,partname(name,++i),interaction); } if(pic != null) { if(L.filltype == NoFill) @@ -1420,7 +1449,7 @@ void label(picture pic=currentpicture, Label L, triple position, },!L.defaulttransform3); Label L=L.copy(); - if(targetsize && settings.render != 0) + if(interaction.targetsize && settings.render != 0) L.T=L.T*scale(abs(currentprojection.camera-position)/ abs(currentprojection.vector())); path[] g=texpath(L); @@ -1433,7 +1462,8 @@ void label(picture pic=currentpicture, Label L, triple position, } void label(picture pic=currentpicture, Label L, path3 g, align align=NoAlign, - bool targetsize=false, pen p=currentpen) + pen p=currentpen, string name=L.s, + interaction interaction=LabelInteraction()) { Label L=L.copy(); L.align(align); @@ -1449,7 +1479,7 @@ void label(picture pic=currentpicture, Label L, path3 g, align align=NoAlign, a.dir3=dir(g,position); // Pass 3D direction via unused field. L.align(a); } - label(pic,L,point(g,position),targetsize); + label(pic,L,point(g,position),name,interaction); } surface extrude(Label L, triple axis=Z) @@ -1467,7 +1497,7 @@ restricted surface nullsurface; // Embed a Label onto a surface. surface surface(Label L, surface s, real uoffset, real voffset, - real height=0, bool bottom=false, bool top=true) + real height=0, bool bottom=true, bool top=true) { int nu=s.index.length; int nv; @@ -1689,6 +1719,11 @@ void draw(picture pic=currentpicture, triple[][] P, real[] uknot, real[] vknot, if(colors.length > 0) m=mean(colors); bool lighton=light.on(); + P=copy(P); + uknot=copy(uknot); + vknot=copy(vknot); + weights=copy(weights); + colors=copy(colors); pic.add(new void(frame f, transform3 t, picture pic, projection Q) { if(is3D()) { triple[][] P=t*P; |