Skip to content
Kiln0.10Get Kiln

A metre-scale procedural suspension bridge with Art Deco towers, main cables, suspenders and a six-lane roadway, saved as full, web and far tiers from one Kiln source.

Standalone · Architecture

Golden Gate Bridge, three-quarter view on a neutral backdrop

Drag to orbit after opening. The model starts stationary.

Web detail in the interactive preview; the poster shows the full model. Full and far downloads are available below.

Revision r_76c7a4080e7844e185896b7e1b196e5a

Metres · roadway along Z · west +X · water Y = 0

The poster is this revision’s exported GLB rendered under the Kiln review lighting rig (review-neutral-v1) on the neutral backdrop, with nothing retouched. The 3D view applies the same rig (review-neutral-v1): its light directions and strengths, exposure, tone mapping and backdrop.

For your engine. The download is a standard glTF 2.0 binary (GLB) with PBR metallic-roughness materials. glTF stores materials, not lighting or tone mapping, so your engine decides how they read. This 3D view tone-maps with Review Neutral, the Khronos PBR Neutral construction with a smaller glare offset (0.015 instead of 0.04), at exposure 0.9. Its Tone mapping control also shows ACES and Linear, for comparison.

Triangles
311,826
Meshes drawn
173
Materials
11
Bounds · X × Y × Z
91.44 × 262.76 × 2067.96 m
Animation clips
None

Review views

Six views of this revision, rendered on the GPU from its source.

Six saved review views of the Golden Gate Bridge: front, right, back, left, top and three-quarter.
Material-faithful GPU source review views for r_76c7a4080e7844e185896b7e1b196e5a. These views come from a source evaluation (exactArtifact: false), not a capture of the exported runtime GLB.

Read the actual source.

Download .kiln.js

This is the source extracted from the sealed editable archive for the displayed revision.

golden-gate-bridge.kiln.js
// Golden Gate Bridge | original procedural geometry | CC0
const meta = { name: 'Golden Gate Bridge', role: 'wonder' };
const PARAMS = { lod: 'full' }; // full | web | far; the only variant selector.
const FULL=PARAMS.lod==='full', FAR=PARAMS.lod==='far';
const L={full:{roadSteps:160,cableSteps:660,cableSides:12,railPitch:3.81,crownSteps:16,lampStep:1,armSteps:10,trussBays:258},web:{roadSteps:32,cableSteps:180,cableSides:6,railPitch:3.81,crownSteps:6,lampStep:2,armSteps:6,trussBays:258},far:{roadSteps:16,cableSteps:80,cableSides:4,railPitch:15.24,crownSteps:4,lampStep:8,armSteps:3,trussBays:65}}[PARAMS.lod];
if(!L)throw new Error('Unknown bridge LOD');
const OMIT_DETAIL=['PlateSeams','RivetRows','PortalRivets','ClampFlangesBolts','DeckClevises','GussetPlates','SidewalkBearingStools','LongitudinalTStringers','DrainSlots','FormworkCourseLines'];
const OMIT_FAR=['FluteRibs','RecessedDecoPanels','SteppedBordersAndHaunches','CrownInsetPanels','ConnectionPlates','CableBands','FloorbeamISections','CrossFramesAndLateralX','OuterOpenRailings','RoadSafetyRailings','Underdeck','WestBypassFascia','EastBypassFascia','BrokenLaneLines','ExpansionJoints','ChevronFlutes','HousingPilasters','AccessDoorReveal'];
const D = { halfMain:640.08, end:982.98, stub:1032.98, cableX:13.716, tower:227.3808, sag:143.256, pitch:15.24, truss:7.62 };
const PV={crest:150,yMid:75.30,yTower:75.04,yEnd:62.55};PV.z1=D.halfMain-PV.crest/2;PV.z2=D.halfMain+PV.crest/2;PV.k=(PV.yMid-PV.yTower)/D.halfMain**2;PV.y1=PV.yMid-PV.k*PV.z1**2;PV.s1=-2*PV.k*PV.z1;PV.grade=(PV.y1+PV.s1*PV.crest/2-PV.yEnd)/(D.stub-D.halfMain);
function road(z) { const a=Math.min(Math.abs(z),D.stub); if(a<=PV.z1)return PV.yMid-PV.k*a*a; if(a<=PV.z2){const t=a-PV.z1;return PV.y1+PV.s1*t-(PV.grade+PV.s1)*t*t/(2*PV.crest);} return PV.yEnd+PV.grade*(D.stub-a); }
function roadSlope(z) { const a=Math.min(Math.abs(z),D.stub),s=a<=PV.z1?-2*PV.k*a:a<=PV.z2?PV.s1-(PV.grade+PV.s1)*(a-PV.z1)/PV.crest:-PV.grade; return z<0?-s:s; }
function roadTilt(z) { return new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1,0,0),-Math.atan(roadSlope(z))); }
function roadStations(z0,z1,n,walkSide) {
 const ds=FULL?25:FAR?100:50,cn=FAR?8:22,dl=PV.crest/cn,e=1e-8,zs=[],inCrest=t=>{const a=Math.abs(t);return a>PV.z1+e&&a<PV.z2-e;};
 n=Math.max(n,Math.ceil((z1-z0)/ds-e));
 for(let k=0;k<=n;k++){const t=z0+(z1-z0)*k/n;if(k===0||k===n||!inCrest(t))zs.push(t);}
 if(z1-z0>2*dl)for(const s of [-1,1])for(let j=0;j<=cn;j++){const t=s*(PV.z1+dl*j);if(t>z0+e&&t<z1-e)zs.push(t);}
 if(walkSide)for(const s of [-1,1])for(const v of [-26,-10.5,0,10.5,26]){const t=s*D.halfMain+v;if(t>z0+e&&t<z1-e)zs.push(t);}
 zs.sort((a,b)=>a-b);const out=[zs[0]];
 for(let i=1;i<zs.length;i++){const a=out[out.length-1],b=zs[i];if(b-a<e)continue;const m=Math.ceil((b-a)/(inCrest((a+b)/2)?dl:ds)-1e-6);for(let j=1;j<m;j++)out.push(a+(b-a)*j/m);out.push(b);}
 return out;
}
function cableY(z) {
 const a=Math.abs(z),q=a-D.halfMain;
 function base(v){if(v<=D.halfMain)return D.tower-D.sag+D.sag*(v/D.halfMain)**2;const t=(v-D.halfMain)/(D.end-D.halfMain);return D.tower+(64-D.tower)*t-24*t*(1-t);}
 if(Math.abs(q)>=5)return base(a);
 const edge=D.halfMain+(q<0?-5:5),t=1-Math.abs(q)/5,y0=base(edge),m=(base(edge+.01)-base(edge-.01))/.02*(q<0?5:-5);
 return (2*t*t*t-3*t*t+1)*y0+(t*t*t-2*t*t+t)*m+(-2*t*t*t+3*t*t)*D.tower;
}
function group(name,parent,pos=[0,0,0]) { const g=new THREE.Group();g.name=name;g.position.set(...pos);parent.add(g);return g; }
function chamfer(w,h,d,b=.05) {
 b=Math.min(b,w*.2,h*.2,d*.2); const A=[w/2,h/2,d/2],B=A.map(v=>v-b),P=[],N=[],U=[],I=[];
 function face(vs) { let a=new THREE.Vector3(...vs[0]), bb=new THREE.Vector3(...vs[1]),c=new THREE.Vector3(...vs[2]);let n=bb.clone().sub(a).cross(c.clone().sub(a)).normalize();let mid=new THREE.Vector3();vs.forEach(v=>mid.add(new THREE.Vector3(...v)));if(n.dot(mid)<0){vs.reverse();n.negate();}const off=P.length/3;for(const v of vs){P.push(...v);N.push(n.x,n.y,n.z);const ax=Math.abs(n.x),ay=Math.abs(n.y);if(ay>=ax&&ay>=Math.abs(n.z))U.push(v[0],v[2]);else if(ax>=Math.abs(n.z))U.push(v[2],v[1]);else U.push(v[0],v[1]);}for(let j=1;j<vs.length-1;j++)I.push(off,off+j,off+j+1); }
 for(let axis=0;axis<3;axis++)for(const s of [-1,1]){const u=(axis+1)%3,v=(axis+2)%3;face([[-1,-1],[1,-1],[1,1],[-1,1]].map(q=>{const p=[0,0,0];p[axis]=s*A[axis];p[u]=q[0]*B[u];p[v]=q[1]*B[v];return p;}));}
 for(let ax=0;ax<3;ax++){const u=(ax+1)%3,v=(ax+2)%3;for(const s of [-1,1])for(const t of [-1,1])face([[-1,0],[-1,1],[1,1],[1,0]].map(q=>{const p=[0,0,0];p[ax]=q[0]*B[ax];p[u]=s*(q[1]?B[u]:A[u]);p[v]=t*(q[1]?A[v]:B[v]);return p;}));}
 for(const x of [-1,1])for(const y of [-1,1])for(const z of [-1,1])face([[x*A[0],y*B[1],z*B[2]],[x*B[0],y*A[1],z*B[2]],[x*B[0],y*B[1],z*A[2]]]);
 return meshGeo({positions:P,normals:N,uvs:U,indices:I});
}
function merge(items) {
 const p=[],n=[],u=[],idx=[];const v=new THREE.Vector3(),nn=new THREE.Vector3();
 for(const item of items){const g=item.g;const mat=new THREE.Matrix4().compose(new THREE.Vector3(...(item.p||[0,0,0])),item.q||new THREE.Quaternion(),new THREE.Vector3(...(item.s||[1,1,1])));const nm=new THREE.Matrix3().getNormalMatrix(mat);const po=g.attributes.position,no=g.attributes.normal,uv=g.attributes.uv,off=p.length/3;
 for(let i=0;i<po.count;i++){v.fromBufferAttribute(po,i).applyMatrix4(mat);p.push(v.x,v.y,v.z);nn.fromBufferAttribute(no,i).applyMatrix3(nm).normalize();n.push(nn.x,nn.y,nn.z);u.push(uv?uv.getX(i):0,uv?uv.getY(i):0);}
 if(g.index)for(let i=0;i<g.index.count;i++)idx.push(off+g.index.getX(i));else for(let i=0;i<po.count;i++)idx.push(off+i);
 }return meshGeo({positions:p,normals:n,uvs:u,indices:idx});
}
function solid(name,g,mat,parent,p=[0,0,0],s=[1,1,1]){if(!FULL&&(OMIT_DETAIL.includes(name)||(FAR&&OMIT_FAR.includes(name))))return null;return createPart(name,g,mat,{parent,position:p,scale:s});}
function segmentItem(g,a,b,scale=[1,1]) {const av=new THREE.Vector3(...a),bv=new THREE.Vector3(...b),delta=bv.clone().sub(av);return {g,p:av.add(bv).multiplyScalar(.5).toArray(),q:new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(0,1,0),delta.clone().normalize()),s:[scale[0],delta.length(),scale[1]]};}
function flatShade(g){const po=g.attributes.position,uv=g.attributes.uv,ix=g.index,P=[],N=[],U=[],I=[],a=new THREE.Vector3(),b=new THREE.Vector3(),c=new THREE.Vector3();
 for(let t=0;t<ix.count;t+=3){const ids=[ix.getX(t),ix.getX(t+1),ix.getX(t+2)];a.fromBufferAttribute(po,ids[0]);b.fromBufferAttribute(po,ids[1]);c.fromBufferAttribute(po,ids[2]);const n=b.clone().sub(a).cross(c.clone().sub(a)).normalize();
 for(const id of ids){P.push(po.getX(id),po.getY(id),po.getZ(id));N.push(n.x,n.y,n.z);U.push(uv.getX(id),uv.getY(id));I.push(I.length);}}
 return meshGeo({positions:P,normals:N,uvs:U,indices:I});}
function walkShift(z){const a=Math.abs(Math.abs(z)-D.halfMain);return a<10.5?8.6:a<26?8.6*(26-a)/15.5:0;}
function roadSolid(x0,x1,z0,z1,topOffset,thick,steps=32,walkSide=0) {
 if(!FULL)steps=Math.min(steps,L.roadSteps);
 const zs=roadStations(z0,z1,walkSide?Math.max(2,Math.min(160,steps)):steps,walkSide);steps=zs.length-1;const P=[],I=[],U=[];for(let i=0;i<=steps;i++){const z=zs[i],y=road(z)+topOffset;const shift=walkSide*walkShift(z);P.push(x0+shift,y,z,x1+shift,y,z,x0+shift,y-thick,z,x1+shift,y-thick,z);U.push(x0,z,x1,z,x0,z,x1,z);}
 for(let i=0;i<steps;i++){const a=4*i,b=a+4;I.push(a,b,a+1,a+1,b,b+1,a+2,a+3,b+2,a+3,b+3,b+2,a,a+2,b,a+2,b+2,b,a+1,b+1,a+3,a+3,b+1,b+3);}
 I.push(0,1,2,1,3,2);const k=steps*4;I.push(k,k+2,k+1,k+1,k+2,k+3);return meshGeo({positions:P,indices:I,uvs:U});
}
function indexedSubset(g,indices) {
 const po=g.attributes.position,no=g.attributes.normal,uv=g.attributes.uv,map=new Map(),P=[],N=[],U=[],I=[];
 for(const id of indices){if(!map.has(id)){map.set(id,P.length/3);P.push(po.getX(id),po.getY(id),po.getZ(id));N.push(no.getX(id),no.getY(id),no.getZ(id));U.push(uv.getX(id),uv.getY(id));}I.push(map.get(id));}
 return meshGeo({positions:P,normals:N,uvs:U,indices:I});
}
function roadSurfaceParts(g) {
 const all=Array.from(g.index.array),wallEnd=(g.attributes.position.count/4-1)*24,top=[],body=[];
 for(let i=0;i<all.length;i++)(i<wallEnd&&i%24<6?top:body).push(all[i]);
 return [indexedSubset(g,top),indexedSubset(g,body)];
}
function metreBox(w,h,d,cy) {
 const H=[w/2,h/2,d/2],P=[],N=[],U=[],I=[];
 for(const [n,u,v] of [[[1,0,0],[0,1,0],[0,0,1]],[[-1,0,0],[0,0,1],[0,1,0]],[[0,1,0],[0,0,1],[1,0,0]],[[0,-1,0],[1,0,0],[0,0,1]],[[0,0,1],[1,0,0],[0,1,0]],[[0,0,-1],[0,1,0],[1,0,0]]]){
  const o=P.length/3;
  for(const [a,b] of [[-1,-1],[1,-1],[1,1],[-1,1]]){const p=[0,1,2].map(k=>(n[k]+a*u[k]+b*v[k])*H[k]);p[1]+=cy;P.push(...p);N.push(...n);if(n[1])U.push(p[0],p[2]);else if(n[0])U.push(p[2],p[1]);else U.push(p[0],p[1]);}
  I.push(o,o+1,o+2,o,o+2,o+3);
 }
 return meshGeo({positions:P,normals:N,uvs:U,indices:I});
}
function ellipseWall(rx,rz,wall,y0,y1) {
 const n=FULL?96:FAR?24:48,P=[],N=[],U=[],I=[],pt=(a,b,j)=>{const t=j%n/n*2*Math.PI;return [a*Math.cos(t),b*Math.sin(t)];};
 for(const [a,b,s] of [[rx,rz,1],[rx-wall,rz-wall,-1]]){
  const o=P.length/3;let arc=0;
  for(let j=0;j<=n;j++){const [x,z]=pt(a,b,j);if(j){const [px,pz]=pt(a,b,j-1);arc+=Math.hypot(x-px,z-pz);}const nl=Math.hypot(x/(a*a),z/(b*b)),nx=s*x/(a*a)/nl,nz=s*z/(b*b)/nl;P.push(x,y0,z,x,y1,z);N.push(nx,0,nz,nx,0,nz);U.push(arc,y0,arc,y1);}
  for(let j=0;j<n;j++){const b0=o+2*j,t0=b0+1,b1=b0+2,t1=b0+3;if(s>0)I.push(b0,t0,b1,b1,t0,t1);else I.push(b0,b1,t0,b1,t1,t0);}
 }
 const o=P.length/3;
 for(let j=0;j<n;j++){const [ox,oz]=pt(rx,rz,j),[ix,iz]=pt(rx-wall,rz-wall,j);P.push(ox,y0,oz,ix,y0,iz);N.push(0,-1,0,0,-1,0);U.push(ox,oz,ix,iz);}
 for(let j=0;j<n;j++){const a=o+2*j,b=o+2*((j+1)%n);I.push(a,b,a+1,a+1,b,b+1);}
 const o2=P.length/3;
 for(let j=0;j<n;j++){const [ox,oz]=pt(rx,rz,j),[ix,iz]=pt(rx-wall,rz-wall,j);P.push(ox,y1,oz,ix,y1,iz);N.push(0,1,0,0,1,0);U.push(ox,oz,ix,iz);}
 for(let j=0;j<n;j++){const a=o2+2*j,b=o2+2*((j+1)%n);I.push(a,a+1,b,a+1,b+1,b);}
 return meshGeo({positions:P,normals:N,uvs:U,indices:I});
}
function recessPanel(w,h) {
 const P=[],I=[],N=[],U=[];
 const out=[[-w/2,-h/2,.15],[w/2,-h/2,.15],[w/2,h/2,.15],[-w/2,h/2,.15]];
 const inn=[[-w/2+.16,-h/2+.22,-.025],[w/2-.16,-h/2+.22,-.025],[w/2-.16,h/2-.22,-.025],[-w/2+.16,h/2-.22,-.025]];
 const back=out.map(p=>[p[0],p[1],-.16]);
 function f(v){let a=new THREE.Vector3(...v[0]),b=new THREE.Vector3(...v[1]),c=new THREE.Vector3(...v[2]),n=b.sub(a).cross(c.sub(a)).normalize(),o=P.length/3;for(const p of v){P.push(...p);N.push(n.x,n.y,n.z);U.push(p[0],p[1]);}I.push(o,o+1,o+2,o,o+2,o+3);}
 for(let j=0;j<4;j++){let k=(j+1)%4;f([out[j],out[k],inn[k],inn[j]]);f([out[k],out[j],back[j],back[k]]);}
 f(inn);f([back[3],back[2],back[1],back[0]]);return meshGeo({positions:P,normals:N,uvs:U,indices:I});
}
function lodCableGeo(x) {
 const zs=[-1012.98,1012.98,-D.end,D.end],P=[],N=[],I=[],U=[],r=.4619625,sides=L.cableSides;
 if(!FAR)for(let i=0;i<=L.cableSteps;i++)zs.push(-1012.98+i*2025.96/L.cableSteps);
 for(let k=-63;k<=63;k++){const z=k*D.pitch;if(Math.abs(Math.abs(z)-D.halfMain)>1)zs.push(z);}
 for(const t of [-D.halfMain,D.halfMain])for(const dz of [-5,-2,-.5,0,.5,2,5])zs.push(t+dz);
 zs.sort((a,b)=>a-b);for(let i=zs.length-1;i>0;i--)if(Math.abs(zs[i]-zs[i-1])<1e-8)zs.splice(i,1);
 for(let j=0;j<zs.length;j++){const z=zs[j],slope=(cableY(z+.001)-cableY(z-.001))/.002,den=Math.sqrt(1+slope*slope);
 for(let k=0;k<sides;k++){const a=2*Math.PI*k/sides,c=Math.cos(a),s=Math.sin(a);P.push(x+r*c,cableY(z)+r*s/den,z-r*s*slope/den);N.push(c,s/den,-s*slope/den);U.push(k/sides,j/(zs.length-1));}}
 for(let j=0;j<zs.length-1;j++)for(let k=0;k<sides;k++){const a=j*sides+k,b=j*sides+(k+1)%sides,c=a+sides,d=b+sides;I.push(a,b,c,b,d,c);}
 for(const end of [0,1]){const ring=end?(zs.length-1)*sides:0,z=zs[end?zs.length-1:0],slope=(cableY(z+.001)-cableY(z-.001))/.002,normal=new THREE.Vector3(0,slope,1).normalize().multiplyScalar(end?1:-1),center=P.length/3;
 P.push(x,cableY(z),z);N.push(...normal.toArray());U.push(.5,.5);
 for(let k=0;k<sides;k++){P.push(P[(ring+k)*3],P[(ring+k)*3+1],P[(ring+k)*3+2]);N.push(...normal.toArray());U.push(.5+.5*Math.cos(k/sides*2*Math.PI),.5+.5*Math.sin(k/sides*2*Math.PI));}
 for(let k=0;k<sides;k++){const a=center+1+k,b=center+1+(k+1)%sides;if(end)I.push(center,a,b);else I.push(center,b,a);}}
 return meshGeo({positions:P,normals:N,indices:I,uvs:U});
}
function cappedCable(path,count,radius,sides){
 if(!FULL)return lodCableGeo(path.getPoint(0).x);
 const tube=new THREE.TubeGeometry(path,count,radius,sides,false),po=tube.attributes.position,P=[],N=[],U=[],I=[];
 for(const end of [0,1]){const normal=path.getTangentAt(end).multiplyScalar(end?1:-1),center=path.getPointAt(end),base=P.length/3;P.push(...center.toArray());N.push(...normal.toArray());U.push(.5,.5);const ring=end?count*(sides+1):0;
 for(let k=0;k<sides;k++){P.push(po.getX(ring+k),po.getY(ring+k),po.getZ(ring+k));N.push(...normal.toArray());U.push(.5+.5*Math.cos(k/sides*2*Math.PI),.5+.5*Math.sin(k/sides*2*Math.PI));}
 for(let k=0;k<sides;k++){const a=base+1+k,b=base+1+(k+1)%sides,va=new THREE.Vector3(P[a*3],P[a*3+1],P[a*3+2]).sub(center),vb=new THREE.Vector3(P[b*3],P[b*3+1],P[b*3+2]).sub(center);if(va.cross(vb).dot(normal)>0)I.push(base,a,b);else I.push(base,b,a);}
 }return merge([{g:tube},{g:meshGeo({positions:P,normals:N,uvs:U,indices:I})}]);
}
function openVerticalBox(w,h,d) {
 const P=[],N=[],U=[],I=[];
 for(const axis of [0,2])for(const s of [-1,1]){const other=axis===0?2:0,hw=w/2,hd=d/2,vs=[];
 for(const [a,b] of [[-1,-1],[1,-1],[1,1],[-1,1]]){const p=[0,b*h/2,0];p[axis]=s*(axis===0?hw:hd);p[other]=a*(other===0?hw:hd);vs.push(p);}
 const n=new THREE.Vector3(axis===0?s:0,0,axis===2?s:0);const ab=new THREE.Vector3(...vs[1]).sub(new THREE.Vector3(...vs[0])),ac=new THREE.Vector3(...vs[2]).sub(new THREE.Vector3(...vs[0]));if(ab.cross(ac).dot(n)<0)vs.reverse();const o=P.length/3;
 for(let k=0;k<4;k++){P.push(...vs[k]);N.push(...n.toArray());U.push(k===1||k===2?1:0,k>=2?1:0);}I.push(o,o+1,o+2,o,o+2,o+3);}
 return meshGeo({positions:P,normals:N,uvs:U,indices:I});
}
function surfaceStrap(w,h,depth) {
 const x=w/2,y=h/2;return meshGeo({positions:[-x,-y,0,x,-y,0,x,y,0,-x,y,0,-x,-y,depth,x,-y,depth,x,y,depth,-x,y,depth],indices:[4,5,6,4,6,7,0,4,7,0,7,3,1,2,6,1,6,5,0,1,5,0,5,4,3,7,6,3,6,2]});
}
function plateSkin(base,w,d,lo,hi) {
 if(!FULL)return base;
 const bevels=base.clone(),all=Array.from(base.index.array);bevels.setIndex(all.filter((v,i)=>i>=36||(i>=12&&i<24)));
 const cuts=[lo+.09];for(let y=lo+5;y<hi-.5;y+=6)cuts.push(y);cuts.push(hi-.09);
 const P=[],N=[],U=[],I=[],center=(lo+hi)/2;
 for(const axis of [0,2])for(const sign of [-1,1])for(let row=0;row<cuts.length-1;row++){
 const a=cuts[row],b=cuts[row+1],other=axis===0?2:0,half=(other===0?w:d)/2-.09,face=sign*(axis===0?w:d)/2,normal=new THREE.Vector3(axis===0?sign:0,0,axis===2?sign:0),vs=[];
 for(const [x,y] of [[-half,a],[half,a],[half,b],[-half,b]]){const p=[0,y-center,0];p[axis]=face;p[other]=x;vs.push(p);}
 if(new THREE.Vector3(...vs[1]).sub(new THREE.Vector3(...vs[0])).cross(new THREE.Vector3(...vs[2]).sub(new THREE.Vector3(...vs[0]))).dot(normal)<0)vs.reverse();
 const o=P.length/3,phase=((row*37+axis*17+(sign>0?11:3))%101)/101;
 for(const p of vs){P.push(...p);N.push(...normal.toArray());U.push(p[other]/(axis===0?d*.1466667:w*.21)+phase,(p[1]+center-a)/(b-a));}I.push(o,o+1,o+2,o,o+2,o+3);
 }return merge([{g:bevels},{g:meshGeo({positions:P,normals:N,uvs:U,indices:I})}]);
}
function cableRangeAtZ(geo,z) {
 const p=geo.attributes.position,idx=geo.index;let low=Infinity,high=-Infinity;
 for(let i=0;i<idx.count;i+=3){const a=idx.getX(i),b=idx.getX(i+1),c=idx.getX(i+2),za=p.getZ(a),zb=p.getZ(b),zc=p.getZ(c);
 if(z<Math.min(za,zb,zc)-1e-8||z>Math.max(za,zb,zc)+1e-8)continue;
 for(const [u,v] of [[a,b],[b,c],[c,a]]){const zu=p.getZ(u),zv=p.getZ(v);if(z<Math.min(zu,zv)-1e-8||z>Math.max(zu,zv)+1e-8)continue;
 if(Math.abs(zv-zu)<1e-10){low=Math.min(low,p.getY(u),p.getY(v));high=Math.max(high,p.getY(u),p.getY(v));}
 else{const t=(z-zu)/(zv-zu),y=p.getY(u)+(p.getY(v)-p.getY(u))*t;low=Math.min(low,y);high=Math.max(high,y);}
 }}
 if(!Number.isFinite(low)||!Number.isFinite(high))throw new Error('Cable section missing at '+z);return [low,high];
}
function roundedSaddleHousing(towerZ,fittingCableGeo) {
  const rootY=223.81464, halfLength=4.5, angular=FULL?16:8;
  const stations=Array.from({length:L.crownSteps+1},(_,j)=>-halfLength+2*halfLength*j/L.crownSteps);
  for(const dz of [-1.819169981105233,.8470898715306703,3.6876660706620896])stations.push(towerZ<0?dz:-dz);
  stations.sort((a,b)=>a-b);const longitudinal=stations.length-1;
  const halfWidth=1.40, roofRise=.86, floor=.32, innerX=.54;
  const P=[],I=[],U=[];
  function vertex(x,y,z,u,v){const index=P.length/3;P.push(x,y,z);U.push(u,v);return index;}
  // Outer rings precede inner rings at every station. Each ring is CCW in XY.
  for(let j=0;j<=longitudinal;j++) {
    const dz=stations[j];
    const cy=cableY(towerZ+dz)-rootY;
    const section=cableRangeAtZ(fittingCableGeo,towerZ+dz),innerCy=(section[0]+section[1])/2-rootY,innerY=(section[1]-section[0])/2+.08;
    for(let layer=0;layer<2;layer++)for(let k=0;k<angular;k++) {
      const t=2*Math.PI*k/angular,c=Math.cos(t),s=Math.sin(t);
      let x,y;
      if(layer===0) {
        // Rounded upper half ellipse; lower rays stop at side walls or flat base.
        const radial=s>=-1e-12
          ? 1/Math.sqrt(c*c/(halfWidth*halfWidth)+s*s/(roofRise*roofRise))
          : Math.min(Math.abs(c)>1e-12?halfWidth/Math.abs(c):Infinity,(cy-floor)/(-s));
        x=radial*c;y=cy+radial*s;
      } else {
        x=innerX*c;y=innerCy+innerY*s;
        // Seat follows the actual exported cable's triangle cross-section.
        if(k===3*angular/4)y=section[0]-rootY+.008;
      }
      vertex(x,y,dz,k/angular,j/longitudinal);
    }
  }
  const ring=2*angular;
  for(let j=0;j<longitudinal;j++)for(let k=0;k<angular;k++) {
    const n=(k+1)%angular,a=j*ring+k,b=j*ring+n,c=a+ring,d=b+ring;
    I.push(a,b,c,b,d,c); // outward outer wall
    I.push(a+angular,c+angular,b+angular,b+angular,c+angular,d+angular); // inward tunnel wall
  }
  // Duplicate end vertices for hard annular-face normals; position weld remains closed.
  for(const end of [0,1]) {
    const old=end?longitudinal*ring:0,base=P.length/3;
    for(let k=0;k<ring;k++)vertex(P[(old+k)*3],P[(old+k)*3+1],P[(old+k)*3+2],U[(old+k)*2],U[(old+k)*2+1]);
    for(let k=0;k<angular;k++) {
      const n=(k+1)%angular,a=base+k,b=base+n,c=base+angular+k,d=base+angular+n;
      if(end)I.push(a,b,c,b,d,c);else I.push(a,c,b,b,c,d);
    }
  }
  return meshGeo({positions:P,indices:I,uvs:U});
}
function calibratedPaint(texture,roughness,name,normal) {
 const bytes=texture.image.data,count=texture.image.width*texture.image.height;
 if(bytes.length!==count*4||bytes.BYTES_PER_ELEMENT!==1)throw new Error('Expected 8-bit RGBA procedural albedo');
 const sums=[0,0,0],linear=v=>v<=.04045?v/12.92:Math.pow((v+.055)/1.055,2.4);
 for(let i=0;i<bytes.length;i+=4)for(let c=0;c<3;c++)sums[c]+=linear(bytes[i+c]/255);
 const target=[192,54,44].map(v=>linear(v/255)),factors=sums.map((sum,c)=>target[c]/(sum/count));
 if(factors.some(v=>v>1||v<0))throw new Error('Paint compensation outside dielectric base-color range');
 const material=pbrMaterial({albedo:texture,normal,roughness,metalness:0});
 material.color.setRGB(...factors);material.name=name;return material;
}
function build() {
 const root=createRoot('GoldenGateBridge');
 const fittingPoints=[];for(let i=0;i<=800;i++){const z=-1012.98+i*2025.96/800;fittingPoints.push(new THREE.Vector3(D.cableX,cableY(z),z));}const fittingCableGeo=cappedCable(new THREE.CatmullRomCurve3(fittingPoints),660,.4619625,12);
 const paintMap=proceduralTexture({schemaVersion:2,size:256,usage:'albedo',name:'CC0_Paint_SubtleValue',layers:[{op:'noise',colorA:0xf2f2f2,colorB:0xffffff,scale:8,octaves:3,seed:1937}]});
 const paint=calibratedPaint(paintMap,.68,'Paint');
 const insetMap=proceduralTexture({schemaVersion:2,size:256,usage:'albedo',name:'CC0_RecessGrime',layers:[{op:'noise',colorA:0xf0f0f0,colorB:0xffffff,scale:6,octaves:3,seed:1933}]});
 const inset=calibratedPaint(insetMap,.74,'PaintRecess');
 const panelMap=proceduralTexture({schemaVersion:2,size:512,usage:'albedo',name:'CC0_Tower_PlateCoursesAndRunoff',layers:[
 {op:'noise',colorA:0xebebeb,colorB:0xffffff,scale:3,octaves:2,seed:1937},
 {op:'stripes',colorA:0xeeeeee,colorB:0xffffff,count:32,angleDeg:0,blend:'multiply',opacity:.24},
 {op:'noise',colorA:0xf7f7f7,colorB:0xffffff,scale:64,octaves:2,seed:470,blend:'multiply',opacity:.20},
 {op:'gradient',from:0xffffff,to:0xd9d9d9,angleDeg:90,blend:'multiply',opacity:.35},
 {op:'bricks',brick:0xffffff,mortar:0xc9c9c9,rows:1,cols:1,mortarWidth:.025,stagger:0,blend:'multiply',opacity:.22}]});
 const panelPaint=calibratedPaint(panelMap,.70,'PaintPanels',normalMapFromHeight(panelMap,{strength:.018,name:'CC0_MaintainedPaint_Microrelief'}));
 const concreteMap=proceduralTexture({schemaVersion:2,size:256,usage:'albedo',name:'CC0_Concrete_MineralVariation',layers:[{op:'noise',colorA:0x9e9c95,colorB:0x9f9d96,scale:11,octaves:4,seed:1933},{op:'noise',colorA:0xbab6af,colorB:0xffffff,scale:80,octaves:2,seed:744,blend:'multiply',opacity:.03}]});
 const concrete=pbrMaterial({albedo:concreteMap,roughness:.9,metalness:0});
const anchorageMap=proceduralTexture({schemaVersion:2,size:256,usage:'albedo',name:'CC0_AnchorageConcrete_LiftTone',layers:[{op:'noise',colorA:0xa8a398,colorB:0xb2ada2,scale:14,octaves:3,seed:4127},{op:'gradient',from:0xf0f0f0,to:0xffffff,angleDeg:0,blend:'multiply'},{op:'bricks',brick:0xffffff,mortar:0xb8b8b8,rows:1,cols:1,mortarWidth:.03,stagger:0,blend:'multiply'}]});
const anchorage=pbrMaterial({albedo:anchorageMap,roughness:.9,metalness:0});
const D4=[.004,.5],F4=[.5,.5],tg4=[()=>F4,(x,y,z)=>(Math.abs(x)>.999||Math.abs(z)>.999)?D4:F4,(x,y,z)=>y<-.4?D4:F4,()=>F4,()=>F4];
let pi4=0;
const Q4=()=>({P:[],N:[],U:[],I:[]});
const q4g=q=>meshGeo({positions:q.P,normals:q.N,uvs:q.U,indices:q.I});
function retag4(g,fn){const po=g.attributes.position,no=g.attributes.normal,ix=g.index,P=[],N=[],U=[],I=[];for(let i=0;i<po.count;i++){const nx=no.getX(i),ny=no.getY(i),nz=no.getZ(i),t=fn(nx,ny,nz);P.push(po.getX(i),po.getY(i),po.getZ(i));N.push(nx,ny,nz);U.push(t[0],t[1]);}if(ix)for(let i=0;i<ix.count;i++)I.push(ix.getX(i));else for(let i=0;i<po.count;i++)I.push(i);return meshGeo({positions:P,normals:N,uvs:U,indices:I});}
function skin4(g,fn,m=0){const po=g.attributes.position,no=g.attributes.normal,ix=g.index,P=[],N=[],U=[],I=[],n=ix?ix.count:po.count,at=k=>ix?ix.getX(k):k;for(let t=0;t<n;t+=3){const v=[at(t),at(t+1),at(t+2)],A=v.map(i=>[po.getX(i),po.getY(i),po.getZ(i)]),e1=[A[1][0]-A[0][0],A[1][1]-A[0][1],A[1][2]-A[0][2]],e2=[A[2][0]-A[0][0],A[2][1]-A[0][1],A[2][2]-A[0][2]],gx=e1[1]*e2[2]-e1[2]*e2[1],gy=e1[2]*e2[0]-e1[0]*e2[2],gz=e1[0]*e2[1]-e1[1]*e2[0],l=Math.hypot(gx,gy,gz)||1;const dw=gy/l<-.999;if(m===2?dw:(Math.abs(gx/l)>.999||Math.abs(gz/l)>.999||(m===1&&dw)))continue;const b=P.length/3;v.forEach((i,k)=>{const nx=no.getX(i),ny=no.getY(i),nz=no.getZ(i),u=fn(nx,ny,nz);P.push(A[k][0],A[k][1],A[k][2]);N.push(nx,ny,nz);U.push(u[0],u[1]);});I.push(b,b+1,b+2);}return meshGeo({positions:P,normals:N,uvs:U,indices:I});}
function fq4(q,vs,uv,n){const A=vs[0],B=vs[1],E=vs[2],e1=[B[0]-A[0],B[1]-A[1],B[2]-A[2]],e2=[E[0]-A[0],E[1]-A[1],E[2]-A[2]],gx=e1[1]*e2[2]-e1[2]*e2[1],gy=e1[2]*e2[0]-e1[0]*e2[2],gz=e1[0]*e2[1]-e1[1]*e2[0],m=vs.length,flip=gx*n[0]+gy*n[1]+gz*n[2]<0,b=q.P.length/3;for(let i=0;i<m;i++){const j=flip?(m-i)%m:i;q.P.push(vs[j][0],vs[j][1],vs[j][2]);q.N.push(n[0],n[1],n[2]);q.U.push(uv[j][0],uv[j][1]);}for(let i=1;i<m-1;i++)q.I.push(b,b+i,b+i+1);}
function liftFace4(q,ax,sg,c,h0,h1,T,ye,fi,yt){ye.forEach(([ya,yb],j)=>{const uj=.12+.76*((j*.618034+fi*.291+.07)%1),o0=sg>0?c:-c-T,o1=sg>0?c+T:-c,lo=ax==='x'?[o0,ya,h0]:[h0,ya,o0],hi=ax==='x'?[o1,yb,h1]:[h1,yb,o1],[x0,y0,z0]=lo,[x1,y1,z1]=hi,hh=p=>ax==='x'?p[2]:p[0],uvF=(k,p)=>(k==='+y'||k==='-y')?D4:[uj+.02*Math.min(1,Math.max(0,(p[1]-ya)/(yb-ya))),.12+.76*(hh(p)-h0)/(h1-h0)];const FV={'+x':[[x1,y0,z0],[x1,y1,z0],[x1,y1,z1],[x1,y0,z1]],'-x':[[x0,y0,z1],[x0,y1,z1],[x0,y1,z0],[x0,y0,z0]],'+y':[[x0,y1,z1],[x1,y1,z1],[x1,y1,z0],[x0,y1,z0]],'-y':[[x0,y0,z0],[x1,y0,z0],[x1,y0,z1],[x0,y0,z1]],'+z':[[x0,y0,z1],[x1,y0,z1],[x1,y1,z1],[x0,y1,z1]],'-z':[[x1,y0,z0],[x0,y0,z0],[x0,y1,z0],[x1,y1,z0]]},NV={'+x':[1,0,0],'-x':[-1,0,0],'+y':[0,1,0],'-y':[0,-1,0],'+z':[0,0,1],'-z':[0,0,-1]};for(const k of [(sg>0?'+':'-')+ax,'+y','-y',...(ax==='x'?['+z','-z']:['+x','-x'])]){const vs=FV[k];fq4(q,vs,vs.map(p=>uvF(k,p)),NV[k]);}});ye.slice(1).concat(yt?[[yt]]:[]).forEach(([ya],j)=>{const yb=ye[j][1],o=sg>0?c:-c,v=ax==='x'?[[o,yb,h0],[o,ya,h0],[o,ya,h1],[o,yb,h1]]:[[h0,yb,o],[h0,ya,o],[h1,ya,o],[h1,yb,o]];fq4(q,v,v.map(()=>D4),ax==='x'?[sg,0,0]:[0,0,sg]);});}
function flute4(q,xc,ss,y0,y1){const S=[[-.28,-.38,D4],[.28,-.38,D4],[.42,-.10,D4],[.245,.15,D4],[0,.50,F4],[-.245,.15,D4],[-.42,-.10,D4]],P=S.map(([x,o,t])=>({x:xc+x,z:ss*(3.6+o),t})),cx=P.reduce((s,p)=>s+p.x,0)/P.length,cz=P.reduce((s,p)=>s+p.z,0)/P.length;for(let i=0;i<P.length;i++){const A=P[i],B=P[(i+1)%P.length];let nx=B.z-A.z,nz=-(B.x-A.x);const l=Math.hypot(nx,nz);nx/=l;nz/=l;if(nx*((A.x+B.x)/2-cx)+nz*((A.z+B.z)/2-cz)<0){nx=-nx;nz=-nz;}fq4(q,[[A.x,y0,A.z],[B.x,y0,B.z],[B.x,y1,B.z],[A.x,y1,A.z]],[A.t,B.t,B.t,A.t],[nx,0,nz]);}for(const [y,ny] of [[y0,-1],[y1,1]])fq4(q,P.map(p=>[p.x,y,p.z]),P.map(p=>p.t),[0,ny,0]);}
const hy4=[];{let ya=3.8;for(let k=1;k<=17;k++){const yc=3.8+3*k;hy4.push([ya,yc-.075]);ya=yc+.075;}hy4.push([ya,55.34]);}
const sy4=[[-.46,61.325],[61.475,63.325],[63.475,65.325],[65.475,66.26]].map(([a,b])=>[a-32.9,b-32.9]);
 const asphaltMap=proceduralTexture({schemaVersion:2,size:256,usage:'albedo',name:'CC0_Asphalt_Aggregate',layers:[{op:'noise',colorA:0x454545,colorB:0x474648,scale:96,octaves:3,seed:1986}]});
 const asphaltHeight=proceduralTexture({schemaVersion:2,size:256,usage:'albedo',name:'CC0_Asphalt_Height',layers:[{op:'noise',colorA:0x07090a,colorB:0x131619,scale:96,octaves:3,seed:1986}]});
 const asphalt=pbrMaterial({albedo:asphaltMap,normal:normalMapFromHeight(asphaltHeight,{strength:.60,name:'CC0_Asphalt_Normal'}),roughness:.97,metalness:0});
 const ivory=gameMaterial(0xb9b6ab,{roughness:.83,metalness:0});
 const glass=gameMaterial(0xe9c68c,{roughness:.22,metalness:0,emissive:0xffbd62,emissiveIntensity:.45});
 const red=gameMaterial(0xba1712,{roughness:.18,metalness:0,emissive:0xff1505,emissiveIntensity:.8});
 const dark=gameMaterial(0x171612,{roughness:.9,metalness:0});
 const steel=gameMaterial(0x7d8185,{roughness:.5,metalness:.6});
 const mats={paint,inset,concrete,asphalt,ivory,glass,red,dark};
 concrete.name='Concrete';anchorage.name='AnchorageConcrete';asphalt.name='Asphalt';ivory.name='RoadMarkings';glass.name='LampGlass';red.name='BeaconEmissive';dark.name='DarkDetail';steel.name='JointSteel';
 const cache={};const C=(w,h,d,b=.05)=>{const key=[w,h,d,b].join('_');return cache[key]||(cache[key]=!FULL&&(FAR||Math.min(w,h,d)<1)?new THREE.BoxGeometry(w,h,d):chamfer(w,h,d,b));};
 const towers=[];
 for(const [label,z] of [['South',-D.halfMain],['North',D.halfMain]]) {
 const tower=group(label+'Tower',root,[0,0,z]);towers.push(tower);
 const pier=group('Pier',tower);solid('Footing',merge([{g:C(46,3,23.6,.4)},{g:label==='South'?metreBox(46,31.4,23.6,-17.2):metreBox(46,9.4,23.6,-6.2)}]),concrete,pier,[0,.9,0]);solid('PierBody',C(42.672,11.0112,20.1168,.5),concrete,pier,[0,7.9056,0]);
 const levels=[13.4112,72,121,161,191,223.81464],ws=[10.0584,7.4,6.5,5.4,4.5],ds=[16.4592,11.4,9.7,8,7];
 for(const [side,x] of [['West',D.cableX],['East',-D.cableX]]) {
 const leg=group('Leg'+side,tower,[x,0,0]);
 for(let j=0;j<5;j++)solid('Tier'+(j+1),plateSkin(C(ws[j]-.26,levels[j+1]-levels[j],ds[j]-.26,.09),ws[j]-.26,ds[j]-.26,levels[j],levels[j+1]),panelPaint,leg,[0,(levels[j]+levels[j+1])/2,0]);
 const ribs=[],seams=[],rivets=[];const rivetGeo=meshGeo({positions:[-.045,-.045,0,.045,-.045,0,.045,.045,0,-.045,.045,0,0,0,.030],indices:[0,1,4,1,2,4,2,3,4,3,0,4]});
 for(let j=0;j<5;j++){const w=ws[j],d=ds[j],lo=levels[j],hi=levels[j+1],hh=hi-lo;
 for(const sign of [-1,1]){
 for(let k=0;k<5;k++){const xx=-w*.42+k*w*.21;ribs.push({g:new THREE.BoxGeometry(.22,hh-.22,.30),p:[xx,(lo+hi)/2,sign*(d/2-.11)]});}
 for(let k=0;k<7;k++){const zz=-d*.44+k*d*.88/6;ribs.push({g:new THREE.BoxGeometry(.30,hh-.22,.22),p:[sign*(w/2-.11),(lo+hi)/2,zz]});}
 }
 for(let yy=lo+5;yy<hi-.5;yy+=6)for(const sign of [-1,1]){
 const qFront=new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,1,0),sign<0?Math.PI:0),qSide=new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,1,0),sign*Math.PI/2);
 seams.push({g:surfaceStrap(w-.32,.11,.075),p:[0,yy,sign*(d/2-.14)],q:qFront},{g:surfaceStrap(d-.32,.11,.075),p:[sign*(w/2-.14),yy,0],q:qSide});
 for(let k=0;k<5;k++)rivets.push({g:rivetGeo,p:[-w*.42+k*w*.21,yy,sign*(d/2+.037)],q:qFront});
 for(let k=0;k<7;k++)rivets.push({g:rivetGeo,p:[sign*(w/2+.037),yy,-d*.44+k*d*.88/6],q:qSide});
 }
 ribs.push({g:C(w,.18,d,.04),p:[0,hi-.09,0]});
 }solid('FluteRibs',merge(ribs),paint,leg);solid('PlateSeams',merge(seams),inset,leg);solid('RivetRows',merge(rivets),paint,leg);
 const crown=group('Crown'+side,tower,[x,223.81464,0]);
 solid('SaddleBed',C(4.3,.35,7.8,.10),inset,crown,[0,.175,0]);
 solid('RoundedSaddleHousing',roundedSaddleHousing(z,fittingCableGeo),paint,crown);
// First tier bites into the rounded roof without reaching the cable passage.
const pedestal=[];
pedestal.push({g:C(1.60,.86,1.90,.06),p:[0,4.55,0]}); // 4.12 .. 4.98
pedestal.push({g:C(1.34,.60,1.60,.05),p:[0,5.27,0]}); // 4.97 .. 5.57
pedestal.push({g:C(1.10,.70,1.28,.04),p:[0,5.91,0]}); // 5.56 .. 6.26
solid('SteppedBeaconPlinth',merge(pedestal),paint,crown);
const crownPanels=[];
for(const sign of [-1,1])crownPanels.push({
  g:recessPanel(.94,.58),p:[0,4.55,sign*.935],s:[1,1,.22],
  q:new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,1,0),sign<0?Math.PI:0)
});
solid('CrownInsetPanels',merge(crownPanels),inset,crown);
 solid('BeaconFoot',C(1.6,.16,2.05,.05),inset,crown,[0,6.25,0]);solid('AircraftWarningLens',new THREE.CylinderGeometry(.22,.25,.50,12),red,crown,[0,6.58,0]);
 solid('BeaconCap',C(.66,.12,.66,.045),paint,crown,[0,6.89,0]);
 }
 for(const [j,y,h] of [[1,114.87912,9.144],[2,154.50312,9.17448],[3,188.03112,6.64464],[4,218.26728,6.67512]]){
 const portal=group('Portal'+j,tower),depth=j<3?7:5,width=27.432-(j===1?7.4:j===2?6.5:j===3?5.4:4.5)+.38;
 solid('Core',C(width,h,depth-.28,.10),inset,portal,[0,y,0]);
 const pan=[],trim=[],riv=[];const faceGeo=recessPanel(1.15,h-1.5);
 for(const sign of [-1,1]){
 for(let k=-6;k<=6;k++){pan.push({g:faceGeo,p:[k*1.48,y,sign*(depth/2-.05)],q:new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,1,0),sign<0?Math.PI:0)});for(const yy of [y-h/2+.5,y+h/2-.5])riv.push({g:new THREE.OctahedronGeometry(.045,0),p:[k*1.48,yy,sign*(depth/2+.035)]});}
 for(const yy of [y-h/2+.24,y+h/2-.24])trim.push({g:C(width+.1,.45,.34,.05),p:[0,yy,sign*(depth/2-.02)]});
 }
 for(const side of [-1,1])for(let step=0;step<3;step++)trim.push({g:C(1.9-step*.48,.40,depth-.15,.06),p:[side*(width/2-.85+step*.23),y-h/2-.20-step*.4,0]});
 solid('RecessedDecoPanels',merge(pan),paint,portal);solid('SteppedBordersAndHaunches',merge(trim),paint,portal);solid('PortalRivets',merge(riv),paint,portal);
 }
 const braces=group('BelowRoadBracing',tower),bs=[],joints=[];
 for(const [lo,hi] of [[14.0,39.2],[39.2,69.0]]){
 for(const sign of [-1,1])bs.push(segmentItem(C(1.45,1,1.9,.10),[-D.cableX,lo,sign*.8],[D.cableX,hi,sign*.8]));
 for(const sign of [-1,1])bs.push(segmentItem(C(1.45,1,1.9,.10),[D.cableX,lo,sign*.8],[-D.cableX,hi,sign*.8]));
 }
 for(const yy of [14.0,39.2,69.0])bs.push({g:C(27.432,1.65,5.2,.1),p:[0,yy,0]});
 solid('XMembers',merge(bs),paint,braces);
 for(const yy of [14,39.2,69])for(const xx of [-9.2,9.2])joints.push({g:C(2.8,3.2,.15,.10),p:[xx,yy,2.63]},{g:C(2.8,3.2,.15,.10),p:[xx,yy,-2.63]});
 solid('ConnectionPlates',merge(joints),inset,braces);
 }
 const fender=group('SouthFender',root,[0,0,-D.halfMain]);solid('EllipticalWall',ellipseWall(45.72,23.622,3.048,-32,4.572),concrete,fender);
 for(const [side,x] of [['West',D.cableX],['East',-D.cableX]]) {
 const g=group('MainCable'+side,root);const points=[];for(let i=0;i<=800;i++){const z=-1012.98+i*2025.96/800;points.push(new THREE.Vector3(x,cableY(z),z));}
 const path=new THREE.CatmullRomCurve3(points);solid('ContinuousCable',cappedCable(path,660,.4619625,12),paint,g);
 }
 const deck=group('Deck',root),roadParts=roadSurfaceParts(roadSolid(-9.4488,9.4488,-D.stub,D.stub,0,.45,160));solid('Roadway',roadParts[0],asphalt,deck);solid('Roadbed',roadParts[1],asphalt,deck);
 solid('Underdeck',roadSolid(-9.4488,9.4488,-D.stub,D.stub,-.43,.10,96),paint,deck);
 for(const side of [-1,1]){const concreteWalk=[],steelWalk=[],edgeSteel=[],cuts=[-D.stub,-D.halfMain-26,-D.halfMain+26,D.halfMain-26,D.halfMain+26,D.stub],x0=side>0?9.4488:-12.4968,x1=side>0?12.4968:-9.4488;
 for(let i=0;i<cuts.length-1;i++){const a=cuts[i],b=cuts[i+1],isBypass=i===1||i===3;(isBypass?steelWalk:concreteWalk).push({g:roadSolid(x0,x1,a,b,.22,.28,isBypass?12:32,side)});if(isBypass){for(const xx of [x0,x1])edgeSteel.push({g:roadSolid(xx-.065,xx+.065,a,b,.19,.53,12,side)});}}
 solid(side>0?'WestWalk':'EastWalk',merge(concreteWalk),concrete,deck);solid(side>0?'WestSteelBypass':'EastSteelBypass',merge(steelWalk),paint,deck);solid(side>0?'WestBypassFascia':'EastBypassFascia',merge(edgeSteel),paint,deck);}
 const unitBox=new THREE.BoxGeometry(1,1,1),memberGeo=FULL?unitBox:openVerticalBox(1,1,1);
 const trianglePlate=meshGeo({positions:[-.5,-.5,-.5,-.5,-.5,.5,-.5,.5,0,.5,-.5,-.5,.5,-.5,.5,.5,.5,0],indices:[0,1,2,3,5,4,0,3,4,0,4,1,1,4,5,1,5,2,2,5,3,2,3,0]});
 const ropeGeo=FULL?new THREE.CylinderGeometry(.03413125,.03413125,1,5):new THREE.CylinderGeometry(FAR?.3:.08,FAR?.3:.08,1,FAR?3:4,1,true);
 const bandGeo=new THREE.CylinderGeometry(.535,.535,.72,FULL?10:6);
 const boltGeo=new THREE.OctahedronGeometry(.09,0);
 const stations=[];for(let k=-63;k<=63;k++){const zz=k*D.pitch;if(Math.abs(Math.abs(zz)-D.halfMain)>1)stations.push(zz);}
 for(const [side,x] of [['West',D.cableX],['East',-D.cableX]]){
 const hg=group('Suspenders'+side,root),rr=[],bb=[],ff=[],sockets=[];
 for(const zz of stations){const cy=cableY(zz),dy=road(zz)-.40,delta=new THREE.Vector3(0,cableY(zz+.1)-cableY(zz-.1),.2).normalize(),q=new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(0,1,0),delta);
 bb.push({g:bandGeo,p:[x,cy,zz],q});
 for(const s of (FAR?[0]:[-1,1])){rr.push(segmentItem(ropeGeo,[x+s*.25,dy,zz],[x+s*.25,cy-.32,zz]));sockets.push({g:new THREE.BoxGeometry(.18,.56,.22),p:[x+s*.25,dy+.23,zz]});ff.push({g:new THREE.BoxGeometry(.28,.16,.95),p:[x+s*.56,cy-.18,zz]});
 for(const dz of [-.28,0,.28])ff.push({g:boltGeo,p:[x+s*.57,cy-.02,zz+dz]});
 }sockets.push({g:new THREE.BoxGeometry(1.32,.20,.70),p:[x,dy-.01,zz]});
 }
 solid('RopePairs',merge(rr),FAR?dark:paint,hg);solid('CableBands',merge(bb),paint,hg);solid('ClampFlangesBolts',merge(ff),inset,hg);solid('DeckClevises',merge(sockets),paint,hg);
 }
 const under=group('DeckLateralBracing',root),cross=[];
 for(let k=-64;k<64;k+=(FULL?1:4)){const z0=k*D.pitch,z1=(k+(FULL?1:4))*D.pitch,y0=road(z0)-7.96,y1=road(z1)-7.96;
 cross.push(segmentItem(memberGeo,[-13.716,y0,z0],[13.716,y1,z1],[.18,.24]),segmentItem(memberGeo,[13.716,y0,z0],[-13.716,y1,z1],[.18,.24]));
 cross.push({g:unitBox,p:[0,y0,z0],s:[27.432,.50,.24]});
 }solid('CrossFramesAndLateralX',merge(cross),paint,under);
 const floorItems=[],stringerItems=[],walkStools=[],stoolGeo=openVerticalBox(.36,1.11,.34);
 for(const zz of stations){const yy=road(zz);floorItems.push(
 {g:unitBox,p:[0,yy-1.80,zz],s:[27.432,1.20,.12]},
 {g:unitBox,p:[0,yy-1.18,zz],s:[27.432,.10,.44]},
 {g:unitBox,p:[0,yy-2.40,zz],s:[27.432,.10,.44]});
 if(Math.abs(Math.abs(zz)-D.halfMain)>=26)for(const side of [-1,1])walkStools.push({g:stoolGeo,p:[side*10.9728,yy-.595,zz]});
 }
 for(const xx of [-6.3,-3.15,0,3.15,6.3])stringerItems.push({g:roadSolid(xx-.07,xx+.07,-D.end,D.end,-.50,.64,32)},{g:roadSolid(xx-.23,xx+.23,-D.end,D.end,-1.10,.10,32)});
 if(!FULL){floorItems.length=0;for(let i=0;i<stations.length;i+=2){const zz=stations[i];floorItems.push({g:unitBox,p:[0,road(zz)-1.80,zz],s:[27.432,1.20,.44]});}}
 solid('FloorbeamISections',merge(floorItems),paint,under);
 solid('SidewalkBearingStools',merge(walkStools),paint,under);
 solid('LongitudinalTStringers',merge(stringerItems),paint,under);
 for(const [side,x] of [['West',D.cableX],['East',-D.cableX]]){
 const truss=group('DeckTruss'+side,root),members=[],gussets=[],hardware=[];
 if(FAR){solid('TrussBox',flatShade(roadSolid(x-.455,x+.455,-D.end,D.end,-.12,8.32,32)),paint,truss);continue;}
 const chords=[];for(const off of [0,-D.truss+.3])chords.push({g:flatShade(roadSolid(x-.455,x+.455,-D.end,D.end,-.12+off,1,32))});solid('RolledChords',merge(chords),paint,truss);
 const n=L.trussBays,tstep=FULL?7.62:2*D.end/n;
 for(let k=0;k<n;k++){const z0=-D.end+k*tstep,z1=z0+tstep,top0=road(z0)-.62,top1=road(z1)-.62,bot0=top0-D.truss+.3,bot1=top1-D.truss+.3;
 // continuous rolled chord profiles are emitted once per cable plane
 const a=[x,k%2?bot0:top0,z0],b=[x,k%2?top1:bot1,z1];members.push(segmentItem(memberGeo,a,b,[.61,.61]));
 members.push(segmentItem(memberGeo,[x,bot0,z0],[x,top0,z0],[.61,.76]));
 for(const yy of [top0,bot0]){for(const dx of [-.34,.34])gussets.push({g:trianglePlate,p:[x+dx,yy,z0],s:[.10,1.0,1.05]});}
 }
 solid('ChordsPostsDiagonals',merge(members),paint,truss);solid('GussetPlates',merge(gussets),inset,truss);
 }
 // Pedestrian bypasses flare around each main tower leg.
 function walkCenter(zz){const a=Math.abs(Math.abs(zz)-D.halfMain);return 10.9728+(a<10.5?8.6:a<26?8.6*(26-a)/15.5:0);}
 const railRoot=group('SidewalkRailings',deck),railItems=[],innerItems=[];
 const balGeo=openVerticalBox(.032,1.1392,.032),postGeo=openVerticalBox(.09,1.2192,.09),guardPostGeo=openVerticalBox(.10,.88,.10);
 const avoidTower=zz=>Math.abs(Math.abs(zz)-D.halfMain)<7;
 for(const sign of [-1,1]){
 const start=-D.stub,end=D.stub,steps=Math.round((end-start)/L.railPitch),pitch=(end-start)/steps;
 for(let k=0;k<steps;k++){const z0=start+k*pitch,z1=z0+pitch,y0=road(z0)+.22,y1=road(z1)+.22,x0=sign*(walkCenter(z0)+1.47),x1=sign*(walkCenter(z1)+1.47);
 railItems.push({g:postGeo,p:[x0,y0+.6096,z0]});
 // Handrails are continuous geometry below, without hidden per-bay end caps.
 for(let b=1;b<(FULL?4:1);b++){const zz=z0+pitch*b/4;railItems.push({g:balGeo,p:[sign*(walkCenter(zz)+1.47),road(zz)+.87,zz]});}
 // Guard rail on the curb side remains clear of the roadway.
 if(FULL||k%2===0)innerItems.push({g:guardPostGeo,p:[sign*(walkCenter(z0)-1.36),y0+.44,z0]});
 }
 for(const hh of [.12,1.2192])railItems.push({g:roadSolid(sign*12.4428-.0375,sign*12.4428+.0375,-D.stub,D.stub,.22+hh+.0375,.075,96,sign)});for(const hh of [.42,.88])innerItems.push({g:roadSolid(sign*9.6128-.05,sign*9.6128+.05,-D.stub,D.stub,.22+hh+.0375,.075,96,sign)});
 solid(sign>0?'WestCurb':'EastCurb',roadSolid(sign>0?9.4488:-9.6488,sign>0?9.6488:-9.4488,-D.stub,D.stub,.27,.30,160),concrete,deck);
 }
 solid('OuterOpenRailings',merge(railItems),paint,railRoot);solid('RoadSafetyRailings',merge(innerItems),paint,railRoot);
 const barrier=group('MovableMedian',deck),median=[],medianCount=FULL?Math.ceil(2*D.stub):1,medianPitch=2*D.stub/medianCount,medianJoint=FULL?.004:0;
 for(let k=0;k<medianCount;k++){const z0=-D.stub+k*medianPitch+(k?medianJoint/2:0),z1=-D.stub+(k+1)*medianPitch-(k<medianCount-1?medianJoint/2:0);median.push({g:roadSolid(-.1524,.1524,z0,z1,.8128,.8128,FULL?1:L.roadSteps)});}
 solid('LinkedConcreteUnits',merge(median),concrete,barrier);
 const lines=group('LaneMarkings',deck),marks=[],whitePlane=new THREE.PlaneGeometry(.115,3.0),flat=new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1,0,0),-Math.PI/2);
 for(const xx of [-6.28,-3.17,3.17,6.28])for(let zz=-D.stub+3;zz<D.stub-3;zz+=12)marks.push({g:whitePlane,p:[xx,road(zz)+.012,zz],q:roadTilt(zz).multiply(flat)});
 solid('BrokenLaneLines',merge(marks),ivory,lines);
 for(const xx of [-9.18,9.18])solid(xx>0?'WestEdgeLine':'EastEdgeLine',roadSolid(xx-.065,xx+.065,-D.stub,D.stub,.013,.003,160),ivory,lines);
 const drains=[],joints=[];for(let zz=-D.end;zz<D.end;zz+=15.24){for(const side of [-1,1])drains.push({g:unitBox,p:[side*9.32,road(zz)+.014,zz],q:roadTilt(zz),s:[.15,.012,.42]});}
 // Flush finger-joint plates: 0.6 m long, top 1.5 mm over the road, 10 mm deep, tilted to the local grade.
 for(const zz of [-D.halfMain,D.halfMain,-D.end,D.end]){const sl=roadSlope(zz);joints.push({g:unitBox,p:[0,road(zz)-.0035,zz],q:roadTilt(zz),s:[18.88,.01/Math.sqrt(1+sl*sl),.6]});}
 solid('DrainSlots',merge(drains),dark,deck);solid('ExpansionJoints',merge(joints),steel,deck);
 // One reusable lamp geometry per finish, placed with shared buffers.
 const lamps=group('ArtDecoLampStandards',deck);
 const lampBody=[],lampGlass=[];
 lampBody.push({g:C(.42,.5,.42,.025),p:[0,.25,0]},{g:C(.23,6.2,.26,.022),p:[0,3.5,0]});
 for(const armY of [6.4,7.07]){const arm=[];for(let i=0;i<=L.armSteps;i++){const t=i/L.armSteps*Math.PI/2;arm.push([2.05*(1-Math.cos(t)),armY+1.95*Math.sin(t),0]);}
 lampBody.push({g:sweepProfile([[-.065,-.08],[.065,-.08],[.065,.08],[-.065,.08]],arm,{up:[0,0,1]})});}
 lampBody.push({g:C(1.35,.30,.62,.04),p:[2.27,8.68,0]},{g:C(.26,.18,.30,.025),p:[0,5.85,0]});
 lampGlass.push({g:C(1.14,.10,.48,.03),p:[2.27,8.49,0]});
 const lampGeo=merge(lampBody),lensGeo=merge(lampGlass);
 for(const side of [-1,1]){const bodies=[],lenses=[],q=new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,1,0),side>0?Math.PI:0);
 for(let k=-22;k<=22;k++){if(!FULL&&k%L.lampStep!==0)continue;const zz=k*45.72;if(Math.abs(Math.abs(zz)-D.halfMain)<11)continue;const p=[side*9.91,road(zz)+.22,zz];bodies.push({g:lampGeo,p,q});lenses.push({g:lensGeo,p,q});}
 const sideRoot=group(side>0?'WestLampArray':'EastLampArray',lamps);solid('StandardsAndTwinArms',merge(bodies),paint,sideRoot);solid('AmberLenses',merge(lenses),glass,sideRoot);
 }
 const bypass=group('TowerSidewalkBrackets',deck),bk=[];
 for(const tz of [-D.halfMain,D.halfMain])for(const side of [-1,1])for(const dz of [-10.5,-6,6,10.5]){const zz=tz+dz,yy=road(zz)-.06;
 bk.push(segmentItem(C(.22,1,.32,.025),[side*13.7,yy-3.8,tz+Math.max(-6,Math.min(6,dz))],[side*20.8,yy-.10,zz]));
 bk.push(segmentItem(C(.20,1,.34,.022),[side*13.7,yy-.10,tz+Math.max(-5.5,Math.min(5.5,dz))],[side*20.8,yy-.10,zz]));
 }solid('CantileverKnees',merge(bk),paint,bypass);

 for(const [label,sgn] of [['South',-1],['North',1]]){
 const a=group(label+'Anchorage',root,[0,0,sgn*(D.end+25)]),body=[];
 body.push({g:C(43,4,52,.45),p:[0,1.4,0]},{g:C(39,52.4,49.5,.4),p:[0,29.6,0]},{g:C(40.2,5.6,50.0,.32),p:[0,58.2,0]},{g:C(40.8,.5,50.4,.10),p:[0,61.15,0]});
 if(sgn<0)body.push({g:metreBox(43,3.4,52,-3.7),p:[0,1.4,0]});
 const hq=Q4();[['x',1,19.5,-24.35,24.35],['x',-1,19.5,-24.35,24.35],['z',1,24.75,-19.1,19.1],['z',-1,24.75,-19.1,19.1]].forEach(([ax,sg,c,h0,h1],fi)=>liftFace4(hq,ax,sg,c,h0,h1,.06,hy4,fi+(sgn>0?4:0),55.4));
 solid('AnchorageHousing',merge([...body.map((it,i)=>({g:i===1?skin4(it.g,tg4[1],1):i===0&&sgn<0?skin4(it.g,tg4[0],2):retag4(it.g,tg4[i]),p:it.p})),{g:q4g(hq)}]),anchorage,a);
 const courses=[],pilasters=[],windows=[];
 for(const side of [-1,1]){
 
 for(const zz of [-19,-6,6,19]){const tu=.15+.7*((pi4++*.618034+.11)%1);pilasters.push({g:retag4(C(1.0,53,.8,.07),()=>[tu,.5]),p:[side*19.9,31,zz]});}
 const pylon=group(side>0?'PylonWest':'PylonEast',a,[side*16.2,0,-sgn*22]);
 const sq=Q4();[['x',1,2.75,-3.46,3.46],['x',-1,2.75,-3.46,3.46],['z',1,3.6,-2.61,2.61],['z',-1,3.6,-2.61,2.61]].forEach(([ax,sg,c,h0,h1],fi)=>liftFace4(sq,ax,sg,c,h0,h1,.06,sy4,fi+(side>0?8:12)));
  solid('PylonShaft',merge([{g:skin4(C(5.5,67,7.2,.14),tg4[1])},{g:q4g(sq)}]),anchorage,pylon,[0,32.9,0]);solid('SteppedCrown',retag4(C(4.3,3.8,5.8,.10),tg4[0]),anchorage,pylon,[0,67.9,0]);solid('UpperCrown',retag4(C(3.3,1.1,4.8,.07),tg4[0]),anchorage,pylon,[0,70.1,0]);
 const flq=Q4();for(const ss of [-1,1])for(let k=-2;k<=2;k++)flute4(flq,k*.77,ss,12,70);
 solid('ChevronFlutes',q4g(flq),anchorage,pylon);
 solid('AccessDoorReveal',C(1.14,2.0,.14,.045),inset,pylon,[0,64.2,-sgn*3.63]);solid('InsetAccessDoor',C(.80,1.57,.08,.025),dark,pylon,[0,64.2,-sgn*(FAR?3.625:3.715)]);
 }
 solid('HousingPilasters',merge(pilasters),anchorage,a);
 }
 function qualify(node,prefix){for(const child of node.children){child.name=prefix+'_'+child.name;qualify(child,child.name);}}for(const child of root.children)qualify(child,child.name);
 root.traverse(node=>{
  const names={Deck_Mesh_Roadway:'Roadway',Deck_Mesh_WestCurb:'CurbsWest',Deck_Mesh_EastCurb:'CurbsEast',Deck_MovableMedian_Mesh_LinkedConcreteUnits:'Median'};
  if(names[node.name])node.name=names[node.name];
  const match=/^(South|North)Tower_Crown(West|East)_Mesh_AircraftWarningLens$/.exec(node.name);
  if(match)node.name='Beacon_'+match[1]+'_'+match[2];
 });
 root.userData={lod:PARAMS.lod,units:'metres',up:'+Y',roadAxis:'+Z',sceneNodes:['Roadway','Median','CurbsWest','CurbsEast','Beacon_South_West','Beacon_South_East','Beacon_North_West','Beacon_North_East']};
 return root;
}

Source SHA-256: 2a739bea8197e718b6912930012c9ab36317965ff263d9fe05a9821ba7e138f2

Named part paths (173)
  • GoldenGateBridge/SouthTower/SouthTower_Pier/SouthTower_Pier_Mesh_Footing
  • GoldenGateBridge/SouthTower/SouthTower_Pier/SouthTower_Pier_Mesh_PierBody
  • GoldenGateBridge/SouthTower/SouthTower_LegWest/SouthTower_LegWest_Mesh_Tier1
  • GoldenGateBridge/SouthTower/SouthTower_LegWest/SouthTower_LegWest_Mesh_Tier2
  • GoldenGateBridge/SouthTower/SouthTower_LegWest/SouthTower_LegWest_Mesh_Tier3
  • GoldenGateBridge/SouthTower/SouthTower_LegWest/SouthTower_LegWest_Mesh_Tier4
  • GoldenGateBridge/SouthTower/SouthTower_LegWest/SouthTower_LegWest_Mesh_Tier5
  • GoldenGateBridge/SouthTower/SouthTower_LegWest/SouthTower_LegWest_Mesh_FluteRibs
  • GoldenGateBridge/SouthTower/SouthTower_LegWest/SouthTower_LegWest_Mesh_PlateSeams
  • GoldenGateBridge/SouthTower/SouthTower_LegWest/SouthTower_LegWest_Mesh_RivetRows
  • GoldenGateBridge/SouthTower/SouthTower_CrownWest/SouthTower_CrownWest_Mesh_SaddleBed
  • GoldenGateBridge/SouthTower/SouthTower_CrownWest/SouthTower_CrownWest_Mesh_RoundedSaddleHousing
  • GoldenGateBridge/SouthTower/SouthTower_CrownWest/SouthTower_CrownWest_Mesh_SteppedBeaconPlinth
  • GoldenGateBridge/SouthTower/SouthTower_CrownWest/SouthTower_CrownWest_Mesh_CrownInsetPanels
  • GoldenGateBridge/SouthTower/SouthTower_CrownWest/SouthTower_CrownWest_Mesh_BeaconFoot
  • GoldenGateBridge/SouthTower/SouthTower_CrownWest/Beacon_South_West
  • GoldenGateBridge/SouthTower/SouthTower_CrownWest/SouthTower_CrownWest_Mesh_BeaconCap
  • GoldenGateBridge/SouthTower/SouthTower_LegEast/SouthTower_LegEast_Mesh_Tier1
  • GoldenGateBridge/SouthTower/SouthTower_LegEast/SouthTower_LegEast_Mesh_Tier2
  • GoldenGateBridge/SouthTower/SouthTower_LegEast/SouthTower_LegEast_Mesh_Tier3
  • GoldenGateBridge/SouthTower/SouthTower_LegEast/SouthTower_LegEast_Mesh_Tier4
  • GoldenGateBridge/SouthTower/SouthTower_LegEast/SouthTower_LegEast_Mesh_Tier5
  • GoldenGateBridge/SouthTower/SouthTower_LegEast/SouthTower_LegEast_Mesh_FluteRibs
  • GoldenGateBridge/SouthTower/SouthTower_LegEast/SouthTower_LegEast_Mesh_PlateSeams
  • GoldenGateBridge/SouthTower/SouthTower_LegEast/SouthTower_LegEast_Mesh_RivetRows
  • GoldenGateBridge/SouthTower/SouthTower_CrownEast/SouthTower_CrownEast_Mesh_SaddleBed
  • GoldenGateBridge/SouthTower/SouthTower_CrownEast/SouthTower_CrownEast_Mesh_RoundedSaddleHousing
  • GoldenGateBridge/SouthTower/SouthTower_CrownEast/SouthTower_CrownEast_Mesh_SteppedBeaconPlinth
  • GoldenGateBridge/SouthTower/SouthTower_CrownEast/SouthTower_CrownEast_Mesh_CrownInsetPanels
  • GoldenGateBridge/SouthTower/SouthTower_CrownEast/SouthTower_CrownEast_Mesh_BeaconFoot
  • GoldenGateBridge/SouthTower/SouthTower_CrownEast/Beacon_South_East
  • GoldenGateBridge/SouthTower/SouthTower_CrownEast/SouthTower_CrownEast_Mesh_BeaconCap
  • GoldenGateBridge/SouthTower/SouthTower_Portal1/SouthTower_Portal1_Mesh_Core
  • GoldenGateBridge/SouthTower/SouthTower_Portal1/SouthTower_Portal1_Mesh_RecessedDecoPanels
  • GoldenGateBridge/SouthTower/SouthTower_Portal1/SouthTower_Portal1_Mesh_SteppedBordersAndHaunches
  • GoldenGateBridge/SouthTower/SouthTower_Portal1/SouthTower_Portal1_Mesh_PortalRivets
  • GoldenGateBridge/SouthTower/SouthTower_Portal2/SouthTower_Portal2_Mesh_Core
  • GoldenGateBridge/SouthTower/SouthTower_Portal2/SouthTower_Portal2_Mesh_RecessedDecoPanels
  • GoldenGateBridge/SouthTower/SouthTower_Portal2/SouthTower_Portal2_Mesh_SteppedBordersAndHaunches
  • GoldenGateBridge/SouthTower/SouthTower_Portal2/SouthTower_Portal2_Mesh_PortalRivets
  • GoldenGateBridge/SouthTower/SouthTower_Portal3/SouthTower_Portal3_Mesh_Core
  • GoldenGateBridge/SouthTower/SouthTower_Portal3/SouthTower_Portal3_Mesh_RecessedDecoPanels
  • GoldenGateBridge/SouthTower/SouthTower_Portal3/SouthTower_Portal3_Mesh_SteppedBordersAndHaunches
  • GoldenGateBridge/SouthTower/SouthTower_Portal3/SouthTower_Portal3_Mesh_PortalRivets
  • GoldenGateBridge/SouthTower/SouthTower_Portal4/SouthTower_Portal4_Mesh_Core
  • GoldenGateBridge/SouthTower/SouthTower_Portal4/SouthTower_Portal4_Mesh_RecessedDecoPanels
  • GoldenGateBridge/SouthTower/SouthTower_Portal4/SouthTower_Portal4_Mesh_SteppedBordersAndHaunches
  • GoldenGateBridge/SouthTower/SouthTower_Portal4/SouthTower_Portal4_Mesh_PortalRivets
  • GoldenGateBridge/SouthTower/SouthTower_BelowRoadBracing/SouthTower_BelowRoadBracing_Mesh_XMembers
  • GoldenGateBridge/SouthTower/SouthTower_BelowRoadBracing/SouthTower_BelowRoadBracing_Mesh_ConnectionPlates
  • GoldenGateBridge/NorthTower/NorthTower_Pier/NorthTower_Pier_Mesh_Footing
  • GoldenGateBridge/NorthTower/NorthTower_Pier/NorthTower_Pier_Mesh_PierBody
  • GoldenGateBridge/NorthTower/NorthTower_LegWest/NorthTower_LegWest_Mesh_Tier1
  • GoldenGateBridge/NorthTower/NorthTower_LegWest/NorthTower_LegWest_Mesh_Tier2
  • GoldenGateBridge/NorthTower/NorthTower_LegWest/NorthTower_LegWest_Mesh_Tier3
  • GoldenGateBridge/NorthTower/NorthTower_LegWest/NorthTower_LegWest_Mesh_Tier4
  • GoldenGateBridge/NorthTower/NorthTower_LegWest/NorthTower_LegWest_Mesh_Tier5
  • GoldenGateBridge/NorthTower/NorthTower_LegWest/NorthTower_LegWest_Mesh_FluteRibs
  • GoldenGateBridge/NorthTower/NorthTower_LegWest/NorthTower_LegWest_Mesh_PlateSeams
  • GoldenGateBridge/NorthTower/NorthTower_LegWest/NorthTower_LegWest_Mesh_RivetRows
  • GoldenGateBridge/NorthTower/NorthTower_CrownWest/NorthTower_CrownWest_Mesh_SaddleBed
  • GoldenGateBridge/NorthTower/NorthTower_CrownWest/NorthTower_CrownWest_Mesh_RoundedSaddleHousing
  • GoldenGateBridge/NorthTower/NorthTower_CrownWest/NorthTower_CrownWest_Mesh_SteppedBeaconPlinth
  • GoldenGateBridge/NorthTower/NorthTower_CrownWest/NorthTower_CrownWest_Mesh_CrownInsetPanels
  • GoldenGateBridge/NorthTower/NorthTower_CrownWest/NorthTower_CrownWest_Mesh_BeaconFoot
  • GoldenGateBridge/NorthTower/NorthTower_CrownWest/Beacon_North_West
  • GoldenGateBridge/NorthTower/NorthTower_CrownWest/NorthTower_CrownWest_Mesh_BeaconCap
  • GoldenGateBridge/NorthTower/NorthTower_LegEast/NorthTower_LegEast_Mesh_Tier1
  • GoldenGateBridge/NorthTower/NorthTower_LegEast/NorthTower_LegEast_Mesh_Tier2
  • GoldenGateBridge/NorthTower/NorthTower_LegEast/NorthTower_LegEast_Mesh_Tier3
  • GoldenGateBridge/NorthTower/NorthTower_LegEast/NorthTower_LegEast_Mesh_Tier4
  • GoldenGateBridge/NorthTower/NorthTower_LegEast/NorthTower_LegEast_Mesh_Tier5
  • GoldenGateBridge/NorthTower/NorthTower_LegEast/NorthTower_LegEast_Mesh_FluteRibs
  • GoldenGateBridge/NorthTower/NorthTower_LegEast/NorthTower_LegEast_Mesh_PlateSeams
  • GoldenGateBridge/NorthTower/NorthTower_LegEast/NorthTower_LegEast_Mesh_RivetRows
  • GoldenGateBridge/NorthTower/NorthTower_CrownEast/NorthTower_CrownEast_Mesh_SaddleBed
  • GoldenGateBridge/NorthTower/NorthTower_CrownEast/NorthTower_CrownEast_Mesh_RoundedSaddleHousing
  • GoldenGateBridge/NorthTower/NorthTower_CrownEast/NorthTower_CrownEast_Mesh_SteppedBeaconPlinth
  • GoldenGateBridge/NorthTower/NorthTower_CrownEast/NorthTower_CrownEast_Mesh_CrownInsetPanels
  • GoldenGateBridge/NorthTower/NorthTower_CrownEast/NorthTower_CrownEast_Mesh_BeaconFoot
  • GoldenGateBridge/NorthTower/NorthTower_CrownEast/Beacon_North_East
  • GoldenGateBridge/NorthTower/NorthTower_CrownEast/NorthTower_CrownEast_Mesh_BeaconCap
  • GoldenGateBridge/NorthTower/NorthTower_Portal1/NorthTower_Portal1_Mesh_Core
  • GoldenGateBridge/NorthTower/NorthTower_Portal1/NorthTower_Portal1_Mesh_RecessedDecoPanels
  • GoldenGateBridge/NorthTower/NorthTower_Portal1/NorthTower_Portal1_Mesh_SteppedBordersAndHaunches
  • GoldenGateBridge/NorthTower/NorthTower_Portal1/NorthTower_Portal1_Mesh_PortalRivets
  • GoldenGateBridge/NorthTower/NorthTower_Portal2/NorthTower_Portal2_Mesh_Core
  • GoldenGateBridge/NorthTower/NorthTower_Portal2/NorthTower_Portal2_Mesh_RecessedDecoPanels
  • GoldenGateBridge/NorthTower/NorthTower_Portal2/NorthTower_Portal2_Mesh_SteppedBordersAndHaunches
  • GoldenGateBridge/NorthTower/NorthTower_Portal2/NorthTower_Portal2_Mesh_PortalRivets
  • GoldenGateBridge/NorthTower/NorthTower_Portal3/NorthTower_Portal3_Mesh_Core
  • GoldenGateBridge/NorthTower/NorthTower_Portal3/NorthTower_Portal3_Mesh_RecessedDecoPanels
  • GoldenGateBridge/NorthTower/NorthTower_Portal3/NorthTower_Portal3_Mesh_SteppedBordersAndHaunches
  • GoldenGateBridge/NorthTower/NorthTower_Portal3/NorthTower_Portal3_Mesh_PortalRivets
  • GoldenGateBridge/NorthTower/NorthTower_Portal4/NorthTower_Portal4_Mesh_Core
  • GoldenGateBridge/NorthTower/NorthTower_Portal4/NorthTower_Portal4_Mesh_RecessedDecoPanels
  • GoldenGateBridge/NorthTower/NorthTower_Portal4/NorthTower_Portal4_Mesh_SteppedBordersAndHaunches
  • GoldenGateBridge/NorthTower/NorthTower_Portal4/NorthTower_Portal4_Mesh_PortalRivets
  • GoldenGateBridge/NorthTower/NorthTower_BelowRoadBracing/NorthTower_BelowRoadBracing_Mesh_XMembers
  • GoldenGateBridge/NorthTower/NorthTower_BelowRoadBracing/NorthTower_BelowRoadBracing_Mesh_ConnectionPlates
  • GoldenGateBridge/SouthFender/SouthFender_Mesh_EllipticalWall
  • GoldenGateBridge/MainCableWest/MainCableWest_Mesh_ContinuousCable
  • GoldenGateBridge/MainCableEast/MainCableEast_Mesh_ContinuousCable
  • GoldenGateBridge/Deck/Roadway
  • GoldenGateBridge/Deck/Deck_Mesh_Roadbed
  • GoldenGateBridge/Deck/Deck_Mesh_Underdeck
  • GoldenGateBridge/Deck/Deck_Mesh_EastWalk
  • GoldenGateBridge/Deck/Deck_Mesh_EastSteelBypass
  • GoldenGateBridge/Deck/Deck_Mesh_EastBypassFascia
  • GoldenGateBridge/Deck/Deck_Mesh_WestWalk
  • GoldenGateBridge/Deck/Deck_Mesh_WestSteelBypass
  • GoldenGateBridge/Deck/Deck_Mesh_WestBypassFascia
  • GoldenGateBridge/Deck/Deck_SidewalkRailings/Deck_SidewalkRailings_Mesh_OuterOpenRailings
  • GoldenGateBridge/Deck/Deck_SidewalkRailings/Deck_SidewalkRailings_Mesh_RoadSafetyRailings
  • GoldenGateBridge/Deck/CurbsEast
  • GoldenGateBridge/Deck/CurbsWest
  • GoldenGateBridge/Deck/Deck_MovableMedian/Median
  • GoldenGateBridge/Deck/Deck_LaneMarkings/Deck_LaneMarkings_Mesh_BrokenLaneLines
  • GoldenGateBridge/Deck/Deck_LaneMarkings/Deck_LaneMarkings_Mesh_EastEdgeLine
  • GoldenGateBridge/Deck/Deck_LaneMarkings/Deck_LaneMarkings_Mesh_WestEdgeLine
  • GoldenGateBridge/Deck/Deck_Mesh_DrainSlots
  • GoldenGateBridge/Deck/Deck_Mesh_ExpansionJoints
  • GoldenGateBridge/Deck/Deck_ArtDecoLampStandards/Deck_ArtDecoLampStandards_EastLampArray/Deck_ArtDecoLampStandards_EastLampArray_Mesh_StandardsAndTwinArms
  • GoldenGateBridge/Deck/Deck_ArtDecoLampStandards/Deck_ArtDecoLampStandards_EastLampArray/Deck_ArtDecoLampStandards_EastLampArray_Mesh_AmberLenses
  • GoldenGateBridge/Deck/Deck_ArtDecoLampStandards/Deck_ArtDecoLampStandards_WestLampArray/Deck_ArtDecoLampStandards_WestLampArray_Mesh_StandardsAndTwinArms
  • GoldenGateBridge/Deck/Deck_ArtDecoLampStandards/Deck_ArtDecoLampStandards_WestLampArray/Deck_ArtDecoLampStandards_WestLampArray_Mesh_AmberLenses
  • GoldenGateBridge/Deck/Deck_TowerSidewalkBrackets/Deck_TowerSidewalkBrackets_Mesh_CantileverKnees
  • GoldenGateBridge/SuspendersWest/SuspendersWest_Mesh_RopePairs
  • GoldenGateBridge/SuspendersWest/SuspendersWest_Mesh_CableBands
  • GoldenGateBridge/SuspendersWest/SuspendersWest_Mesh_ClampFlangesBolts
  • GoldenGateBridge/SuspendersWest/SuspendersWest_Mesh_DeckClevises
  • GoldenGateBridge/SuspendersEast/SuspendersEast_Mesh_RopePairs
  • GoldenGateBridge/SuspendersEast/SuspendersEast_Mesh_CableBands
  • GoldenGateBridge/SuspendersEast/SuspendersEast_Mesh_ClampFlangesBolts
  • GoldenGateBridge/SuspendersEast/SuspendersEast_Mesh_DeckClevises
  • GoldenGateBridge/DeckLateralBracing/DeckLateralBracing_Mesh_CrossFramesAndLateralX
  • GoldenGateBridge/DeckLateralBracing/DeckLateralBracing_Mesh_FloorbeamISections
  • GoldenGateBridge/DeckLateralBracing/DeckLateralBracing_Mesh_SidewalkBearingStools
  • GoldenGateBridge/DeckLateralBracing/DeckLateralBracing_Mesh_LongitudinalTStringers
  • GoldenGateBridge/DeckTrussWest/DeckTrussWest_Mesh_RolledChords
  • GoldenGateBridge/DeckTrussWest/DeckTrussWest_Mesh_ChordsPostsDiagonals
  • GoldenGateBridge/DeckTrussWest/DeckTrussWest_Mesh_GussetPlates
  • GoldenGateBridge/DeckTrussEast/DeckTrussEast_Mesh_RolledChords
  • GoldenGateBridge/DeckTrussEast/DeckTrussEast_Mesh_ChordsPostsDiagonals
  • GoldenGateBridge/DeckTrussEast/DeckTrussEast_Mesh_GussetPlates
  • GoldenGateBridge/SouthAnchorage/SouthAnchorage_Mesh_AnchorageHousing
  • GoldenGateBridge/SouthAnchorage/SouthAnchorage_PylonEast/SouthAnchorage_PylonEast_Mesh_PylonShaft
  • GoldenGateBridge/SouthAnchorage/SouthAnchorage_PylonEast/SouthAnchorage_PylonEast_Mesh_SteppedCrown
  • GoldenGateBridge/SouthAnchorage/SouthAnchorage_PylonEast/SouthAnchorage_PylonEast_Mesh_UpperCrown
  • GoldenGateBridge/SouthAnchorage/SouthAnchorage_PylonEast/SouthAnchorage_PylonEast_Mesh_ChevronFlutes
  • GoldenGateBridge/SouthAnchorage/SouthAnchorage_PylonEast/SouthAnchorage_PylonEast_Mesh_AccessDoorReveal
  • GoldenGateBridge/SouthAnchorage/SouthAnchorage_PylonEast/SouthAnchorage_PylonEast_Mesh_InsetAccessDoor
  • GoldenGateBridge/SouthAnchorage/SouthAnchorage_PylonWest/SouthAnchorage_PylonWest_Mesh_PylonShaft
  • GoldenGateBridge/SouthAnchorage/SouthAnchorage_PylonWest/SouthAnchorage_PylonWest_Mesh_SteppedCrown
  • GoldenGateBridge/SouthAnchorage/SouthAnchorage_PylonWest/SouthAnchorage_PylonWest_Mesh_UpperCrown
  • GoldenGateBridge/SouthAnchorage/SouthAnchorage_PylonWest/SouthAnchorage_PylonWest_Mesh_ChevronFlutes
  • GoldenGateBridge/SouthAnchorage/SouthAnchorage_PylonWest/SouthAnchorage_PylonWest_Mesh_AccessDoorReveal
  • GoldenGateBridge/SouthAnchorage/SouthAnchorage_PylonWest/SouthAnchorage_PylonWest_Mesh_InsetAccessDoor
  • GoldenGateBridge/SouthAnchorage/SouthAnchorage_Mesh_HousingPilasters
  • GoldenGateBridge/NorthAnchorage/NorthAnchorage_Mesh_AnchorageHousing
  • GoldenGateBridge/NorthAnchorage/NorthAnchorage_PylonEast/NorthAnchorage_PylonEast_Mesh_PylonShaft
  • GoldenGateBridge/NorthAnchorage/NorthAnchorage_PylonEast/NorthAnchorage_PylonEast_Mesh_SteppedCrown
  • GoldenGateBridge/NorthAnchorage/NorthAnchorage_PylonEast/NorthAnchorage_PylonEast_Mesh_UpperCrown
  • GoldenGateBridge/NorthAnchorage/NorthAnchorage_PylonEast/NorthAnchorage_PylonEast_Mesh_ChevronFlutes
  • GoldenGateBridge/NorthAnchorage/NorthAnchorage_PylonEast/NorthAnchorage_PylonEast_Mesh_AccessDoorReveal
  • GoldenGateBridge/NorthAnchorage/NorthAnchorage_PylonEast/NorthAnchorage_PylonEast_Mesh_InsetAccessDoor
  • GoldenGateBridge/NorthAnchorage/NorthAnchorage_PylonWest/NorthAnchorage_PylonWest_Mesh_PylonShaft
  • GoldenGateBridge/NorthAnchorage/NorthAnchorage_PylonWest/NorthAnchorage_PylonWest_Mesh_SteppedCrown
  • GoldenGateBridge/NorthAnchorage/NorthAnchorage_PylonWest/NorthAnchorage_PylonWest_Mesh_UpperCrown
  • GoldenGateBridge/NorthAnchorage/NorthAnchorage_PylonWest/NorthAnchorage_PylonWest_Mesh_ChevronFlutes
  • GoldenGateBridge/NorthAnchorage/NorthAnchorage_PylonWest/NorthAnchorage_PylonWest_Mesh_AccessDoorReveal
  • GoldenGateBridge/NorthAnchorage/NorthAnchorage_PylonWest/NorthAnchorage_PylonWest_Mesh_InsetAccessDoor
  • GoldenGateBridge/NorthAnchorage/NorthAnchorage_Mesh_HousingPilasters

Follow the saved revisions.

Originally authored by GPT-6 Astra. Refinements in this delivery: Claude Sonnet 5.5.

Each run asked its harness for a model and a reasoning effort; that request is recorded from the run’s own receipt and invocation. No run’s effort was independently confirmed. The delivered revisions come from Claude Sonnet 5.5’s runs: the full and web tiers from review 5; the far tier from review 2 (unchanged since).

GPT-6 Astra · first run

Codex 0.157.1

Requested effort: ultra. Independently confirmed: not recorded.

  1. True-scale blockout

    r_003e29ccca7d4149952dbeb38d260e57

  2. Structure

    r_864fdb9b078c447fb61e6db945342eb1

    Parent: r_003e29ccca7d4149952dbeb38d260e57

  3. Deck and end structures

    r_e6fc425ac972452a927d2e9e768dc3c5

    Parent: r_864fdb9b078c447fb61e6db945342eb1

  4. Materials

    r_891f756291cf4b4c9865bc30c5627908

    Parent: r_e6fc425ac972452a927d2e9e768dc3c5

  5. Geometry repairs and optimization

    r_62e15876bd6d4e6b8fb72be910eafb42

    Parent: r_891f756291cf4b4c9865bc30c5627908

  6. Final paint/concrete correction

    r_9f4b0e76ea634be083de8a5e38c4e838

    Parent: r_62e15876bd6d4e6b8fb72be910eafb42

GPT-6 Astra · review 1

Codex 0.157.1

Requested effort: ultra. Independently confirmed: not recorded.

  1. Rough paint and steel bypass

    r_99009f9869b34133b24aae698ae52096

    Parent: r_9f4b0e76ea634be083de8a5e38c4e838

  2. Plate courses, rail repair and optimization

    r_ee0f97666f264c88b21d28d1ddf9ccfe

    Parent: r_99009f9869b34133b24aae698ae52096

  3. Rounded crowns

    r_64633d24733040e59977e69e880b721e

    Parent: r_ee0f97666f264c88b21d28d1ddf9ccfe

  4. Floor framing and graded median

    r_4e2faa2ac4b24b7b91a92e735c9ac1bb

    Parent: r_64633d24733040e59977e69e880b721e

  5. Crown contact QA

    r_947dd72d3b74420e8b48bc9987049d60

    Parent: r_4e2faa2ac4b24b7b91a92e735c9ac1bb

  6. Final bypass-root repair

    r_18e4fb0aff0345669fc86efe33c85f7c

    Parent: r_947dd72d3b74420e8b48bc9987049d60

GPT-6 Astra · review 2

Codex 0.157.1

Requested effort: ultra. Independently confirmed: not recorded.

  1. Calibrated paint

    r_6ef01791e9cf45fa9b1f4dd7b5d0aed6

    Parent: r_18e4fb0aff0345669fc86efe33c85f7c

  2. Full final

    r_8b79b09984b14e15b9426f6db2df0140

    Parent: r_6ef01791e9cf45fa9b1f4dd7b5d0aed6

Claude Sonnet 5.5 · fix-up 1

Claude Code 2.1.280

Requested effort: max. Independently confirmed: not recorded.

  1. Fix-up 1: piers to the seabed, lighter concrete and asphalt, thicker ropes

    r_cba97c6c2fc448ee9ca24741d772fa39

    Parent: r_8b79b09984b14e15b9426f6db2df0140

Claude Sonnet 5.5 · review 1

Claude Code 2.1.280

Requested effort: max. Independently confirmed: not recorded.

  1. Review 1: fender ring and truss members

    r_e5cf0cd4a99d49088e7fb0c848587b03

    Parent: r_cba97c6c2fc448ee9ca24741d772fa39

Claude Sonnet 5.5 · review 2

Claude Code 2.1.280

Requested effort: max. Independently confirmed: not recorded.

  1. Review 2: roadway profile

    r_03e7981b4ff84159aa4533c587f033c7

    Parent: r_e5cf0cd4a99d49088e7fb0c848587b03

Claude Sonnet 5.5 · review 3

Claude Code 2.1.280

Requested effort: max. Independently confirmed: not recorded.

  1. Review 3: expansion joints

    r_0d1532b4a00b4663909f8edf2bd290aa

    Parent: r_03e7981b4ff84159aa4533c587f033c7

Claude Sonnet 5.5 · review 4

Claude Code 2.1.280

Requested effort: max. Independently confirmed: not recorded. The run stopped at its spending limit at 2026-09-30 09:58 UTC.

It saved no full-tier revision; its web-tier revision is listed with the tier revisions below.

Claude Sonnet 5.5 · review 5

Claude Code 2.1.280

Requested effort: max. Independently confirmed: not recorded.

  1. Review 5: lift construction fix, first build (it carries the review-4 full tier, which review 4 never saved; superseded by the seam fix)

    r_8e986268599c44ff93d451e81520aaec

    Parent: r_0d1532b4a00b4663909f8edf2bd290aa

  2. Review 5: lift construction fix, seam closed

    r_76c7a4080e7844e185896b7e1b196e5a

    Parent: r_8e986268599c44ff93d451e81520aaec

Web and far tier revisions (each branches from Full final)

web tier

  1. Web final

    r_ba838a2a86e04f2493b5d55b493a766a

    GPT-6 Astra · review 2

  2. Fix-up 1: piers to the seabed, lighter concrete and asphalt, thicker ropes

    r_28ac511af71d4db69a2d7cff8b243a24

    Claude Sonnet 5.5 · fix-up 1

  3. Review 1: fender ring and truss members

    r_560ce144cfad491db7729a3750da884e

    Claude Sonnet 5.5 · review 1

  4. Review 2: roadway profile

    r_8285ccc5ffab4519b049936f792c15ee

    Claude Sonnet 5.5 · review 2

  5. Review 3: expansion joints

    r_e5da8e08bd424a8796a033fbb9793104

    Claude Sonnet 5.5 · review 3

  6. Review 4: anchorage housings and pylons (web tier only; the run stopped at its spending limit before the full tier was saved)

    r_c81f6d5fb70c492fb2c1d57e2d482437

    Claude Sonnet 5.5 · review 4

  7. Review 5: lift construction fix, first build (superseded by the seam fix)

    r_2632afa018de4ac28bde9ffc7ed19e47

    Claude Sonnet 5.5 · review 5

  8. Review 5: lift construction fix, seam closed

    r_de88c9d5481d4642837b9d00c81cf0a9

    Claude Sonnet 5.5 · review 5

far tier

  1. Far final

    r_0da2d1ae635c4f84a10e58e0e03936e7

    GPT-6 Astra · review 2

  2. Fix-up 1: piers to the seabed, lighter concrete and asphalt, thicker ropes

    r_7fd11f06f23b4bfc93b9b47ab1b6ca04

    Claude Sonnet 5.5 · fix-up 1

  3. Review 1: fender ring and truss members

    r_d3f2f39ee4964708a0301d7e7082d12b

    Claude Sonnet 5.5 · review 1

  4. Review 2: roadway profile (unchanged since: the far tier has no expansion joints for review 3, and reviews 4 and 5 left its export byte-identical)

    r_fcddc546fa134910b2221561353d97e2

    Claude Sonnet 5.5 · review 2

Displayed revision’s parent: r_8e986268599c44ff93d451e81520aaec

The measurements have a reference ledger.

Published dimensions, derived values and artistic estimates are recorded separately. This is a visual reconstruction, not an engineering survey.

  • Visual reconstruction, not an engineering survey.
  • 1937 suspension composition with requested modern median, lighting and later lateral bracing.
  • Secondary details include declared estimates.
  • No terrain, water, traffic, people or approach viaducts. The piers, fender and anchorage bases reach below the waterline (the south tower footing to Y −32 m); no seabed or water surface is modelled.
  • The far tier is a distance version: it omits the under-deck framing and the expansion joints.

These views are the full tier’s exported GLB rendered under the Kiln review lighting rig with the author’s own capture cameras, so they show the file you can download.

Golden Gate Bridge from near water level, looking up at the south tower and the roadway.
Golden Gate Bridge from near water level, looking up at the south tower and the roadway.
Golden Gate Bridge from the roadway, looking along the lanes toward the towers ahead.
Golden Gate Bridge from the roadway, looking along the lanes toward the towers ahead.
Golden Gate Bridge from beside the top of the south tower, with the main cables and the roadway below.
Golden Gate Bridge from beside the top of the south tower, with the main cables and the roadway below.
Golden Gate Bridge in side elevation, the full span between both anchorages.
Golden Gate Bridge in side elevation, the full span between both anchorages.
Read the complete modeling reference ledger

Golden Gate Bridge — modeling reference ledger

Research dates: 2026-09-28–29. Asset coordinates: metres, water Y=0, roadway along Z, south -Z, west +X. All geometry and material maps are authored procedurally in Kiln. Reference photographs are measurement/appearance aids only and are excluded from CC0 delivery. This ledger preserves the estimates written before modeling; subsequent correction sections explicitly supersede them. The final reconciliation below is authoritative for the delivered source.

Primary sources

  • D1: Golden Gate Bridge District, Design & Construction Stats.
  • D2: District, historic resources / finding of effect. Existing bridge dimensions only; net proposals excluded.
  • H: Library of Congress, HAER CA-31; catalog/drawing availability and measurement limitations recorded in the research notes when resolved.
  • P1: Guillaume Paumier tower photograph, 2010. Reference only, not copied into textures or delivery. Visible four above-roadway portal struts, recessed vertical panels, stepped underside corbels, fluted legs, paired suspender attachments and curved twin lamp arms.

Published dimensions adopted

Exact international foot conversion: 1 ft = 0.3048 m; 1 in = 0.0254 m. Metres below use the published imperial value rather than rounded metric captions.

QuantityPublishedModel metresSource
Suspension structure6,450 ft1,965.96D1
Main span4,200 ft1,280.16D1
Each side span1,125 ft342.90D1
Tower stationsderivedZ = ±640.08D1
Suspension endsderivedZ = ±982.98D1
Tower height above water746 ft227.3808D1
Tower height above roadway500 ft152.40D1
Tower roadway elevationderived 246 ft74.9808D1, subtraction
Midspan soffit clearance220 ft67.056D1
Bridge width / nominal cable-plane spacing90 ft27.432D1; cable spacing interpreted from brief
Road between curbs62 ft18.8976D1
Sidewalk, each10 ft3.048D1
Tower leg base33 × 54 ft10.0584 × 16.4592D1
Main cable diameter36-3/8 in.923925D1
Suspender diameter2-11/16 in.0682625D1
Suspender / cable-band pitch50 ft15.24D1
Suspender quantity250 pairs500 ropesD1
Truss depth25 ft7.62task reference; pending primary corroboration
Truss vertical pitch25 ft7.62D2 p.2
Outer railing post pitch12.5 ft3.81D2 p.2
Lamp standard pitch, each side150 ft45.72D2 p.2
Historical outer railing height4 ft1.2192District historic resources study, detail research
Movable median width × height12 × 32 in.3048 × .8128District movable median information, detail research

Estimates and artistic construction parameters (declared before modeling)

The following are modeling estimates, not surveyed dimensions. They preserve measured principal spans and massing. Supplemental research may refine them through retained revisions.

  • Cable saddle center Y=224.5; 470 ft / 143.256 m sag from contemporary design report, rather than the brief’s tentative 475 ft. Midspan cable center =81.244. Main cable is an exact sampled parabola between saddle transition zones. Side spans descend to Y=64 at Z=±982.98, with a gentle quadratic sag; cable continues into anchorage housing at ±1011.98. Saddle rounding is a local smooth crest over ±6 m.
  • Road deck initially Y=74.9808, refined to center top Y=75.30, bottom at Y=67.056 including the 7.62 m truss and .624 m upper deck zone. Side-span roadway slopes to Y=62.0 at suspension ends; finished stub ends Z=±1032.98, 50 m beyond suspended span. Median is centered, six lane widths derived from usable carriageway.
  • Tower leg center transverse offset from ±17.5 at pier to ±13.716 at crown. Steel begins Y=12.0. Estimated setbacks at Y=74.98, 110, 146, 183, 220; widths 10.0584, 7.2, 6.25, 5.35, 4.5, 3.6 m; depths 16.4592, 12.8, 10.8, 8.8, 6.8, 5.0 m. Crown cap finishes published tower height. Four portal centers Y=108, 144, 180, 216; 8 m deep vertically, with stepped corbels and faceted vertical recessed panelling. Portal count from P1 and brief.
  • Leg flutes recessed about .16–.28 m, long face seams every 4–7 m, chamfers .05–.14 m. Structural plate skin, inset panels, rivet head diameter .07–.12 m at representative panel boundaries; no claim to individual historic rivet layout.
  • Pier approximate 45 × 24 m at base, crown Y=12. South fender ellipse 91.44 m in X by 47.244 m in Z, wall 3.048 m, top 4.572 m, bottom -.6 m: contemporary 1935 design figures, source research to follow. North pier ground termination as requested, without terrain.
  • Anchorages: two cable housings per end, approximately 11 m wide × 30 m long, rising to 66 m, terraced concrete; flanking pylons rise to 83 m, stepped cap and vertical grooves. Bases begin Y=-.6. Stub has clean planar road end. These omit the approach viaducts and underlying terrain.
  • Truss chord section .50 × .62 m, diagonal .27 × .34 m, posts .28 × .36 m; paired plate/flange geometry, gusset plates and representative rivets. Underdeck lateral bracing section .16 × .22 m every 15.24 m. Intentional member contact at panel nodes.
  • Cable-band length .72 m, shell radius .54 m, flanges and clamp bolts; paired rope centers separated .34 m transversely; deck clevis at each station. Saddle base 3.8 × 6 m, approximately 2 m high, tapering weather cover, aircraft beacon .22 m radius. Wrap seam pitch .26 m only in local crown hero region if cost permits.
  • Sidewalk slab thickness .28 m, curb lip .20 m. Rail top .09 × .09 m, posts .085 m, infill .028 m at .635 m. Lamps 8.5 m above sidewalk, tapered/fluted post, inward curved double arms reaching 2.3 m, rectangular lantern 1.3 × .38 × .52 m; shape follows P1, dimensions estimated. Median unit length 1 m with narrow articulation seams.
  • Painted steel initial sRGB #C0362C, dielectric metalness=0, roughness=.36; secondary recessed paint #AB3026, roughness=.44. Concrete warm grey #BDB6A7 roughness=.88; asphalt #343639 roughness=.96; marking ivory #E8E5D9 roughness=.72; warm lamp glass, red warning lenses. All material/noise choices are artistic estimates tuned only in GPU views. Procedural noise seeds and texture resolutions are implementation choices, not reference facts.
  • Geometry sampling and optimizations are implementation parameters. Dimensions of fillets, fasteners, drains, expansion joints, access door recesses, light lenses and minor trim are artistic estimates where not explicitly published above.

Scope and historical reconciliation

Final source additions and reconciliation

  • D5: District underwater-inspection presentation, PDF p.5 / printed p.15 identifies both visible piers as 140×66 ft = 42.672×20.1168 m. The model uses those body dimensions, top Y 13.4112, a 46×23.6 m flared footing (estimate), and the original 91.44×47.244 m south fender. Its section drawings confirm a broad open moat. The older 5 ft gap is not applied to this waterline geometry.
  • H catalog: HAER CA-31 and its JSON resource list provide 47 photographs, a history and photo captions, with no digitized drawing sheets. HAER saddle photograph CA-31-31 informs 15 gusset fins on each side of the modeled saddle and its tapered beacon plinth; fin count/dimensions are visual approximations. HAER anchorage photograph informs the simplified end masses.
  • S: USNI Proceedings, April 1935, Golden Gate and San Francisco Bay Bridges gives 470 ft sag and the 300×155 ft fender, explicitly crediting District data. These are contemporary design figures, not independent as-built surveys.
  • District movable median design supplies 12 in × 32 in units. Unit length 2 m and 22 mm visual articulation joints in this asset remain estimates.
  • Final color tuning: original Kiln noise albedo paint #962B20–#A83124, recess #7C2119; warm concrete #625D53–#736D60; asphalt #07090A–#131619. These are artistic factors chosen against photos in the fixed material-faithful GPU lighting, not a claim to official paint reflectance. Paint roughness .48; all painted surfaces metalness 0. Four 256² procedural maps total: paint, concrete, asphalt, asphalt normal. No acquired imagery.
  • Camera near-plane choices (.5–5 m) are presentation settings for stable depth precision in kilometre-scale geometry, not alterations to the mesh.
  • Final geometry uses 660 longitudinal main-cable segments with a 12-sided smooth cross section and closed endpoint caps; 5-sided smooth suspender ropes; 10-sided cable bands. Small rivets/bolt heads use octahedral approximations. Static arrays batch repeated primitive geometry by material; no GPU instancing extension or compressed geometry is assumed.

Pre-modeling correction from the District tower elevation

Deck-stage estimates: movable median modeled as articulated 2 m units with 22 mm joints (unit length unverified; width/height published). Outer railing uses four equal subdivisions of the 3.81 m principal-post bay, approximately .9525 m infill spacing; estimated intentionally open rail. At the main towers sidewalks flare 8.6 m outward over a 26 m half-length to bypass the leg solids, a visual routing approximation. Anchorage concrete is a 43×52 m base, 39×49.5 m main body, roof at 61.4 m, and pylon crowns 70.65 m. These supersede the preliminary 83 m pylons and smaller cable-housing estimate; Y0 ground termination is a requested abstraction of the terrain-supported real anchorages.

D3: District seismic presentation, 26 June 2025, PDF p.5, existing tower elevation (proposed retrofit details excluded). This supersedes the preliminary tower estimates above: leg centerlines remain fixed at X=±13.716; only each leg’s local envelope steps inward. Four portal center elevations are 376.9, 506.9, 616.9, 716.1 ft = 114.87912, 154.50312, 188.03112, 218.26728 m. Their vertical depths are 30, 30.1, 21.8, 21.9 ft = 9.144, 9.17448, 6.64464, 6.67512 m. Two X-bracing bays are below deck, between approximate Y=13.411, 35.8 and 67.7. Drawing steel cap 734.3 ft = 223.81464 m; beacon tip 758.2 ft = 231.09936 m. Drawing datum is not explicitly identified on this slide, so alignment with model water is an assumption; cable saddle center chosen Y=227.3808 (published nominal tower height), steel cap 223.81464 and beacon tip 231.10. Principal tower datum remains within published dimensions; report projections separately.

Estimated tower tier boundaries adopted: 13.4112, 72, 121, 161, 191, 223.81464 m. Tier widths X: 10.0584, 7.4, 6.5, 5.4, 4.5 m; Z depths: 16.4592, 11.4, 9.7, 8.0, 7.0 m. Top saddle cover tapers separately to approx 3.7×6.1 m. Actual tier steps and flutes are photo-based estimates. Main cable midspan center becomes 84.1248 m using 143.256 m sag. Fender orientation confirmed: 91.44 X × 47.244 Z.

D4: District Art Deco exhibit supplies appearance photos of twin curved lamp arms and chevron-faced stepped concrete pylons. These are viewed for form; no pixels enter the authored maps. Pylon detail estimate updated to repeated triangular vertical ribs, not simple rectangular groove faces.

1937 suspension composition with present paint, lamps, movable median and requested lateral bracing; the District dates added lower lateral bracing to 1953–54. This is therefore a deliberate hybrid requested by the brief. No terrain, water, traffic, people, approach viaduct, net or maintenance apparatus. Fort Point arch deferred until primary scope passes review. This is a visual reconstruction, not an engineering survey.

Final reconciliation — source p_5bfd30103aaf

This section records the pre-Review 1 delivery. The Review 1 ledger at the end supersedes affected finishes and detail estimates.

The published dimensional table and corrected District tower geometry govern the final source. These final values supersede the preliminary estimates retained above:

ParameterDelivered value / basis
Cable curveNominal saddle Y = 227.3808 m, sag = 143.256 m, center Y = 84.1248 m; local Hermite rounding over 5 m each side of the saddle; end centers at Z = ±1012.98 m, Y ≈ 51.9894 m inside housings
Road and truss clearanceRoad Y = 75.30 m at center, 74.9808 m at towers, 62 m at span ends; lowest nominal midspan truss surface ≈ 67.05 m, within 0.01% of 67.056 m
Tower envelopeSteel crown cap Y = 223.81464 m; beacon maximum Y = 230.76464 m; nominal published tower height retained as cable saddle datum, with projections reported separately
Tower tiersBoundaries 13.4112, 72, 121, 161, 191, 223.81464 m; estimated nominal widths 10.0584, 7.4, 6.5, 5.4, 4.5 m and depths 16.4592, 11.4, 9.7, 8, 7 m. Flutes project slightly beyond the nominal envelope
Below-road bracingTwo X bays use final estimated node elevations 14, 39.2 and 69 m; representative beam sections, not a structural calculation
Piers and fenderPier body 42.672 × 20.1168 m, crown Y = 13.4112 m. Footing estimate 46 × 23.6 m. South fender 91.44 × 47.244 m, wall 3.048 m, top Y = 4.572 m, lower skirt Y = −0.6 m
MedianWidth 0.3048 m and height 0.8128 m verified against District Key Dates, September 2013 and January 2015 entries. Simplified rectangular units are 2 m long with 0.022 m joints; length and profile are modeling approximations
Rail infillApproximately 0.9525 m pitch within published 3.81 m main-post bays; aesthetic estimate
Sidewalk bypass8.6 m maximum outward shift, blending within 26 m of tower station; estimated geometry, not measured accessibility clearance
End structures43 × 52 m base, 39 × 49.5 m housing body, roof Y = 61.4 m, pylon tips Y = 70.65 m; estimated forms. Base at water datum is the brief’s standalone abstraction
Final paintOriginal noise albedo #6A1D12–#7A2417, roughness 0.60, metalness 0; inset paint #7C2119, roughness 0.52. Tuned by GPU appearance under Kiln’s fixed lighting; these factors are not official paint reflectance measurements
Final concreteOriginal low-contrast noise #69645A–#6C675D, roughness 0.90; noise scale 11, 4 octaves, seed 1933, fine modulation opacity 0.06. Replaces the visibly repetitive higher-contrast finish
Other materialsAsphalt #07090A–#131619, roughness 0.97 with a subtle generated normal; ivory markings; amber lamp lenses and red warning lenses. Four original 256 × 256 texture maps total

All secondary section sizes, bevels, panels, bolt approximations, lamp construction, pylon decoration, sampling counts, noise seeds and camera values in the supplied source/camera JSON are declared artistic or implementation estimates unless specifically linked to a published measurement above. The truss depth remains the supplied 25 ft brief value; the separate 25 ft panel pitch is primary-source corroborated. No inference that the two measurements are the same was used as verification.

Review 1 refinement ledger — recorded before edits

The coordinator’s Review 1 is the design authority for these corrections. Principal span, cable and tower dimensions remain locked to the published ledger. All new minor dimensions below are visual construction estimates, not newly surveyed historic facts.

  • Main paint base factor: exact sRGB #C0362C, metalness 0, roughness 0.68; recessed paint roughness 0.74. Original neutral modulation textures add restrained value variation without a second orange tint. Plate variation, rivet streaking and recessed dirt are procedural; map sizes at most 1024² under the 2048² brief limit.
  • Tower plate cadence: approximately 6 m vertical rows on all four leg faces, with horizontal joint lines and representative rivet heads. Existing tier heights and envelope remain unchanged. Seam widths, rivet sizes and weathering lengths are artistic estimates.
  • Tower sidewalk bypass: retain the 8.6 m outward displacement and 26 m blend zones, replace the local 3.048 m-wide concrete bypass with painted steel, preserve walking height and continuous railings, add a shallow painted edge fascia connected to the existing cantilever knees.
  • Outer railing infill repair and optimization: retain post spacing and silhouettes; infill height 1.1392 m, center at roadway +0.87 m, so it reaches both horizontal rails. Square profiles omit only end faces buried in connected rails/slabs; side walls remain visible geometry.
  • Crown refinement: continue the upper leg’s stepped, recessed Art Deco envelope, replace exposed picket fins and pyramidal covers with explicit rounded cable housings, preserve nominal cable saddle Y=227.3808 m and aircraft beacon tip Y=230.76464 m. Detailed dimensions will be recorded with the accepted revision.
  • Underdeck: narrow/recess the soffit around the 18.8976 m carriageway and expose structural floor beams and longitudinal stringers. Member sections and cadence are estimates selected to join the existing truss and lateral frames without changing clearance.
  • Median: retain published 0.3048 m width and 0.8128 m height, use approximately 1 m short segments with millimetre-scale joints, and conform each end to the actual road curve. This replaces ungraded 2 m boxes; hinge/profile geometry remains an approximation.
  • Postcard camera: estimated Battery Spencer composition, on +X/+Z (Marin north-west), approximately Y=120 m, looking south-east along the span. Terrain is excluded. Camera position is a composition choice, not a survey location.
  • Crown implementation estimates: rounded tunnel housing 2.8 m wide × 9 m long, floor 0.32 m above steel crown; roof 0.86 m above the local cable center; nominal tunnel horizontal radius 0.53 m with slope-adjusted vertical radius and a small 0.450 m bottom bearing land. Three beacon-plinth steps occupy local Y=4.12–6.26 m. All four retained beacon tips stay at Y=230.76464 m. Explicit 16×16 section grid; source topology verified as a closed tunnel, not a fabrication survey.
  • Underdeck implementation estimates: plate X±9.4488 m, top road−0.43 m, thickness 0.10 m. Five T-stringers at X=−6.3,−3.15,0,3.15,6.3 m; web 0.14×0.64 m, bottom flange 0.46×0.10 m. At suspender stations, floor I-beams span 27.432 m, web 1.20 m deep×0.12 m, flange 0.44×0.10 m, center about road−1.80 m. Ordinary sidewalk stools 0.36×1.11×0.34 m; ends embed into supporting surfaces. These are visual member estimates, not verified load-bearing specifications.
  • Final median segmentation uses 2,066 approximately 1 m units, 4 mm joints and exact road samples at the tower/span grade breaks, preserving constant 0.8128 m vertical height. Inner guard posts are 0.88 m tall with their ends seated inside slab/upper rail. Narrow chord/stringer sampling at 32 intervals preserves the shallow crown to approximately submillimetre accuracy between forced grade-break samples.
Download REFERENCE.md

Download the assets

full detail

Every modelled part, available for applications that need the complete detail.

Runtime assets

Models, textures and animations prepared for use in a scene or application.

12,402,960 bytes (12.40 MB)

Download runtime assets

Editable assets

Models plus Kiln source, editing metadata, materials and included revisions, so you can reopen and continue editing.

28,385,461 bytes (28.39 MB)

Download editable assets

web detail

The 3D preview uses this lighter version, with reduced segment counts and paired thin suspender ropes.

Runtime assets

Models, textures and animations prepared for use in a scene or application.

3,508,476 bytes (3.51 MB)

Download runtime assets

Editable assets

Models plus Kiln source, editing metadata, materials and included revisions, so you can reopen and continue editing.

23,920,003 bytes (23.92 MB)

Download editable assets

far detail

A distance version with single suspender ropes; it has no under-deck framing and no expansion joints.

Runtime assets

Models, textures and animations prepared for use in a scene or application.

490,460 bytes (0.49 MB)

Download runtime assets

Editable assets

Models plus Kiln source, editing metadata, materials and included revisions, so you can reopen and continue editing.

19,677,563 bytes (19.68 MB)

Download editable assets

Original procedural geometry and embedded maps are CC0. Reference photographs are excluded; software retains its own licences.