(P,rnd,h=1.9)
| 1417 | } |
| 1418 | |
| 1419 | function buildBanner(P,rnd,h=1.9){ |
| 1420 | const g=new THREE.Group(); |
| 1421 | g.add(meshOf(new THREE.CylinderGeometry(0.05,0.05,h,5),mat(P.wood)).translateY(h/2)); |
| 1422 | const w=0.5,hh=0.85; |
| 1423 | const cloth=meshOf(new THREE.PlaneGeometry(w,hh,6,4), |
| 1424 | mat(rnd()<0.5?P.roof2:P.accent,{side:THREE.DoubleSide,flat:false,rough:0.85}),true,false); |
| 1425 | cloth.position.set(w/2,h-hh/2-0.1,0); g.add(cloth); |
| 1426 | const base=cloth.geometry.attributes.position.array.slice(); |
| 1427 | const ph=rnd()*TAU; |
| 1428 | cloth.userData.tick=t=>{ |
| 1429 | const p=cloth.geometry.attributes.position; |
| 1430 | for(let i=0;i<p.count;i++){ |
| 1431 | const x=base[i*3], y=base[i*3+1]; |
| 1432 | p.setZ(i,Math.sin(t*3+ph+x*5+y*1.5)*0.07*(x/w+0.5)); |
| 1433 | } |
| 1434 | p.needsUpdate=true; |
| 1435 | }; |
| 1436 | animated.push(cloth); |
| 1437 | return g; |
| 1438 | } |
| 1439 | |
| 1440 | /* The gate. Every realm has one because every realm has a way IN, and the way |
| 1441 | in is where the district hangs its colours — but it was two posts and a torus |
no test coverage detected